KTransformers 精度基准测试指南:基于 DeepSeek-V3 的 MMLU/MMLU-pro 复现方法与结果解析
【免费下载链接】ktransformersA Flexible Framework for Experiencing Heterogeneous LLM Inference/Fine-tune Optimizations项目地址: https://gitcode.com/GitHub_Trending/ktr/ktransformers
导读
本文基于 KTransformers 项目官方基准测试文档(doc/en/benchmark.md),完整讲解项目团队用于校验异构推理精度的 MMLU / MMLU-pro 快速评测方案:从数据集准备、评测提示词、API 评测脚本,到 bf16 / q8_0 / q4km / iq1 / fp8 等多种 CPU 与 GPU 权重格式、cpuinfer/marlin/fp8gemm等 Kernel 组合下的精度结果与逐用例复现步骤。读完本文,你将能够在本地复现 KTransformers 的精度验证流程,并理解如何通过修改优化规则 YAML 与源码来切换 GEMM Kernel、MLA Kernel,从而评估不同异构优化配置对推理精度的影响。
一、评测背景:为什么需要一套"快速精度检查"流程
KTransformers 是一个用于体验异构 LLM 推理 / 微调优化的灵活框架,其核心思路是在 CPU 与 GPU 之间按算子类型灵活分配计算(典型如将 MoE 专家权重放在 CPU、Attention 与 GEMM 放在 GPU)。由于同一模型可能以多种量化格式(bf16、q8_0、q4km、iq1、fp8 等)加载,并由不同 Kernel 执行(CPU 侧cpuinfer、GPU 侧marlin/fp8gemm,MLA 侧triton/torch),量化与 Kernel 选择必然引入精度差异。
为了快速、方便地评估精度,项目采用一个简单的 Python 脚本(仓库内 mmlu_test.py),在固定数据集上对比 KTransformers 与云端服务平台的推理结果,从而对项目精度做出初步评估。官方明确说明这是一项初步判断(preliminary assessment),不是对模型的完整学术评测。
二、测试设置:数据集、模型与提示词
2.1 数据集与取样方式
评测使用MMLU数据集,取样策略如下:
- 选取全部子数据集,并使用固定随机种子(脚本中为
random.seed(42))进行 shuffle,保证每次测试的数据顺序一致; - 跳过 few-shot 部分,仅取前1,000 条数据做快速检查。
重要说明:由于跳过了 few-shot 且只测 1,000 条,结果可能与 DeepSeek-V3 官方技术报告不完全一致;1,000 条样本只提供初步判断,存在合理波动。R1 的测试及更多测试当时仍在进行中(文档记录时的状态)。
2.2 模型与权重格式
评测以DeepSeek-V3为主(部分用例为 DeepSeek-R1),覆盖以下权重格式组合:
| 角色 | 格式 |
|---|---|
| CPU 侧权重 | bf16、q8_0、q4km、iq1 |
| GPU 侧权重 | bf16、q4km→marlin(4bit/8bit)、fp8 |
| 对应 Kernel | CPUcpuinfer;GPUtorch/marlin/fp8gemm;MLAtorch/triton |
文档同时给出权重获取线索:bf16 模型可从公开渠道获取后用 llama.cpp 转为 GGUF;q4km 对应 DeepSeek-V3-Q4_K_M 系列 GGUF;q8_0 对应 DeepSeek-V3-Q8_0 系列 GGUF(均不在此给出外部链接,请以原文档为准)。
2.3 评测提示词与参数
为保证各 Kernel / 格式间可比,统一使用如下单轮问答提示词(无 few-shot):
There is a single choice question. Answer the question by replying A, B, C, D. No other answers are accepted. Just the letter. Question: {question} A. {option_a} B. {option_b} C. {option_c} D. {option_d} Answer: '采样参数设定temperature=0.6。这一提示词与参数均可在评测脚本 mmlu_test.py 中找到对应实现。
2.4 基线对照
为验证 KTransformers 的结果,文档选择了 Siliconflow 云服务平台作为基线(baseline),所有测试使用同一脚本、同一数据集运行,从而对项目精度做初步评估。基线分数(Siliconflow)与 KTransformers 得分(Ktrans Point)并列展示在结果表中。
三、评测脚本实现解析
评测脚本 mmlu_test.py 的核心逻辑可以分为四个环节,理解它有助于你复现或改造评测:
- 数据加载(
DataEvaluator.load_data):通过pd.read_parquet读取cais/mmlu数据集的 test 分片,将每条记录转为字典存入列表; - 提示词构造(
get_prompt):将记录中的 question 与 choices 拼接成 2.3 节所示的模板;MMLU-pro 版本见 mmlu_pro_test.py; - 推理调用(
generate_text):向 OpenAI 兼容的/v1/chat/completions接口发起 POST 请求。默认api_url为http://localhost:10003/v1/chat/completions(即本地 KTransformers 服务地址),可通过--api_url参数切换; - 后处理与打分(
post_processing/score):取回复最后一个字符作为预测答案,与标准答案(chr(answer + 65))比对,命中计 1 分,否则 0 分。
脚本同时输出每个问题的 JSON 结果文件与日志文件(总耗时、吞吐量、平均分),并支持通过--concurrent控制评测条目数(默认 1000)。实测时可通过--api_url分别指向本地 KTransformers 服务与基线云服务,用同一份数据完成对比。
四、完整结果表(文档记录)
以下为文档记录的结果。表中"CPU Weight Format / CPU Kernel"描述 CPU 侧加载权重格式与执行 Kernel;"GPU Weight Format / GEMM Kernel / MLA Kernel"描述 GPU 侧情况;Siliconflow 列与 Ktrans Point 列分别对应基线得分与 KTransformers 得分。
4.1 MMLU(shuffle 1k,temperature=0.6)
| # | 模型 | CPU Weight Format | CPU Kernel | GPU Weight Format | GEMM Kernel | MLA Kernel | Siliconflow | Ktrans Point |
|---|---|---|---|---|---|---|---|---|
| 1 | DeepSeek-V3 | bf16 | cpuinfer | bf16 | torch | torch | 81.6 | 81.9 |
| 2 | DeepSeek-V3 | q8_0 | cpuinfer | bf16 | torch | torch | 81.6 | 83.1 |
| 3 | DeepSeek-V3 | q4km | cpuinfer | bf16 | torch | triton | 81.6 | 81.4 |
| 4 | DeepSeek-V3 | q4km | cpuinfer | q4km→marlin 8 | marlin | triton | 81.6 | 81.1 |
| 5 | DeepSeek-V3 | q4km | cpuinfer | q4km→marlin 4 | marlin | triton | 81.6 | 81.0 |
| 6 | DeepSeek-V3 | q4km | cpuinfer | fp8 | fp8gemm | triton | 81.6 | 81.5 |
| 7 | DeepSeek-R1 | iq1 | cpuinfer | fp8 | fp8gemm | triton | 78.6 | 83.6 |
4.2 MMLU-pro(shuffle 1k,temperature=0.6)
| # | 模型 | CPU Weight Format | CPU Kernel | GPU Weight Format | GEMM Kernel | MLA Kernel | Siliconflow | Ktrans Point |
|---|---|---|---|---|---|---|---|---|
| 1 | DeepSeek-V3 | q4km | cpuinfer | fp8 | fp8gemm | triton | 57.7 | 57.6 |
| 2 | DeepSeek-V3 | q4km | cpuinfer | q4km→marlin 4 | marlin | triton | 57.7 | 57.5 |
| 3 | DeepSeek-R1 | iq1 | cpuinfer | fp8 | fp8gemm | triton | 71.9 | tbd |
4.3 待补测项
HumanEval 与 GSM8K 两个基准当时标记为 tbd(待测试),KTransformers 侧得分同样待补充。
读表提示:文档特别提醒,由于仅测 1,000 条且为快速检查,结果波动属正常现象;同一数据集、固定种子保证可比性。从表内数据可看到,不同量化与 Kernel 组合下 KTransformers 得分与基线大致相当(部分组合甚至更高),可作为配置选型的参考,但不应据此得出"超越基线"的绝对结论。
五、逐用例复现细节
文档对每个用例给出了具体的复现操作,全部围绕优化规则文件 DeepSeek-V3-Chat.yaml 展开。
5.1 MMLU 用例
- Case 1(CPU bf16 / GPU bf16 / torch / torch):使用 v3-chat YAML,将其中所有
KLinearMarlin替换为KLinearTorch(在该文件中查找全部出现处逐一替换)。源权重为 DeepSeek-V3-bf16,需用 llama.cpp 转为 GGUF。 - Case 2(CPU q8_0 / GPU bf16 / torch / torch):同样使用 v3-chat YAML,但需修改代码以单独加载 CPU 侧专家权重。文档在 experts.py 中留下了注释标记点(约 L122、L136、L137 三处;其中 L137 处需改为本地权重文件路径)。q8_0 权重文件对应 DeepSeek-V3-Q8_0 系列 GGUF。
- Case 3(CPU q4km / GPU bf16 / triton):操作同 Case 2(同样需改 experts.py 加载 CPU 专家权重),q4km 权重文件对应 DeepSeek-V3-Q4_K_M 系列 GGUF。
- Case 4(CPU q4km / GPU q4km→marlin 8):无需修改源码(两侧均用 q4km)。但需注意 YAML 文件中的两处位置(约 L29 与 L18,即所有使用
KLinearMarlin的规则下方),为每条KLinearMarlin规则添加num_bits: 8参数(即把该 kwargs 加到所有使用KLinearMarlin的配置中)。 - Case 5(CPU q4km / GPU q4km→marlin 4):不需要修改 YAML,直接使用默认配置即可。权重文件同样为 DeepSeek-V3-Q4_K_M。
- Case 6(GPU fp8 / fp8gemm):这是混合张量(mixture tensor)用例,需参考 fp8_kernel.md 学习如何测试。
- Case 7(DeepSeek-R1,CPU iq1 / GPU fp8):同样为混合张量用例,参考 fp8_kernel.md。
5.2 MMLU-pro 用例
- Case 1(CPU q4km / GPU fp8 / fp8gemm):混合张量用例,参考 fp8_kernel.md。
- Case 2(CPU q4km / GPU q4km→marlin 4):无需修改 YAML,使用默认配置,权重为 DeepSeek-V3-Q4_K_M。
- Case 3(DeepSeek-R1,CPU iq1 / GPU fp8):混合张量用例,参考 fp8_kernel.md。
5.3 优化规则文件中的关键配置
DeepSeek-V3-Chat.yaml 定义了默认的异构注入策略,理解它可以解释上述用例为何要改 YAML:
- lm_head 与除 kv_b_proj 外的 Linear:替换为
KTransformersLinear,generate_op用KLinearMarlin、prefill_op用KLinearTorch(Case 1 即把KLinearMarlin全部改成KLinearTorch以实现纯 torch GEMM); - MoE 模块:
DeepseekV3MoE替换为KDeepseekV3MoE,其中mlp.experts的generate_op为KExpertsCPU(生成阶段专家走 CPU)、prefill_op为KExpertsTorch、out_device为cuda,这正是"CPU 加载专家权重"的来源,也是 Case 2/3 需要单独加载 CPU 专家权重的原理; - Attention:替换为
KDeepseekV2Attention(优化的 MLA 实现),absorb_for_prefill默认 False(改为 True 可支持长上下文,但 prefill 可能变慢); - MoE Gate:替换为
KMoEGate,运行在cuda:0。
六、Kernel 切换方法
6.1 切换 GEMM Kernel(Marlin ↔ Torch)
GEMM Kernel 由优化规则 YAML 中的generate_op/prefill_op控制:
- 默认:
KLinearMarlin(GPU 量化 GEMM); - 切换为纯 torch:将
KLinearMarlin改为KLinearTorch(对应 DeepSeek-V3-Chat.yaml 中所有使用处)。
6.2 切换 MLA Kernel(Triton ↔ Torch)
默认行为:Linux 上 MLA Kernel 使用 Triton,Windows 上使用 Torch。若需在 Linux 上强制使用 Torch(例如 Case 1/2 需要 torch MLA),文档给出的做法是手动修改 attention.py:删除forward中所有 if 分支判断,强制调用self.forward_windows方法(该方法对应 Windows 的 torch 实现,位于 attention.py 附近,而 Linux Triton 实现在forward_linux_triton,约 L196)。
从源码结构看,KDeepseekV2Attention.forward(约 L685)内部按平台/条件在forward_linux_triton、forward_linux_flashinfer、forward_windows、forward_xpu等实现间分派,因此修改分派逻辑即可完成 Kernel 切换。
七、环境注意事项:g++/as 版本与开发容器
进行 bf16 测试(无论是 CPU Weight 还是 GPU Weight)时,Ubuntu 20 或更早版本可能因系统自带的 g++ 与 as(汇编器)版本过旧而遇到编译问题。为便于复现结果,项目提供了预配置的开发容器:
- 容器内已预装适配 bf16 构建的环境,但未安装 ktrans 包,仍需手动安装若干依赖包;
- 模型挂载目录可在
devcontainer/devcontainer.json中配置(文档提到检查其中的"mouts"配置项——注意这是原文档的笔误,实际对应 devcontainer 的 mounts/挂载配置)。
八、限制与适用范围
最后重申本文所述评测方法的边界,避免误用:
- 非完整评测:跳过 few-shot、仅 1,000 条样本、
temperature=0.6,结果不宜与 DeepSeek-V3 技术报告直接对比; - 初步结论:文档明确定位为快速检查与初步精度评估,HumanEval / GSM8K 等基准仍待补测;
- 波动合理:1,000 条样本下分数存在合理波动;
- 环境依赖:复现 bf16 用例需注意 g++/as 版本,建议使用提供的开发容器环境。
如需进一步深入,可继续阅读仓库内的 fp8_kernel.md(混合张量 / fp8 用例)、mmlu_pro_test.py(MMLU-pro 脚本)以及 DeepSeek-V3-Chat.yaml(优化规则全文)。
【免费下载链接】ktransformersA Flexible Framework for Experiencing Heterogeneous LLM Inference/Fine-tune Optimizations项目地址: https://gitcode.com/GitHub_Trending/ktr/ktransformers
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考