☰
DeepSeek-Coder 数学推理评估实战:基于 PAL 方法的七大数据集评测指南
2026/9/30 6:40:45 网站建设 项目流程
  • 人工智能
  • 大模型
  • 代码模型
  • 预训练
  • 微调
  • 模型评测
  • DeepSeek

【免费下载链接】DeepSeek-Coder

DeepSeek Coder: Let the Code Write Itself

项目地址:https://gitcode.com/GitHub_Trending/de/DeepSeek-Coder
点击查看免费下载

本指南围绕本仓库Evaluation/PAL-Math目录下的评估脚本展开,系统讲解如何用PAL(Program-Aided Language Models)方法评测 DeepSeek-Coder 系列代码模型在数学推理任务上的能力——让模型编写可执行的 Python 程序,再由 Python 解释器代为完成计算。读完本文,你将掌握评估环境的搭建、多 GPU 并行推理与离线判分的完整命令流程、run.py中各参数的底层作用,以及 GSM8k、MATH、GSM-Hard、SVAMP、TabMWP、ASDiv、MAWPS 七大数据集的结果口径与判分原理,可直接复现官方基准结果。

1. 评估思路:为什么用代码解数学题

传统的大模型数学推理依赖模型在自然语言中"心算",而 DeepSeek-Coder 是代码模型,其强项在于生成程序。PAL 方法的核心思路是:让模型针对数学题生成一段 Python 代码(通常封装为solution()函数),由真实的 Python 解释器执行这段代码得到答案,从而把算术、代数符号运算等繁重计算外包给解释器,模型只需负责正确建模题意与书写逻辑。

本仓库为此提供了完整可复现的测试脚本,覆盖GSM8k、MATH、GSM-Hard、SVAMP、TabMWP、ASDiv、MAWPS七个数据集,测试目标是验证 deepseek-coder 系列模型在"程序辅助数学推理"场景下的表现。README 中给出的官方基准(见文末表格)表明,DeepSeek-Coder-Base 33B 在该评测口径下取得了七数据集平均 65.8% 的最好成绩,且随着模型规模增大(1.3B → 6.7B → 33B)准确率稳定提升。

2. 仓库结构速览

评估代码位于 Evaluation/PAL-Math,主要组成如下:

路径作用
run.py主入口脚本,包含数据加载、推理、判分三个阶段
prompts/gsm8k.mdGSM8k 等六个数据集使用的 few-shot 提示模板
prompts/math.mdMATH 数据集使用的 few-shot 提示模板(含 LaTeX/sympy 风格)
datasets/七个数据集的test.json测试文件
utils/parser.py数据解析、答案归一化与代码块提取
utils/grader.py预测答案与标准答案的数学等价性判分
utils/python_executor.py基于 pebble 进程池的 Python 程序执行器

七个数据集的测试集规模(以test.json行数计)为:GSM8k 1319 条、GSM-Hard 1319 条、MATH 5000 条、SVAMP 1000 条、TabMWP 1000 条、ASDiv 2215 条、MAWPS 2065 条。

3. 环境搭建

评估依赖sympy(符号计算)、pebble(进程池执行)、timeout-decorator(执行超时控制)与transformers(模型加载与生成)。安装命令:

pip install sympy==1.12 pebble timeout-decorator transformers

其中sympy承担两类关键工作:一是 MATH 数据集提示中要求模型使用sympy.simplify等符号化简;二是判分阶段 grader.py 用parse_latex/parse_expr将字符串解析为符号表达式做等价性判断,因此版本被固定为 1.12。此外 python_executor.py 还用到regex、multiprocess、dateutil.relativedelta等传递依赖。

4. 运行评估:8 卡并行推理 + 离线判分

4.1 完整命令流程

README 给出了以deepseek-coder-1.3b-base在gsm8k数据集、8 块 GPU上运行的完整示例。推理阶段按rank把测试集切分到各 GPU 上并行生成,全部完成后统一执行判分:

MODEL_NAME_OR_PATH=deepseek-ai/deepseek-coder-1.3b-base DATA=gsm8k # 'math' 'gsm8k' 'gsm-hard' 'svamp' 'tabmwp' 'asdiv' 'mawps' MODEL_DIR_NAME=${MODEL_NAME_OR_PATH##*/} GPU_NUM=8 for rank in {0..7}; do CUDA_VISIBLE_DEVICES=$rank nohup python run.py \ --data_name ${DATA} \ --model_name_or_path ${MODEL_NAME_OR_PATH} \ --batch_size 16 \ --do_inference \ --rank $rank \ --world_size $GPU_NUM 2>&1 & done # Wait for all processes to finish wait echo "All processes completed." python run.py --do_eval --data_name ${DATA} --model_name_or_path ${MODEL_NAME_OR_PATH} --world_size $GPU_NUM | tee outputs/${MODEL_DIR_NAME}/${DATA}/result.out

脚本中的wait确保 8 个推理进程全部结束后才进入判分阶段(每个run.py推理进程会把结果写入独立文件outputs/<模型名>/<数据集>/world_size_8_rank_<rank>.json)。判分进程按world_size遍历合并所有 rank 的结果文件后计算平均准确率,结果同时写入outputs/<模型名>/<数据集>/result.out便于留档。更换模型或数据集只需修改MODEL_NAME_OR_PATH与DATA两个变量。

4.2 命令行参数一览

run.py 通过argparse定义了如下参数:

参数默认值说明
--data_namemath数据集名,可选math/gsm8k/gsm-hard/svamp/tabmwp/asdiv/mawps
--model_name_or_pathdeepseek/deepseek-coder-1b-python模型名称或本地路径
--batch_size16每批送入生成的样本数
--max_context_length2048输入上下文最大长度,超长则截断为最后 2048 token
--max_output_length512生成的最大新 token 数
--do_inference关闭是否执行推理阶段
--do_eval关闭是否执行判分阶段(与--do_inference互斥分支)
--rank0当前进程的 GPU 编号,用于数据分片
--world_size1参与推理的 GPU 总数

README 同时声明了统一评测口径:最大输入长度 2048、最大输出长度 512、贪心搜索(greedy)策略。这在 run.py 中对应GenerationConfig(num_beams=1)与do_sample=False,即 beam size 为 1、不做采样,保证结果可复现。

5. 源码级原理剖析

5.1 数据加载与提示构造

load_data(run.py)按data_name选择提示模板:非math数据集统一使用 prompts/gsm8k.md,math数据集使用 prompts/math.md。随后逐行读取datasets/<data_name>/test.json,调用 parser.py 的parse_ground_truth按数据集格式解析标准答案(例如 GSM8k 从answer字段按####切分推理链与答案、MATH 从solution中提取\boxed{...}结果、SVAMP 取Answer字段、TabMWP 对带单位/百分比的答案做数值归一化),再调用parse_question重组题干(如 ASDiv 拼接body与question,TabMWP 把表格与选项并入提示)。最终每条样本构造成:

{prompt模板} Question: {question}

5.2 推理与代码块提取

推理阶段(run.py)先按i % world_size == rank对测试集分片,随后加载模型:tokenizer 使用padding_side="left"并强制pad_token_id=0;模型以torch.float16+device_map="auto"加载。生成时传入停用词Question与----------------(将它们编码为 eos token,防止模型在 few-shot 风格下继续生成下一个示例)。停止条件还包括max_output_length。

生成结束后,通过 run.py 的正则python\n(.*?)def solution\(\):\n(.*?)从响应中提取含solution()的完整 Python 代码块,随后交给 Python 执行器运行。

5.3 程序执行:隔离进程 + 超时保护

python_executor.py 实现了安全的程序执行器:

  • GenericRuntime.exec_code会拒绝包含input(或os.system(的代码,防止交互阻塞与系统调用;
  • PythonExecutor.execute支持三种取答案方式:get_answer_from_stdout(捕获 stdout 最后一行)、answer_symbol(读全局变量)、answer_expr(求值表达式)。本评测使用PythonExecutor(get_answer_expr='solution()'),即执行代码后求值solution();
  • 执行结果还会经过str()转字符串与pickle.dumps序列化检查,确保可回传;
  • batch_apply通过pebble的ProcessPool以进程池并行执行整批代码,每个样本默认timeout_length=5秒,超时返回空结果并记为Timeout Error,避免个别死循环拖垮整个评测。

5.4 判分:数值等价 + 符号等价

判分阶段(run.py)合并各 rank 结果后,对每个样本调用math_equal(gt, pred)统计平均分。结果先经strip_string归一化(parser.py)——统一\frac、\sqrt写法,去除\left/\right、单位文本、百分号、千分位逗号与小数尾零等干扰。

grader.py 的math_equal采用两级判断:

  1. 数值等价:若预测值与参考答案都能转成浮点数,则按isclose(rel_tol=1e-4)比较,且支持百分比(reference/100、reference、reference*100三者其一命中即通过);
  2. 符号等价:若为表达式,先用parse_latex/parse_expr解析为 sympy 表达式,判断simplify(a-b)==0或数值逼近N(a)与N(b)在rel_tol=1e-3内一致;列表/元组形式则逐元素递归比较。

math_equal还提供timeout=True模式,通过multiprocessing.Process子进程 1 秒超时兜底,防止 sympy 在复杂符号化简上卡死。

6. Prompt 设计:两种 few-shot 风格

GSM8k 风格模板(prompts/gsm8k.md)用于算术类数据集,示例把每个变量显式命名(如money_initial、golf_balls_left),逐步计算后return result,模型只需照此风格输出代码,无需输出中间推理文本:

def solution(): """Olivia has $23. She bought five bagels for $3 each. How much money does she have left?""" money_initial = 23 bagels = 5 bagel_cost = 3 money_spent = bagels * bagel_cost money_left = money_initial - money_spent result = money_left return result

MATH 风格模板(prompts/math.md)面向高等数学(代数、几何、概率、向量等),指示"Display the final result in LaTeX",因此示例大量使用sympy做符号化简、math.pi做数值计算,并用r'\begin{pmatrix} ... \end{pmatrix}'这类 LaTeX 格式返回向量结果。例如求多项式系数:

from sympy import symbols, simplify def solution(): x = symbols('x') expr = 3*(x**2 - x**3 + x) + 3*(x + 2*x**3 - 3*x**2 + 3*x**5 + x**3) - 5*(1 + x - 4*x**3 - x**2) simplified_expr = simplify(expr) x3_coefficient = simplified_expr.as_coefficients_dict()[x**3] result = x3_coefficient return result

两种模板的共同点是统一要求输出def solution():函数并return最终结果,这正是 run.py 正则提取与get_answer_expr='solution()'执行方式的约定基础。

7. 实验结果:七数据集官方基准

下表为 README 在统一评测口径(输入 2048 / 输出 512 / 贪心搜索、相同 prompt)下报告的七数据集准确率。所有开源对比模型均使用本仓库脚本评测,DeepSeek-Coder 33B 在全部七个数据集上取得最优成绩:

ModelSizeGSM8kMATHGSM-HardSVAMPTabMWPASDivMAWPSAvg
CodeShell7B15.8%8.6%17.3%35.5%28.2%44.4%59.8%29.9%
CodeGeex-27B22.2%9.7%23.6%39.0%44.6%48.5%66.0%36.2%
StarCoder-Base16B23.4%10.3%23.0%42.4%45.0%54.9%81.1%40.0%
CodeLLama-Base7B31.2%12.1%30.2%54.2%52.9%59.6%82.6%46.1%
CodeLLama-Base13B43.1%14.4%40.2%59.2%60.3%63.6%85.3%52.3%
CodeLLama-Base34B58.2%21.2%51.8%70.3%69.8%70.7%91.8%62.0%
DeepSeek-Coder-Base1.3B14.6%16.8%14.5%36.7%30.0%48.2%62.3%31.9%
DeepSeek-Coder-MQA-Base5.7B38.8%20.0%36.8%52.5%55.9%63.9%84.8%50.4%
DeepSeek-Coder-Base6.7B43.2%19.2%40.3%58.4%67.9%67.2%87.0%54.7%
DeepSeek-Coder-Base33B60.7%29.1%54.1%71.6%75.3%76.7%93.3%65.8%

从结果可以看出两个关键趋势:一是代码模型规模越大,程序辅助推理能力越强,DeepSeek-Coder 从 1.3B 到 33B 的平均分由 31.9% 提升至 65.8%;二是 DeepSeek-Coder 在 MATH 这种依赖符号计算与 LaTeX 输出的高阶数据集上优势尤为明显(33B 达 29.1%,超过同为 33B 级别的 CodeLLama-Base 的 21.2% 约 8 个百分点),验证了代码训练数据对符号操作类任务的迁移价值。该基准亦作为 Program-Aid Math Reasoning Benchmark 收录于仓库根目录 README.md 的详细评测结果章节。

8. 结语与复现要点

总结本评测方案的可复现要点:先按数据集选择对应 few-shot 模板并组装提示,再以贪心搜索限制输入/输出长度生成solution()代码,经隔离进程池执行取回结果,最后由math_equal以数值 + 符号双重等价标准判分。若想验证其他模型或数据集,仅需修改MODEL_NAME_OR_PATH与DATA并保持--world_size与 GPU 数量一致即可;判分阶段会自动按world_size合并所有 rank 的分片结果,无需手工拼接。

  • 人工智能
  • 大模型
  • 代码模型
  • 预训练
  • 微调
  • 模型评测
  • DeepSeek

【免费下载链接】DeepSeek-Coder

DeepSeek Coder: Let the Code Write Itself

项目地址:https://gitcode.com/GitHub_Trending/de/DeepSeek-Coder
点击查看免费下载

相关推荐

上一篇:E2B集群部署方案:大规模AI Agent系统架构设计
下一篇:Mermaid Live Editor 新手攻略:3分钟搞定专业图表,零代码也能玩转流程图

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询