Files
note_sync/大模型/deepseek/02-代码模型/01-DeepSeek-Coder-2401.14196_abstract.md
T

13 KiB
Raw Blame History

DeepSeek-Coder:当大语言模型遇见编程——代码智能的崛起

原文标题:DeepSeek-Coder: When the Large Language Model Meets Programming -- The Rise of Code Intelligence arXiv:2401.14196 | 发布:25 Jan 2024(最后修订 26 Jan 2024) 作者/机构:Daya Guo、Qihao Zhu、Dejian Yang、Zhenda Xie、Kai Dong、Wentao Zhang 等(DeepSeek-AI,深度求索;Qihao Zhu、Yingfei Xiong 另属北京大学) 原文 PDF:01-DeepSeek-Coder-2401.14196.pdf

一、摘要(全文翻译)

大语言模型的快速发展已经彻底改变了软件开发中的代码智能。然而,闭源模型的主导地位限制了广泛的研究与开发。为解决这一问题,我们提出了 DeepSeek-Coder 系列——一系列参数量从 1.3B 到 33B 的开源代码模型,在 2 万亿 token 上从零开始训练。这些模型在一个高质量的项目级代码语料库上进行预训练,并采用窗口为 16K 的「填空式」(fill-in-the-blank)任务来增强代码生成与代码补全能力。我们的大量评测表明,DeepSeek-Coder 不仅在多个基准上取得了开源代码模型中的最先进性能,还超越了 Codex、GPT-3.5 等现有的闭源模型。此外,DeepSeek-Coder 模型采用宽松许可证发布,允许研究用途以及不受限制的商业使用。

二、核心贡献

  1. 提出开源代码模型系列 DeepSeek-Coder:给出 Base 与 Instruct 两个版本、1.3B/6.7B/33B 三种规模,全部在 2 万亿 token 上从零训练,覆盖 87 种编程语言,解决了「强代码模型被闭源垄断、研究者无法获取」的痛点。
  2. 首次在代码预训练阶段引入仓库级(repository-level)数据构造:通过依赖解析把同仓库文件按调用依赖排序后拼接成训练样本,显著提升跨文件代码生成能力(CrossCodeEval 上相对仅用文件级语料训练的版本在 Java、TypeScript、C# 上均有提升)。
  3. 系统研究 FIM 训练策略的配置影响:用 1.3B 模型在 Python 子集上做消融,比较 0%/50%/100% FIM 率与 MSP 策略,发现 FIM 率与代码补全能力之间存在权衡,最终选定 50% PSM 率,为后续代码模型预训练提供了可复用的经验结论。
  4. 仓库级去重与严格去污染:在仓库粒度而非文件粒度做近似去重以保持仓库结构完整;用 n-gram 匹配(10-gram 相同即剔除,短串用精确匹配)剔除 HumanEval、MBPP、GSM8K、MATH 的题面与解答,避免测试集泄漏。
  5. 全面评测并确立开源 SOTA:在 HumanEval(多语言)、MBPP、DS-1000、LeetCode 竞赛、FIM 单行补全、CrossCodeEval、程序化数学推理七类任务上,DeepSeek-Coder-Base 33B 全面领先开源模型;Instruct 33B 在多数代码任务上超过 GPT-3.5 Turbo。
  6. 推出 DeepSeek-Coder-v1.5 7B:从通用模型 DeepSeek-LLM-7B Base 出发继续预训练,验证「最好的代码大模型建立在强通用大模型之上」这一判断。

三、方法与技术要点

3.1 数据构成与 GitHub 抓取过滤(第 2.1 节)

训练数据由 87% 源代码 + 10% 英文代码相关自然语言(GitHub Markdown 与 StackExchange)+ 3% 与代码无关的中文自然语言 组成。代码侧只保留 2023 年 2 月前创建的公开仓库,并用类似 StarCoder 的规则初筛:文件平均行长 > 100 字符或最大行长 > 1000 字符则丢弃;字母字符占比低于 25% 则丢弃;除 XSLT 外,前 100 字符内出现 <?xml version= 则丢弃;HTML 要求可见文本占代码量至少 20% 且不少于 100 字符;JSON/YAML 只保留字符数在 50–5000 之间的文件。经此过滤,数据量降至原始规模的 32.8%。

3.2 依赖解析与仓库级拓扑排序(第 2.2 节)

此前代码模型多在文件级语料上预训练,忽略了同一项目内文件间的依赖,因此难以扩展到项目级场景。论文用正则表达式抽取文件间的调用关系(Python 的 import、C# 的 using、C 的 include 等),构建依赖图并做拓扑排序:算法 1 先把「A 依赖 B」转成 B→A 的边并统计入度;随后找出所有非连通子图,对每个子图反复选取入度最小的节点(而非标准拓扑排序要求的入度为 0),从而可以容忍依赖图中的环。每个子图排出的文件序列拼接成一个训练样本,并在每个文件开头插入注释形式的文件路径。这样上下文所依赖的文件总是排在前面,使数据更贴近真实编码实践。

3.3 仓库级去重与质量筛选(第 2.3–2.4 节)

已有工作证明去重能显著提升性能,但文件级去重可能删掉仓库内的部分文件、破坏仓库结构,因此论文把整个仓库的拼接代码当作单个样本做近似去重。质量筛选在规则过滤之外还引入编译器与质量模型,配合启发式规则剔除语法错误、可读性差、模块化程度低的数据。清洗后共 87 种语言、798 GB、6.03 亿个文件,占比最高的是 Java(148.66 GB,18.63%)、Python(120.68 GB,15.12%)、C++(90.87 GB,11.39%)、TypeScript(60.62 GB,7.60%)、PHP(58.92 GB,7.38%)、C#(58.56 GB,7.34%)。

3.4 训练目标:下一 token 预测与 FIM(第 3.1 节)

第一目标是常规的下一 token 预测(next token prediction)。第二目标是填充中间(Fill-in-the-Middle, FIM):代码补全常需依据前后文插入内容,仅靠左到右预测无法学到这种能力,故随机把文本切成前、中、后三段再重排拼接。FIM 有两种模式:PSM(Prefix-Suffix-Middle)按 Prefix、Suffix、Middle 排列,SPM(Suffix-Prefix-Middle)按 Suffix、Prefix、Middle 排列。实现上引入三个哨兵 token,对文件切分出的 $f_{pre}$、$f_{suf}$、f_{middle} 按下式构造样本:

<|fim_start|> f_pre <|fim_hole|> f_suf <|fim_end|> f_middle <|eos_token|>

FIM 在 packing 之前于文档级施加,FIM 率为 0.5,采用 PSM 模式。消融实验用 DeepSeek-Coder-Base 1.3B 在 Python 子集上、以 HumanEval-FIM(随机遮盖一行代码,考察单行补全)为指标:100% FIM 率的 FIM 表现最好但代码补全能力最弱,说明二者存在权衡;50% PSM 率优于 MSP(Masked Span Prediction)策略,因此在 FIM 效果与补全能力之间取平衡,最终选择 50% PSM。

3.5 分词器、架构与优化(第 3.2–3.4 节)

分词器用 HuggingFace Tokenizers 库在训练语料子集上训练字节对编码(Byte Pair Encoding, BPE),词表大小 32,000。模型沿用 DeepSeek LLM 的框架:decoder-only Transformer + 旋转位置编码(Rotary Position Embedding, RoPE),33B 版本进一步引入分组查询注意力(Grouped-Query-Attention, GQA,组大小 8)以提升训练与推理效率,并全部使用 FlashAttention v2 加速注意力计算。具体配置为:隐层维度 2048/4096/7168,中间层维度 5504/11008/19200,层数 24/32/62,注意力头数 16/32/56,批大小 1024/2304/3840,最大学习率 5.3e-4/4.2e-4/3.5e-4(对应 1.3B/6.7B/33B),激活函数均为 SwiGLU。优化器为 AdamW($\beta_1=0.9$、$\beta_2=0.95$),批大小与学习率按 DeepSeek LLM 的缩放律设定;学习率采用三阶段策略,含 2000 步预热,最终学习率降至初始值的 10%,每阶段学习率降为上一阶段的 $\sqrt{\frac{1}{10}}$。训练使用 HAI-LLM 框架与 NVIDIA A100、H800 集群(每节点 8 卡,节点内 NVLink/NVSwitch,节点间 InfiniBand)。

3.6 长上下文与指令微调(第 3.6–3.7 节)

为支撑仓库级代码处理,论文重设 RoPE 参数:线性缩放因子由 1 提升到 4,基频由 10000 改为 100000,并用批大小 512、序列长度 16K 额外训练 1000 步(学习率沿用预训练最后阶段)。理论上可处理 64K token 上下文,但实证表明 16K 范围内输出最可靠。指令微调用 Alpaca 指令格式的高质量、有帮助且无偏见的人类指令构造 DeepSeek-Coder-Instruct,各轮对话以 <|EOT|> 分隔;训练采用余弦调度,100 步预热,初始学习率 1e-5,批大小 4M token,共训练 2B token。

四、主要实验结果

基准 / 任务 本模型 对比对象 说明
HumanEval 多语言(平均) Base 33B 50.3% CodeLlama-Base 34B 41.0%、GPT-3.5-Turbo 64.9%、GPT-4 76.5% Base 33B 为开源 SOTA,较 CodeLlama 34B 提升约 9%
MBPP Base 33B 66.0% CodeLlama-Base 34B 55.2%、GPT-3.5-Turbo 70.8% 较同规模开源模型提升约 11%
HumanEval(Python 单语言) Instruct 33B 79.3% GPT-3.5-Turbo 76.2%、GPT-4 84.1% 指令微调后超过 GPT-3.5-Turbo
HumanEval(Python 单语言) Base 6.7B 49.4% CodeLlama-Base 34B 48.2% 小模型超越 5 倍参数量的开源模型
DS-1000(7 个数据科学库平均) Base 33B 40.2% CodeLlama-Base 34B 34.3%、StarCoder-Base 24.6%、CodeGeeX2 22.9% 各库均有较高准确率,Pytorch 36.8%、Tensorflow 46.7%
LeetCode 竞赛(180 题,Jul 2023–Jan 2024) Instruct 33B 27.8%(+CoT 28.9%) GPT-3.5-Turbo 23.3%、GPT-4-Turbo 40.6%(+CoT 41.8%)、CodeLlama-Instruct 34B 9.4% 唯一超过 GPT-3.5-Turbo 的开源模型;与 GPT-4-Turbo 差距仍大
FIM 单行补全(三语言平均) Base 33B 81.2%、Base 7B 80.7% StarCoder 16B 69.7%、CodeLlama-Base 13B 75.5%、SantaCoder 1.1B 69.0% 连 1.3B 版本(70.4%)也超过 StarCoder 与 CodeLlama
CrossCodeEval 跨文件补全(EM,四语言) Base 6.7B +检索 16.14/17.72/14.03/16.23% CodeLlama-Base 7B +检索 13.02/16.41/12.34/13.19%、StarCoder-Base 7B +检索 13.06/15.61/7.54/14.20% 评估设定为最大序列 2048、最大输出 50、跨文件上下文 512 token,检索用官方 BM25 结果
程序化数学推理(PAL,7 基准平均) Base 33B 65.8% CodeLlama-Base 34B 62.0%、StarCoder-Base 16B 40.0% GSM8K 60.7%、MATH 29.1%、MAWPS 93.3%
v1.5 对照(Base 6.7B → v1.5 6.9B) v1.5:HumanEval 43.2%、MBPP 60.4%、GSM8K 62.4%、MATH 24.7%、MMLU 49.1%、BBH 55.2%、HellaSwag 69.9%、WinoG 63.8%、ARC-C 47.2% 原版:44.7%、60.6%、43.2%、19.2%、36.6%、44.3%、53.8%、57.1%、32.5% v1.5 编码性能轻微下降,数学推理与自然语言任务大幅提升

DeepSeek-Coder-Base 33B 在多语言 HumanEval、MBPP、DS-1000、FIM 补全与程序化数学推理上均为开源模型最佳,且优势幅度可观;DeepSeek-Coder-Base 6.7B 已能与 5 倍参数量的 CodeLlama-Base 34B 打平甚至反超,说明项目级高质量语料带来的收益可部分替代参数量。Instruct 33B 在 HumanEval 与 LeetCode 上超过 GPT-3.5-Turbo,但仍明显落后于 GPT-4/GPT-4-Turbo(LeetCode 整体 27.8% vs 40.6%)。CoT 提示对难度较高的子集增益明显(33B 在 Medium 上由 22.0% 升至 25.3%),但并非所有设定都提升。仓库级预训练的有效性由消融验证:去掉仓库级语料后,Java、TypeScript、C# 的跨文件补全性能均下降。

五、结论、局限与影响

  • 结论:DeepSeek-Coder 给出 1.3B/6.7B/33B 三档代码专用模型,在精心筛选的项目级代码语料上以「填空式」目标预训练,上下文扩展到 16,384 token;Base 33B 在各种标准测试上超越现有开源代码模型,Base 6.7B 达到 34B CodeLlama 的水平;Instruct 33B 在多项代码任务上超过 GPT-3.5 Turbo;基于 DeepSeek-LLM 7B 检查点继续预训练得到的 DeepSeek-Coder-v1.5 在保持编码能力的同时增强了自然语言理解,印证「最有效的代码大模型应建立在强通用大模型之上」。
  • 局限性:论文自述的局限包括——长上下文虽然理论上支持 64K token,但只在 16K 范围内输出最可靠,长上下文适配方法仍需继续改进与评估;LeetCode 评估中,尽管尽力收集最新题目,仍无法完全排除数据污染,且观察到 GPT-4-Turbo 与 DeepSeek-Coder 在 2023 年 7、8 月的竞赛题上得分偏高,论文提示社区注意这一风险;此外论文未明确说明 33B 模型训练的具体算力开销与训练时长。
  • 影响:该工作把「项目级/仓库级语料构造 + FIM 目标 + 长上下文」确立为代码模型预训练的标准配方之一,并以宽松许可证开放全部权重,直接缩小了开源与闭源代码模型之间的能力差距;其仓库级去重、n-gram 去污染流程与 50% PSM 的 FIM 配置被后续代码模型广泛沿用,v1.5 的「通用模型继续预训练」路线也预示了后续 DeepSeek-Coder-V2 的技术方向。

六、关键术语对照表

English 中文
Fill-in-the-Middle (FIM) 中间填充
Next Token Prediction 下一 token 预测
Prefix-Suffix-Middle (PSM) 前缀-后缀-中间(FIM 模式)
Suffix-Prefix-Middle (SPM) 后缀-前缀-中间(FIM 模式)
Masked Span Prediction (MSP) 掩码片段预测
Repository-Level Deduplication 仓库级去重
Near-Deduplication 近似去重
Dependency Parsing 依赖解析
Topological Sort 拓扑排序
Decontamination 去污染
Cross-File Code Completion 跨文件代码补全
Program-Aided Math Reasoning (PAL) 程序辅助数学推理
Chain-of-Thought (CoT) 思维链
Grouped-Query-Attention (GQA) 分组查询注意力
Rotary Position Embedding (RoPE) 旋转位置编码
Byte Pair Encoding (BPE) 字节对编码
Instruction Tuning 指令微调