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

97 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# DeepSeek-Coder:当大语言模型遇见编程——代码智能的崛起
> **原文标题**:DeepSeek-Coder: When the Large Language Model Meets Programming -- The Rise of Code Intelligence
> **arXiv**:[2401.14196](https://arxiv.org/abs/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](./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}$ 按下式构造样本:
```text
<|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 | 指令微调 |