Qwen3-Coder FIM 基准评测实战:CrossCodeEval、CrossCodeLongEval、RepoEval 与 humaneval-infilling 完整指南
【免费下载链接】Qwen3-CoderQwen3-Coder is the code version of Qwen3, the large language model series developed by Qwen team.项目地址: https://gitcode.com/GitHub_Trending/co/Qwen3-Coder
本篇技术指南以 Qwen3-Coder 仓库中 fim-bench 评测模块 为骨架,系统讲解 Fill-In-the-Middle(FIM)类代码补全基准的评测流程:从数据准备、脚本调用、上下文模式选择,到指标计算与结果解读。读完本文,你将掌握在本地复现 CrossCodeEval、CrossCodeLongEval、RepoEval、humaneval-infilling 四类 FIM 评测的完整实操能力,并理解评测脚本底层如何构造 prompt、如何利用 tree-sitter 做语法级后处理、如何计算 EM/ES 等核心指标。
一、FIM 评测在 Qwen3-Coder 评测体系中的定位
Qwen3-Coder 是 Qwen 团队发布的代码版大语言模型系列,其评测体系(qwencoder-eval)覆盖 base、instruct、reasoning 等多类模型的全面能力验证。其中qwencoder-eval/base/benchmarks/fim-bench/专门面向FIM(Fill-In-the-Middle,中间填充)任务——即给定代码的前缀(prefix)和后缀(suffix),让模型补全中间被挖空的部分。这是代码补全工具(如 IDE 自动补全、AI 编程助手)最核心的底层能力之一。
该模块的目录结构清晰地反映了评测的组织方式:
qwencoder-eval/base/benchmarks/fim-bench/ ├── cceval/ # CrossCodeEval 评测数据与脚本 ├── cclongeval/ # CrossCodeLongEval 评测数据与脚本 ├── hm_fim/ # humaneval-infilling 评测数据与脚本 ├── repoeval/ # RepoEval 评测数据与脚本 ├── run_cceval.sh # 各基准的启动脚本 ├── run_cclongeval.sh ├── run_repoeval.sh ├── run_hm_fim.sh ├── eval_metric.py # 指标计算与 tree-sitter 后处理 └── utils.py # prompt 构造与 FIM 特殊 token 处理四个基准从不同维度检验 FIM 能力:CrossCodeEval 侧重多语言跨文件上下文(cross-file context),CrossCodeLongEval 侧重长距离代码块的补全,RepoEval 侧重仓库级 API/函数/行级补全,humaneval-infilling 则基于经典 HumanEval 改造为挖空补全形式。下文逐一展开。
二、环境准备与依赖说明
官方 README 对环境的要求非常精简,但结合源码可梳理出完整依赖链:
- tree-sitter == 0.20.1:README 明确指出此版本要求。tree-sitter 用于代码的语法树解析,是评测后处理(判断生成结果是否语法合法、抽取函数体)的关键依赖;
- vLLM:所有评测脚本通过
from vllm import LLM, SamplingParams加载模型并进行批量推理(见 cceval.py),推理时使用temperature=0, top_p=1的贪婪解码,并通过tensor_parallel_size支持多 GPU 张量并行; - transformers:用于加载
AutoTokenizer构造 prompt(见 cceval.py); - 其他:
fuzzywuzzy、editdistance、numpy、timeout_decorator、tqdm等用于指标计算与进度展示(见 eval_metric.py 的导入部分)。
需要注意的是,所有启动脚本均以export LC_ALL="POSIX"开头,并设置export TOKENIZERS_PARALLELISM=false(避免多进程 tokenizer 冲突)与export VLLM_ALLOW_LONG_MAX_MODEL_LEN=1(允许 vLLM 处理较长序列)。
三、CrossCodeEval:多语言跨文件上下文代码补全
3.1 数据准备
CrossCodeEval 的数据以压缩包形式内置于仓库:
cd qwencoder-eval/base/benchmarks/fim-bench/cceval bash prepare_data.shprepare_data.sh 的实际逻辑非常简单:创建processed_data目录,并将crosscodeeval_data.tar.xz解压到其中。解压后即得到各语言(python、java、csharp、typescript)的评测 prompt 文件。
3.2 运行评测
bash ./run_cceval.sh <模型路径> <输出目录> <tp>三个位置参数的含义:
| 参数 | 说明 |
|---|---|
<模型路径> | 预训练模型的路径(本地目录或 HuggingFace 模型名,需含 tokenizer) |
<输出目录> | 评测结果的保存目录(脚本会在此目录下创建cceval/子目录) |
<tp> | 并行 GPU 数量,即 vLLM 的tensor_parallel_size(见 cceval.py) |
从 run_cceval.sh 可以看到完整命令:
python cceval/cceval.py \ --task line_completion \ --model_type codelm_right_cfc_left \ --model_name_or_path ${INPUT_MODEL} \ --cfc_seq_length 2048 \ --right_context_length 2048 \ --prompt_file cceval/processed_data/LANGUAGE/line_completion_oracle_bm25.jsonl \ --gen_length 50 \ --max_seq_length 8192 \ --output_dir ${OUTPUT_DIR} \ --dataset cceval \ --tp ${TP} \ --ts_lib build/LANGUAGE-lang-parser.so \ --language python java csharp typescript3.3 是否使用 cross-file context(两种上下文模式)
README 强调,脚本通过model_type参数控制两种上下文模式。结合 utils.py 的prepare_prompt函数,两种模式的 prompt 构造方式如下:
codelm_right_cfc_left:启用跨文件上下文模式。prompt 结构为{fim_prefix}{左侧截断上下文}{fim_suffix}{右侧上下文}{cross-file 上下文}{fim_middle},其中 cross-file 上下文(来自检索到的同仓库其他文件)会拼接到后缀之后、middle token 之前;codelm_leftright_context:禁用跨文件上下文模式。prompt 结构为{fim_prefix}{左侧上下文}{fim_suffix}{右侧上下文}{fim_middle},不注入 cross-file 上下文。humaneval-infilling 使用的正是该模式(见 run_hm_fim.sh)。
在 cceval.py 的参数定义中,--model_type的可选值为codelm、codelm_cfc、codelm_leftright_context、codelm_right_cfc_left,默认codelm;但prepare_prompt目前只实现了codelm_leftright_context与codelm_right_cfc_left两种分支,其余会抛出NotImplementedError,因此实际可用的就是这两种模式。
另外值得注意:prepare_prompt会根据模型名自动匹配 FIM 特殊 token(见 utils.py):
| 模型名匹配 | prefix token | middle token | suffix token |
|---|---|---|---|
| deepseek | <|fim_begin|> | <|fim_end|> | <|hole|> |
| qwen1.5 | <fim_prefix> | <fim_middle> | <fim_suffix> |
| qwen(含 Qwen3-Coder) | <\|fim_prefix\|> | <\|fim_middle\|> | <\|fim_suffix\|> |
| 其他 | <fim_prefix> | <fim_middle> | <fim_suffix> |
3.4 主要参数说明
README 列出了四个核心参数,结合源码可补充其默认值与截断逻辑:
| 参数 | README 说明 | 默认值(源码) | 截断逻辑 |
|---|---|---|---|
cfc_seq_length | 跨文件上下文最大长度 | 512 | 对'\n\n' + crossfile_cxt编码后取前cfc_seq_length个 token |
right_context_length | 右侧上下文最大长度 | 512 | 对右侧上下文编码后取前right_context_length个 token |
gen_length | 代码补全生成长度 | 50 | 采样时作为max_tokens;若任务为function_completion会自动提升为 256(见 utils.py) |
max_seq_length | 总序列最大长度 | 2048(README 中评测用 8192) | 左侧上下文截断为max_seq_length - gen_length - right_context_length - cfc_seq_length个 token |
除 README 列出的参数外,源码还支持:--task(line_completion/function_completion/api_completion三选一,必填)、--num_return_sequences(默认 1)、--dataset(默认cclong)、--only_compute_metric、--compute_cceval_metric等(见 cceval.py)。
四、CrossCodeLongEval:长距离代码块补全
CrossCodeLongEval 关注更长距离的代码补全场景(跨更远的上下文挖空补全),与 CrossCodeEval 共用同一套评测框架(cclong.py 的推理逻辑与 cceval.py 基本一致)。
4.1 数据准备
cd qwencoder-eval/base/benchmarks/fim-bench/cclongeval bash prepare_data.sh该目录内置了cceval_chunk_eval_data.tar.gz与cceval_function_eval_data.tar.gz两个数据包,prepare_data.sh负责解压生成processed_data下的评测文件。
4.2 运行评测
bash ./run_cclongeval.sh <模型路径> <输出目录> <tp>从 run_cclongeval.sh 可见其核心差异:任务为chunk_completion与function_completion两个,prompt 文件模板为cclongeval/processed_data/python_TASK_sparse_oracle.jsonl(TASK会被替换为具体任务名),且仅评测 Python 语言。同样使用codelm_right_cfc_left模式与--ts_lib build/python-lang-parser.so的 tree-sitter 解析库。值得一提的是,cclong.py 在构造数据时会优先使用full_right_context(完整右侧上下文)作为后缀,这有助于检验模型在长距离上下文下的补全能力。
五、RepoEval:仓库级三种补全任务
RepoEval 将评测细分为三类仓库级补全任务,直接对应--task参数的三个取值:
bash ./run_repoeval.sh <模型路径> <输出目录> <tp>run_repoeval.sh 中一次运行line_completion、function_completion、api_completion三个任务:
- line_completion(行级补全):挖空某一行代码,检验模型的短距离行内补全能力;
- function_completion(函数级补全):挖空整个函数体,生成长度在 utils.py 中被自动放大为 256 token;
- api_completion(API 级补全):基于仓库内 API 调用习惯进行补全,更贴近真实工程场景。
该评测的 prompt 数据已预置于 repoeval/processed_data 目录,每种任务均提供三个变体文件:python_api_completion.jsonl、python_function_completion.jsonl、python_line_completion.jsonl以及对应的_sparse_oracle、_sparse_rg1版本,用于测试不同检索/稀疏策略下的输入;同时提供repocoder_packages.jsonl记录仓库与包的映射信息。仓库级上下文通过codelm_right_cfc_left模式注入,评测语言为 Python。
六、humaneval-infilling:经典 HumanEval 挖空补全
bash ./run_hm_fim.sh <模型路径> <输出目录> <tp>与前三个基准不同,humaneval-infilling 采用codelm_leftright_context模式(不注入 cross-file 上下文),专注于纯粹的前缀-后缀挖空补全。从 run_hm_fim.sh 可见其输出目录会自动追加humaneval-infilling子目录。数据方面,hm_fim/data 内置了fim_singleline.jsonl(单行挖空样本)与train.parquet,并提供 preprocess.py 用于数据预处理。
评测打分逻辑在 humaneval_fim.py 的evaluate_results中:对模型生成结果取第一行、与标准答案做字符串精确匹配(exact_match_rate)和 fuzzywuzzy 编辑相似度(average_edit_similarity)统计,并按语言维度汇总后输出 overall 结果,评测报告使用 rich 表格打印。
七、指标计算与结果解析:EM / ES / ES RepoEval
所有基准共享 eval_metric.py 中的指标体系,READM 虽未展开,但这是理解评测结果的关键:
7.1 三项核心指标
- EM(Exact Match,精确匹配率):将预测与标准答案按正则做 token 化(tokenize_code,含 camelCase 拆分、标点分隔、引号统一),判断 token 序列是否完全一致后取平均;
- ES(Edit Similarity,编辑相似度):基于 fuzzywuzzy 的
fuzz.ratio计算的字符串相似度均值; - ES RepoEval:基于
editdistance的归一化编辑距离相似度(1 - edit_distance / max_len),是 RepoEval 官方推荐的评估口径。
7.2 tree-sitter 语法级后处理
评测并非简单对比生成文本,而是先做语法有效性校验:
is_parse_valid:利用 tree-sitter 解析prompt + completion,检查 AST 中是否存在ERROR节点(eval_metric.py);get_valid_completion:若整体不可解析,则从完整补全逐步截断字符,找到最长可解析前缀,返回"parseable"状态(eval_metric.py);get_function_completion:对 function_completion 任务,用get_functions提取目标函数体后再与标准答案比较(eval_metric.py)。
tree-sitter 解析库通过--ts_lib参数指定(如build/python-lang-parser.so),多语言评测时LANGUAGE占位符会被替换,且csharp会映射为 tree-sitter 的c_sharp语言名(见 eval_metric.py)。后处理与打分使用多进程并行(mp.Pool(mp.cpu_count() - 1))加速。
7.3 输出文件与结果汇总
运行完成后,输出目录下会生成结构化结果:
{output_dir}/{dataset}/{language}/{task}/prediction.jsonl:模型原始预测(每条含task_id、pred、task_type、inputs,其中 pred 已按<|fim_pad|>、<|file_sep|>截断,见 cceval.py);{output_dir}/{dataset}/{language}/{task}/detailed_results.json:逐样本的em、es、es_repoeval明细;{output_dir}/{dataset}/{language}/{task}/results.json:该任务/语言的汇总指标;{output_dir}/{dataset}/results.json:整体汇总(按样本数加权的 EM/ES/ES RepoEval,含overall与per_task/per_language两个层级,见 eval_metric.py)。
八、评测要点小结
- 上下文模式选择:仓库级基准(CrossCodeEval/CrossCodeLongEval/RepoEval)默认使用
codelm_right_cfc_left注入跨文件上下文,humaneval-infilling 使用codelm_leftright_context纯前后缀模式; - 参数三要素:模型路径、输出目录、GPU 并行数(tp)三个位置参数即满足最小运行要求,其余参数均有合理默认值;
- Qwen 系模型自动适配:
prepare_prompt会为 Qwen 系模型自动使用<|fim_prefix|>、<|fim_middle|>、<|fim_suffix|>三 token 模板,评测 Qwen3-Coder 无需额外配置; - 评测质量保障:tree-sitter 语法校验 + 最长可解析前缀截断,保证指标反映的是"合法代码"而非文本巧合匹配;
- 环境约束:tree-sitter 需为 0.20.1,推理依赖 vLLM(建议启用 Ray 分布式后端),生成时采用贪婪解码以保证可复现性。
通过本指南,你可以在 Qwen3-Coder 评测体系下完整复现四类 FIM 基准的评测链路,并结合results.json与detailed_results.json深入分析模型在不同语言、不同补全粒度上的具体表现。
【免费下载链接】Qwen3-CoderQwen3-Coder is the code version of Qwen3, the large language model series developed by Qwen team.项目地址: https://gitcode.com/GitHub_Trending/co/Qwen3-Coder
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考