Qwen2.5-Coder 论文解读:5.5T 代码 token 喂出来的开源编程专家,把 DeepSeek-Coder 逼到了墙角
论文:Qwen2.5-Coder Technical Report 作者:Binyuan Hui, Jian Yang, Zeyu Cui, Jiaxi Yang, Dayiheng Liu, Lei Zhang 等 24 人(阿里 Qwen 团队),arXiv<2409>2409>.12186,2024 年 9 月首次提交,11 月更新到 v3 这篇报告讲的是 Qwen 团队怎么把代码模型做到”开源天花板”级别。一句话概括:六个尺寸、5.5 万亿 token 的代码预训练、从补全到修复全场景覆盖。它不只是发了一个模型,而是发了一整个”代码模型矩阵”,把 0.5B 到 32B 的每个价位段都占满了。我的判断:这是 2024 年下半年开源代码模型最狠的一次出手。
一、先说结论:一家六口,个个能打
Qwen2.5-Coder 是 CodeQwen1.5 的直系升级,一次性发了六个模型:0.5B、1.5B、3B、7B、14B、32B,每个尺寸都有 Base 和 Instruct 两个版本,一共 12 个权重。这个”全家桶”策略本身就值得说——别人家要么只发一个旗舰(比如 Codestral 只有 22B),要么尺寸断档(CodeLlama 是 7B/13B/34B),Qwen 是把每个生态位都堵死了:
- 0.5B/1.5B:跑在手机、边缘设备、IDE 插件里做实时补全;
- 3B/7B:本地工作站的主力;
- 14B/32B:跟闭源 API 正面刚。
技术报告里自己给的说法是:在超过 10 个代码基准上拿到 SOTA,覆盖**代码生成(generation)、补全(completion)、推理(reasoning)、修复(repair)**四大场景。注意”修复”这个词——多数代码报告不敢测这个,因为数据难看。Qwen 敢写进摘要,说明心里有底。
底层架构完全继承 Qwen2.5:GQA(分组查询注意力)、词表 151,646,还专门为代码加了 6 个特殊 token,包括 FIM 的四个标记(prefix/middle/suffix/pad)、仓库名标记和文件分隔符。这些 token 不是摆设,后面讲仓库级训练时会用到。
二、数据工程:5.5 万亿 token 是怎么来的
1. 五路数据源
训练语料统称 Qwen2.5-Coder-Data,总共约 5.5T tokens,分五类:
| 数据类型 | 来源 | 作用 |
|---|---|---|
| 源代码 | GitHub 公开仓库,覆盖 92 种编程语言,含 PR、Commit、Jupyter Notebook、Kaggle | 主力,教模型”代码长什么样” |
| 文本-代码混合 | Common Crawl 里的文档、教程、博客 | 教模型”代码在文档里怎么被讨论” |
| 合成数据 | CodeQwen1.5 生成,执行器验证可运行 | 提纯,减少幻觉 |
| 数学数据 | 直接搬 Qwen2.5-Math 的预训练语料 | 保住数学能力 |
| 通用文本 | Qwen2.5 语料,但剔除了代码片段 | 保住通用语言能力 |
这里有个细节很见功力:通用文本里特意把代码片段移除,避免跟源代码语料重复计数;数学数据则是整个 Qwen2.5-Math 的语料库直接并入。这就是”代码模型不变成偏科生”的关键操作。
2. 过滤和配比:脏活出真功夫
数据清洗走的是”粗到细”路线:规则过滤打底,再用小模型分类器/打分器(比如 fastText)做分层过滤。报告里给了一个很实在的数字:光是对文本-代码数据做四级过滤,Qwen2.5-Coder-1.5B 的 HumanEval+MBPP 平均分就从 41.6% 提到 46.8%——五个多点,全靠洗数据洗出来的,一分钱模型结构没改。
合成数据这块也值得说:用上一代 CodeQwen1.5 生成代码,然后真的拿去执行,跑不通的直接扔掉。“用执行器验证”这五个字,是合成代码数据和”纯 LLM 编出来的代码”的分水岭。
最后是数据配比实验,比较了 Code/Text/Math 不同比例,定下来 70% 代码、20% 文本、10% 数学,最终训练集约 5.2T token(六个模型的总训练量标 5.5T)。这个配比透露了一个判断:代码模型想不偏科,三成非代码数据是下限。
三、训练路线:三阶段,从”读文件”到”读仓库”
1. 文件级预训练:next-token + FIM 双目标
第一阶段最大序列长度 8,192,吃下约 5.2T 数据。训练目标有两个:常规的下一 token 预测,加上 FIM(Fill-in-the-Middle,中间填充)。
FIM 是什么?简单说就是把一个文件切成三段:前缀、后缀、中间待填的部分,训练时打乱顺序让模型”看着前后文补中间”。这就是 IDE 里代码补全的真实场景——你的光标永远在文件中间,没人只从第一行往下写。模型为此专门留了四个特殊 token(FIM prefix/middle/suffix/pad,ID 151659-151662)。
2. 仓库级预训练:8K → 32K → 128K
第二阶段把上下文从 8,192 拉到 32,768,用约 300B 长上下文代码数据继续训。RoPE 基频从 10,000 调到 1,000,000,再叠上 YARN(Yet Another RoPE extensioN)外推,推理时能撑到 131,072 token,也就是 128K。
这一步配套了两个设计:
- 仓库级 FIM(repo-level FIM):待补全的洞不再只在单个文件里,而是跨文件、跨整个仓库。模型要学会从别的文件里找线索来补当前文件。
- 特殊 token 里那个”仓库名”和”文件分隔符”就是为这个阶段准备的,用来把多个文件打包成一个训练序列。
报告里做了个朴素但硬核的验证:往长代码库里插入一个自定义函数,看模型能不能在 128K 范围内把它检索/复述出来。能。这说明 128K 不是纸面数字。
3. 后训练:粗到细 SFT + 拒绝采样 + DPO
指令微调走”粗到细(coarse-to-fine)“路线:先喂数千万条低质量但多样的指令样本铺广度,再用数百万条高质量样本提精度。数据生产上有几个亮点:
- 用 CodeBERT 微调出编程语言识别器,覆盖近 100 种语言,先把指令数据按语言分桶;
- 从 GitHub 代码片段反向合成指令:LLM 出题、代码模型作答、再用 LLM 打分过滤,打分用一套 checklist(问答一致性、代码正确性、代码规范、注释质量……);
- 用 tree-sitter 解析代码 AST,随机抽逻辑块当”待填中间”,造出 FIM 格式的指令样本——也就是说 SFT 阶段也没丢补全能力,大部分标准 SFT 数据加少量 FIM 指令数据混训(mixed tuning);
- 最后上 DPO(直接偏好优化):同一个 query 生成多个候选,能跑的代码用多语言沙箱执行验证,跑不动的复杂代码用 LLM-as-a-judge 打分。
去污染也做了:对预训练和后训练数据做 10-gram 重叠过滤,把 HumanEval、MBPP、GSM8K、MATH 这些测试集都剔掉。敢公开说做了去污染的代码报告,可信度高一截。
四、代码生成:32B-Instruct 把开源纪录又刷了一遍
1. Base 模型:同尺寸全面碾压
先看 Base 模型在 HumanEval/MBPP 上的表现:
| 模型 | HumanEval | HumanEval+ | MBPP | MBPP+ |
|---|---|---|---|---|
| Qwen2.5-Coder-7B-Base | 61.6 | 53.0 | 76.9 | 62.9 |
| CodeQwen1.5-7B(前代) | 51.8 | 45.7 | 72.2 | 60.2 |
| Qwen2.5-Coder-32B-Base | 65.9 | 60.4 | 83.0 | 68.2 |
| DeepSeek-Coder-33B-Base | 54.9 | 47.6 | 74.2 | 60.7 |
| StarCoder2-15B | 46.3 | 37.8 | 66.2 | 53.1 |
对比很直白:32B-Base 对 DeepSeek-Coder-33B-Base,HumanEval 高出 11 个点(65.9 vs 54.9);对 StarCoder2-15B,高出快 20 个点。7B 对自家前代 CodeQwen1.5,HumanEval 从 51.8 拉到 61.6,一代涨 10 个点,这就是 5.5T 数据堆出来的效果。
2. Instruct 模型:贴着 GPT-4o 打
Instruct 版本才是真正的战场:
| 模型 | HumanEval | HumanEval+ | MBPP | BigCodeBench Hard | LiveCodeBench |
|---|---|---|---|---|---|
| Qwen2.5-Coder-32B-Instruct | 92.7 | 87.2 | 90.2 | 27.0 | 31.4 |
| GPT-4o (2024-08) | 92.1 | 86.0 | 86.8 | 25.0 | 34.6 |
| Claude-3.5-Sonnet | 92.1 | 86.0 | 91.0 | 23.6 | 31.6 |
| DeepSeek-Coder-V2-Instruct | 85.4 | 82.3 | 89.4 | 24.3 | 27.9 |
| CodeLlama-70B-Instruct | 72.0 | 65.9 | 77.8 | 11.5 | 3.3 |
| StarCoder2-15B-Instruct | 67.7 | 60.4 | 78.0 | 11.5 | 12.1 |
划重点:
- HumanEval 92.7,全场最高,比 GPT-4o 还高 0.6;MBPP 90.2,同样压过 GPT-4o 的 86.8;
- BigCodeBench Hard 27.0,开源第一,这个基准考的是工具调用和复杂指令跟随,接近真实 Agent 场景;
- 最狠的是跟 CodeLlama 的对比:CodeLlama-70B-Instruct 参数量是 Qwen2.5-Coder-32B 的两倍多,HumanEval 却只有 72.0,差出 20 个点。这就是”一代数据红利”的直观体现——CodeLlama 是 2023 年的产物,吃的还是 1T 量级的代码数据。
3B-Instruct 也值得单拎出来:HumanEval 84.1,比 StarCoder2-15B-Instruct(67.7)高 16 个点,参数量却只有五分之一。小模型做到这个份上,本地部署的门槛已经低到没什么借口了。
还有一个容易被忽略的数字:32B-Instruct 的 HumanEval+(更严格的测试用例版本)拿到 87.2,跟 GPT-4o、Claude-3.5-Sonnet 完全并列。HumanEval+ 的题面没变但用例更刁钻,专门抓”侥幸过测”的代码,能在上面拿 87+ 说明生成的代码不是背题库背出来的,是真的理解了边界条件。
五、代码补全与仓库级:IDE 场景的真护城河
生成能力大家都在卷,补全才是代码模型的差异化战场——因为补全要求的不是”从零写一段”,而是”读懂上下文、跨文件找依赖、精确填洞”。
| 模型 | HumanEval-FIM 均值 | CrossCodeEval EM | RepoEval EM |
|---|---|---|---|
| Qwen2.5-Coder-7B-Base | 86.2 | 49.3 | 46.3 |
| Qwen2.5-Coder-14B-Base | 87.7 | 55.4 | 50.6 |
| Qwen2.5-Coder-32B-Base | 88.3 | 57.1 | 51.6 |
HumanEval-FIM 上 32B 的分语言成绩:Python 81.5、Java 91.0、JavaScript 89.4——Java 补全比 Python 还高,这在代码模型里不常见,说明 FIM 训练确实喂到位了。CrossCodeEval 和 RepoEval 考的都是跨文件补全,32B 拿到 57.1 和 51.6,是同尺寸开源里的最高档。
多语言覆盖上,MultiPL-E 平均:32B-Base 63.9,32B-Instruct 79.4(Python 92.7、Java 80.4、C# 82.9、TypeScript 86.8)。Instruct 版本跟 DeepSeek-Coder-V2-Instruct 的 79.9 基本打平,跟 GPT-4o 的 79.1 也在一条线上,只有 Claude-3.5-Sonnet 的 83.8 拉开了一点差距。另外报告还测了 McEval(40 种语言、16,000 个测试用例)和 MdEval(18 种语言的调试基准,1.2K 样本),这两个偏”广度+调试”的基准也以图的形式给了结果,结论一致:开源第一梯队。
六、不只是代码:数学和通用能力的”意外之喜”
代码模型的传统短板是”离了代码就废”,Qwen2.5-Coder 用数据配比硬是把这个短板补上了。Base 模型:
| 模型 | MATH | GSM8K | MMLU |
|---|---|---|---|
| Qwen2.5-Coder-32B-Base | 57.2 | 91.1 | 79.1 |
| DeepSeek-Coder-33B-Base | 14.4 | 35.4 | 39.5 |
| DeepSeek-Coder-V2-Base | 50.6 | 85.8 | 76.0 |
看第一行对比就知道差距多夸张:DeepSeek-Coder-33B 的 MATH 只有 14.4,Qwen2.5-Coder-32B-Base 是 57.2——差出四倍。原因不复杂:那 10% 的数学数据是直接搬的 Qwen2.5-Math 全套语料。
Instruct 版本更离谱一点:32B-Instruct 在 MATH 上 76.4、AIME24 拿 20.0,比以数学见长的 DeepSeek-Coder-V2-Instruct(MATH 74.2、AIME 6.7)还高。通用能力上,MMLU 77.6、IFEval 79.9、CEval 68.9——IFEval 79.9 这个数字说明指令跟随能力很强,这对做 Agent 底座是硬指标。
一句话总结:这已经不是”会写代码的语言模型”,而是”代码特化但没瘸腿的通才”。
七、修复、编辑与 Agent:从”写代码”到”改代码”
1. 代码编辑:Aider 基准
Aider 是模拟真实 IDE 里”给需求、改现有代码”的基准,测的是编辑能力而非从零生成:
| 模型 | Pass@1 | Pass@2 |
|---|---|---|
| Qwen2.5-Coder-32B-Instruct | 60.9 | 73.7 |
| DeepSeek-Coder-V2-Instruct | 51.9 | 73.7 |
| GPT-4o | 56.8 | 74.4 |
| Claude-3.5-Sonnet | 71.4 | 86.5 |
| CodeLlama-70B-Instruct | 12.8 | 15.0 |
32B-Instruct 的 Pass@1 60.9,开源第一,甚至超过 GPT-4o 的 56.8;只有 Claude-3.5-Sonnet 明显领先。CodeLlama-70B 在这里只有 12.8,再次证明老一代模型在”改代码”上基本不可用。CodeEditorBench 上 32B-Instruct 跟 DeepSeek-Coder-V2 打平(86.2% win rate 附近)。
2. Agent 与工具使用
报告没有单独开 Agent 章节,但三块内容都在给 Agent 铺路:BigCodeBench 考工具调用(32B 开源第一);仓库级 FIM + 128K 上下文是”读懂整个项目再动手”的前提;IFEval 79.9 保证指令跟随不掉链子。报告自己就把应用场景点名到了”代码助手和 Artifacts”。换句话说,32B-Instruct 就是奔着当 Coding Agent 底座去的——后来它在 SWE-bench 这类真实 issue 修复基准上的表现也印证了这条路线。
3. 代码推理:CRUXEval
CRUXEval 考的是”读代码推执行结果”,32B-Instruct 拿 Input-CoT 75.2 / Output-CoT 83.4,开源第一;但 GPT-4o(78.6/89.2)和 o1-mini(91.6/96.2)还是拉开了身位。这是报告里少数”没打赢”的地方,也说明纯推理这条线上,靠堆数据是有天花板的。
收尾:我的一点看法
第一,这篇报告最大的信息量不在模型,在数据配方。5.5T token 里,“92 种语言的 GitHub 源码”只是基本盘,真正的胜负手是三个动作:四级过滤换来 5 个点的 HumanEval 提升、执行器验证的合成数据、以及 70/20/10 的 Code/Text/Math 配比。模型结构一点没动(就是 Qwen2.5),提升全靠喂什么、怎么喂。这基本宣告了代码模型竞争进入”数据工程军备竞赛”阶段。
第二,“全家桶”策略的产业意义被低估了。0.5B 到 32B 六个尺寸同代发布,意味着从 IDE 插件的毫秒级补全到 Agent 的仓库级重构,可以用同一套训练方法论覆盖。3B-Instruct 的 HumanEval 84.1 尤其值得注意——这个数字让”本地跑一个像样的编程助手”从极客玩具变成了默认选项。
第三,跟 DeepSeek-Coder 的对比很说明问题。同为国产、同为主打代码,Qwen2.5-Coder-32B 在生成、补全、数学上全面压过 DeepSeek-Coder-V2,只有 MultiPL-E 多语言平均分上小幅落后(79.4 vs 79.9)。而跟闭源的差距,在 HumanEval/MBPP 这类经典基准上已经抹平甚至反超,真正还剩差距的是 LiveCodeBench(31.4 vs GPT-4o 的 34.6)和 CRUXEval 这种考推理的硬骨头。趋势很清楚:记忆和模式匹配的活儿开源已经赢了,实时竞赛题和深推理还在闭源手里。
第四,一点保留意见。报告坦承 LiveCodeBench 不及 GPT-4o,CRUXEval 不及 o1-mini,这两块恰好是”背题库”最难覆盖的能力。另外 SWE-bench 这类端到端修 issue 的评测在报告里没给数字,说明写报告时仓库级 Agent 的闭环验证还在路上。32B 的 HumanEval 92.7 固然漂亮,但真正决定这个模型历史地位的,是它后来作为 Agent 底座的实际表现——从后续社区的反馈看,它确实扛住了。
第五,关于开源生态。报告特意强调了宽松授权(permissive license),这不是客套话——0.5B 到 32B 全系列可商用,意味着从创业公司到个人开发者都能直接拿去做产品。回头看 2024 年的开源代码模型格局,StarCoder2 起了个大早,DeepSeek-Coder 把水位拉高,而 Qwen2.5-Coder 用全家桶策略把水位线又抬了一截,并且让”选哪个尺寸”这个问题第一次有了覆盖所有场景的答案。
总的来说,这是一篇”没什么新架构、全是硬功夫”的技术报告。它的价值不在于提出了什么新方法,而在于把数据清洗、合成验证、配比实验、三阶段训练这套工程流程做到了当时开源界的最高完成度,然后用 12 个权重文件把结果摊在桌面上。对做代码智能的人来说,这份报告就是 2024 年的路线图。
附:核心数据速查
模型与训练一览
| 项目 | 数值 |
|---|---|
| 模型尺寸 | 0.5B / 1.5B / 3B / 7B / 14B / 32B(各含 Base + Instruct) |
| 训练 token 总量 | 约 5.5T |
| 代码语言覆盖 | 预训练 92 种;语言识别器近 100 种 |
| 数据配比 | 70% 代码 / 20% 文本 / 10% 数学 |
| 文件级阶段 | 最大序列 8,192,约 5.2T token,next-token + FIM |
| 仓库级阶段 | 上下文 8K → 32K,约 300B 长上下文数据;YARN 外推至 128K |
| RoPE 基频 | 10,000 → 1,000,000 |
| 词表大小 | 151,646 |
| 授权 | 宽松许可(permissive license) |
旗舰模型关键战绩(32B-Instruct)
| 基准 | 分数 | 位置 |
|---|---|---|
| HumanEval | 92.7 | 全场最高(超 GPT-4o 的 92.1) |
| MBPP | 90.2 | 超 GPT-4o 的 86.8 |
| BigCodeBench Hard | 27.0 | 开源第一 |
| LiveCodeBench | 31.4 | 略低于 GPT-4o 的 34.6 |
| MultiPL-E 均值 | 79.4 | 与 DeepSeek-Coder-V2 打平 |
| Aider Pass@1 | 60.9 | 开源第一(超 GPT-4o 的 56.8) |
| MATH | 76.4 | 超 DeepSeek-Coder-V2 的 74.2 |
| MMLU | 77.6 | 通用能力不瘸腿 |
| IFEval | 79.9 | 指令跟随强,适合 Agent 底座 |
| CRUXEval Out-CoT | 83.4 | 开源第一,但低于 o1-mini 的 96.2 |
概念清单
- FIM(Fill-in-the-Middle,中间填充):把文件切成前缀/后缀/待填中段,训练模型看前后文补中间,是 IDE 补全能力的来源。
- Repo-level FIM(仓库级中间填充):待填的洞跨文件、跨仓库,逼模型学会从项目全局找上下文。
- YARN:RoPE 外推技术,配合调高的基频把上下文从 32K 拉到 128K。
- GQA(Grouped Query Attention,分组查询注意力):继承自 Qwen2.5 的注意力结构,省显存、提推理速度。
- Coarse-to-fine SFT(粗到细微调):先用数千万条多样但粗糙的指令铺广度,再用数百万条高质量样本提精度。
- DPO(Direct Preference Optimization,直接偏好优化):离线偏好对齐;代码用多语言沙箱执行验证,复杂样本用 LLM-as-a-judge。
- MultiPL-E:多语言代码生成基准,覆盖 Python/C++/Java/JS/TS 等主流语言。
- BigCodeBench:考工具调用与复杂指令跟随的基准,接近 Agent 实战。
- LiveCodeBench:滚动更新的竞赛题基准,防数据污染,考真实泛化。
- CRUXEval:代码执行推理基准,给代码推输入/输出。
- Aider:模拟”在现有代码库上按需求编辑”的基准,测改代码而非写代码。
- McEval / MdEval:大规模多语言基准(40 种语言 16,000 用例)与 18 语言调试基准(1.2K 样本)。
如果这篇文章对你有帮助,欢迎分享给更多人!
部分信息可能已经过时





