Ktransformers 文档
基本信息
转载自:Ktransformers
防止丢失、学习记录备忘。
中译为本站翻译,内容同步于 2026-11-10,对应官方文档最新版(v0.7.x)。
简介

一个能上手玩前沿 LLM 推理与微调优化的灵活框架
🎯 概览 | 🚀 推理 | 🎓 微调 | 🔥 引用 | 🚀 路线图(2026Q2)
🎯 概览
KTransformers 是个研究性质的项目,靠 CPU 和 GPU 一起干活,把大模型的推理和微调都做得更快、更省资源。现在它把 kt-kernel 代码树里的两样东西单独拿出来给用户用:推理(Inference) 和 微调(SFT)。
🔥 更新记录
- 2026 年 10 月 15 日:DeepSeek-V4-Flash LoRA 微调支持原生 MXFP4 路由专家。快速开始。
- 2026 年 10 月 8 日:发布 KTransformers-FineTune (KT-FT) 作者预印本,提出面向 MoE 微调的布局感知、调度优化的 CPU-GPU 协同计算方案。论文与引用 · PDF。
- 2026 年 9 月 13 日:Kimi K2.5 / K2.6 LoRA 微调支持原生 RAWINT4 路由专家。
- 2026 年 8 月 26 日:原生支持 GLM-5.3-flash,把 100 万 token 上下文与多模态输入带到消费级 GPU。(教程)
- 2026 年 8 月 25 日:新增一份易用的 KTransformers × LlamaFactory MoE 微调 Cookbook,覆盖硬件检查、安装、BF16/FP8/INT8 配方、LoRA 与全量微调、资源规划以及故障排查。
- 2026 年 8 月 17 日:LoRA 微调现已支持兼容的 AVX512 x86 CPU(包括 AMD 服务器),无需 AMX。(v0.7.0 发布说明)
- 2026 年 8 月 16 日:在单张昇腾 NPU 上通过 CPU 专家卸载运行 DeepSeek-V4-Flash。(教程)
- 2026 年 8 月 5 日:引入原生 block-FP8 LoRA 微调(PR #2141)
- 2026 年 7 月 23 日:新增 MoE 模型的端到端 BF16 全参数微调,支持完整 checkpoint 保存。(PR #2094)
- 2026 年 6 月 21 日:MiniMax-M3 Day0 支持!(教程)
- 2026 年 6 月 17 日:GLM-5.2 Day0 支持!(教程)
- 2026 年 5 月 6 日:KTransformers 亮相 GOSIM Paris 2026 的”Agentic AI on Edge”分论坛,将分享 KT 在消费级硬件上的推理性能。
- 2026 年 5 月 2 日:DeepSeek-V4-Flash 支持!(教程)
- 2026 年 4 月 30 日:KTransformers v0.6.1 更新 kt-kernel 推理与 SFT 文档,拆分为 推理 与 SFT 快速开始 两个入口。
- 2026 年 3 月 26 日:KT-Kernel 推理支持仅 AVX2 的 CPU 后端。(教程)
- 2026 年 2 月 13 日:MiniMax-M2.5 Day0 支持!(教程)
- 2026 年 2 月 12 日:GLM-5 Day0 支持!(教程)
- 2026 年 1 月 27 日:Kimi-K2.5 Day0 支持!(教程)(SFT 教程)
- 2026 年 1 月 22 日:支持 CPU-GPU 专家调度、原生 BF16 与 FP8 per-channel 精度 以及 AutoDL 训推一体化
- 2025 年 12 月 24 日:支持原生 MiniMax-M2.1 推理。(教程)
- 2025 年 12 月 22 日:支持使用 LLaMA-Factory 进行 RL-DPO 微调。(教程)
- 2025 年 12 月 5 日:支持原生 Kimi-K2-Thinking 推理(教程)
- 2025 年 11 月 6 日:支持 Kimi-K2-Thinking 推理(教程)与微调(教程)
- 2025 年 11 月 4 日:KTransformers 微调 × LLaMA-Factory 集成。(教程)
- 2025 年 10 月 27 日:支持昇腾 NPU。(教程)
- 2025 年 10 月 10 日:集成进 SGLang。(路线图,博客)
- 2025 年 9 月 11 日:支持 Qwen3-Next。(教程)
- 2025 年 9 月 5 日:支持 Kimi-K2-0905。(教程)
- 2025 年 7 月 26 日:支持 SmallThinker 与 GLM4-MoE。(教程)
- 2025 年 7 月 11 日:支持 Kimi-K2。(教程)
- 2025 年 6 月 30 日:支持三层(GPU-CPU-磁盘)prefix cache 复用。
- 2025 年 5 月 14 日:支持 Intel Arc GPU(教程)。
- 2025 年 4 月 29 日:支持 AMX-Int8、AMX-BF16 与 Qwen3MoE(教程)
- 2025 年 4 月 9 日:实验性支持 LLaMA 4 模型(教程)。
- 2025 年 4 月 2 日:支持多并发。(教程)。
- 2025 年 3 月 15 日:支持 AMD GPU 上的 ROCm(教程)。
- 2025 年 3 月 5 日:支持 unsloth 1.58/2.51 bits 权重以及 IQ1_S/FP8 混合权重。在 24GB 显存下支持 DeepSeek-V3 与 R1 的 139K 长上下文。
- 2025 年 2 月 25 日:为 DeepSeek-V3 与 R1 支持 FP8 GPU kernel;更长上下文。
- 2025 年 2 月 15 日:更长上下文(24GB 显存下从 4K 提升到 8K)与略快的速度(+15%,最高 16 tokens/s),更新文档与在线书。
- 2025 年 2 月 10 日:支持在单卡(24GB 显存)/多卡加 382G DRAM 上运行 Deepseek-R1 与 V3,最高 3~28 倍加速。详细的演示与复现教程见此处。
- 2024 年 8 月 28 日:将 DeepseekV2 所需显存从 21G 降至 11G。
- 2024 年 8 月 15 日:更新注入与多 GPU 的详细教程。
- 2024 年 8 月 14 日:支持 llamfile 作为 linear 后端。
- 2024 年 8 月 12 日:支持多 GPU;支持新模型 mixtral 8*7B 和 8*22B;支持 GPU 上的 q2k、q3k、q5k 反量化。
- 2024 年 8 月 9 日:支持 Windows 原生环境。
📦 能力概览
🚀 推理 - 高性能 kt-kernel 服务
这是一组针对 CPU 优化的 kernel 运算,专门服务于 CPU/GPU 混合的 LLM 推理。

核心特性:
- AMX/AVX 加速:针对 INT4/INT8 量化推理的 Intel AMX 与 AVX512/AVX2 优化 kernel
- MoE 优化:结合 NUMA 感知内存管理的高效混合专家推理
- 量化支持:CPU 侧 INT4/INT8 量化权重,GPU 侧支持 GPTQ
- 易于集成:为 SGLang 等框架提供简洁的 Python API
快速开始:
1 | cd kt-kernel |
适用场景:
- 大 MoE 模型的 CPU-GPU 混合推理
- 与 SGLang 集成用于生产环境服务
- 异构专家放置(热专家放 GPU,冷专家放 CPU)
性能示例:
| 模型 | 硬件配置 | 总吞吐 | 输出吞吐 |
|---|---|---|---|
| DeepSeek-R1-0528 (FP8) | 8×L20 GPU + Xeon Gold 6454S | 227.85 tokens/s | 87.58 tokens/s(8 路并发) |
👉 完整文档 →
🎓 微调 - 使用 LlamaFactory 做微调
论文: KTransformers-FineTune (KT-FT) · PDF。
KTransformers 和 LlamaFactory 已经打通,可以用来微调超大规模 MoE 模型。新写的 Cookbook 是一条照着做就行的路径:从检查硬件、装环境,到 BF16/FP8/INT8 各种配法,再到 LoRA 与全量训练、资源规划、出问题怎么排查,全都覆盖。
Kimi K2.5 / K2.6 LoRA 微调支持原生 RAWINT4 路由专家。参见 PyPI 安装、训练、断点续训与 SGLang 服务指南(中文)。端到端验证使用 Kimi K2.5,K2.6 沿用相同的模型架构路径。

核心特性:
- 多后端支持:INT8/INT4 量化的 CPU/GPU 混合微调
- 超大规模 MoE 支持:在有限显存下微调 DeepSeek-V3/R1 等模型
- 快于 ZeRO-Offload:在基准测试的 MoE SFT 负载中训练提速 6-12 倍
- 更低的 CPU 内存:在基准配置下约为此前 KT SFT 路径的一半 CPU 内存
- LlamaFactory 集成:与该流行微调框架无缝集成
| 模型 | 显存 | 训练速度 | 硬件 |
|---|---|---|---|
| DeepSeek-V3 | 约 80GB 总计 | 3.7 it/s | 4x RTX 4090 |
| DeepSeek-R1 | 约 80GB 总计 | 3.7 it/s | 4x RTX 4090 |
| Qwen3-30B-A3B | 约 24GB 总计 | 8+ it/s | 1x RTX 4090 |
快速开始:
1 | cd /path/to/LLaMA-Factory |
👉 易用的微调 Cookbook → 👉 快速开始 → 👉 完整文档 →
🔥 引用
如果你的研究用到了 KTransformers,麻烦顺手引一下对应的论文。
推理论文
1 | @inproceedings{10.1145/3731569.3764843, |
微调论文
KTransformers-FineTune (KT-FT) · 完整 BibTeX
1 | @misc{li2026ktft, |
👥 贡献者与团队
由以下团队开发与维护:
- MADSys Lab @ 清华大学
- Approaching.AI
- 9#AISoft
- 社区贡献者
欢迎一起贡献:发现问题可以提 issue,有改动可以直接提 pull request。
💬 社区与支持
- GitHub Issues:反馈 bug 或提出需求
- 微信群:见 archive/WeChatGroup.png
📦 KT 原始代码
原来那套一体化的 KTransformers 框架已经挪到 archive/ 目录存档备查。现在项目以 kt-kernel 源码树为基准,把上面这两项能力分开组织,文档看得更清楚,维护也省事一些。
想看带完整快速开始和示例的原始文档,可以看这几份:
- archive/README.md(英文)
- archive/README_ZH.md(中文)
KT-Kernel
KT-Kernel 是 KTransformers 的高性能 kernel 层,用 AMX、AVX、KML 以及 blis(AMD 的库)在 CPU 上把 MoE 推理跑快。
- 说明
- 特性
- 安装
- 方式 1:从 PyPI 安装(推荐大多数用户)
- 方式 2:从源码安装(本地使用或自定义构建)
- 验证
- KT CLI 概览
- 与 SGLang 集成
- 安装步骤
- 完整示例:Qwen3-30B-A3B
- KT-Kernel 参数
- 直接使用 Python API
- 高级选项
- 手动配置(进阶)
- 构建配置
- 手动安装(不使用 install.sh)
- 错误排查
- 找不到 CUDA
- 找不到 hwloc
- 权重量化
- 提交代码之前!
说明
当前支持状态:
- ✅ AVX512/AMX 原生精度:在支持
FP8、BF16与RAWINT4格式的 AVX512 CPU 上可用 - 指南 - ✅ 带 AMX 的 Intel CPU:完整支持(使用转换为 INT4/INT8 格式的权重)
- ✅ 通用 CPU(llamafile 后端):支持(使用 GGUF 格式权重)
- ✅ 带 BLIS 的 AMD CPU:支持(用于 int8 预填充与解码)- 指南
KT-CLI
我们还在做一个更省事的用法,细节见 KT-CLI 指南。
特性
- CPU 优化 MoE Kernel:针对指令集优化的高吞吐 MoE 专家 kernel。
- AVX512 原生精度后端:面向支持 AVX512 的服务器,提供 FP8 / BF16 / INT4 原生 MoE 后端。
- AMX INT4/INT8 后端:面向支持 AMX 的服务器,提供 INT4 / INT8 量化专家推理后端。
- Llamafile CPU 后端:基于 Llamafile 的 AVX2/AVX512 MoE 后端,用于通用 CPU 部署。
- NUMA 感知执行:为多路 / 多 NUMA 机器设计的线程池与内存布局。
安装
方式 1:从 PyPI 安装(推荐大多数用户)
一条命令就能装上最新版:
1 | pip install kt-kernel |
注意:查看 PyPI 上的最新版本
特性:
- ✅ 自动 CPU 检测:识别你的 CPU 并加载最优 kernel 变体
- ✅ CPU 多变体支持:内置 AMX、AVX512(Base/VNNI/VBMI/BF16)与 AVX2 变体
- ✅ 包含 CUDA 支持:为 NVIDIA GPU(SM 80、86、89、90)提供 GPU 加速
- ✅ 无需编译:为 Python 3.10、3.11、3.12 提供预编译 wheel
- ✅ 静态 CUDA 运行时:无需安装 CUDA toolkit
- ✅ 纯 CPU 系统可用:无 GPU 时自动禁用 CUDA 功能
环境要求:
- Python 3.10、3.11 或 3.12
- Linux x86-64(兼容 manylinux_2_17)
- 支持 AVX2 的 CPU(Intel Haswell 2013+、AMD Zen+)
- 可选:计算能力 8.0+ 的 NVIDIA GPU 以启用 CUDA 功能
CUDA 安装(GPU 加速)
想让 NVIDIA GPU 参与加速的话:
1 | pip install kt-kernel |
特性:
- ✅ 多架构支持:单个 wheel 支持 SM 80/86/89/90(Ampere、Ada、Hopper)
- ✅ 静态 CUDA 运行时:无需安装 CUDA toolkit
- ✅ 广泛兼容:兼容 CUDA 11.8+ 与 12.x 驱动
- ✅ PyTorch 兼容:可搭配任意 PyTorch CUDA 变体(cu118、cu121、cu124)
环境要求:
- Python 3.10、3.11 或 3.12
- Linux x86-64(兼容 manylinux_2_17)
- 计算能力 8.0+ 的 NVIDIA GPU(Ampere 或更新)
- ✅ 支持:A100、RTX 3000/4000 系列、H100
- ❌ 不支持:V100、P100、GTX 1000/2000 系列(过旧)
- 支持 CUDA 11.8+ 或 12.x 的 NVIDIA 驱动(无需 CUDA toolkit)
GPU 兼容性矩阵:
| GPU 架构 | 计算能力 | 是否支持 | 示例 GPU |
|---|---|---|---|
| Hopper | 9.0 | ✅ | H100, H200 |
| Ada Lovelace | 8.9 | ✅ | RTX 4090, 4080, 4070 |
| Ampere | 8.6 | ✅ | RTX 3090, 3080, 3070, 3060 |
| Ampere | 8.0 | ✅ | A100, A30 |
| Turing | 7.5 | ❌ | RTX 2080, T4 |
| Volta | 7.0 | ❌ | V100 |
CUDA 驱动兼容性(针对 GPU 功能):
- CUDA 11.8、11.9、12.0-12.6+:完整支持
- CUDA 11.0-11.7:不支持(请升级驱动或仅使用 CPU)
内置的 CPU 变体:
wheel 里打包了 6 个优化变体,运行时按你的 CPU 自动挑一个:
| 变体 | CPU 支持 | 性能 | 自动选择条件 |
|---|---|---|---|
| AMX | Intel Sapphire Rapids+(2023+) | ⚡⚡⚡ 最佳 | 检测到 AMX 指令 |
| AVX512+BF16 | Ice Lake 服务器、Zen 4+(2021+) | ⚡⚡⚡ 优秀 | 检测到 AVX512 + BF16 |
| AVX512+VBMI | Ice Lake 客户端(2019+) | ⚡⚡ 很好 | 检测到 AVX512 + VBMI |
| AVX512+VNNI | Cascade Lake+(2019+) | ⚡⚡ 很好 | 检测到 AVX512 + VNNI |
| AVX512 Base | Skylake-X+(2017+) | ⚡⚡ 良好 | 检测到 AVX512 base |
| AVX2 | Haswell+(2013+)、AMD Zen+ | ⚡ 可用 | 兜底以保证最大兼容性 |
验证安装:
1 | import kt_kernel |
环境变量:
1 | # 覆盖自动 CPU 检测(用于测试或调试) |
方式 2:从源码安装(本地使用或自定义构建)
需要本地安装,或者要用 AMD(BLIS)、ARM(KML)、自定义 CUDA 版本时,就走源码构建这条路。
前置条件
先把 git 子模块拉下来,再建一个 conda 环境:
1 | git submodule update --init --recursive |
快速安装(推荐)
直接跑安装脚本就行——它会自己认出你的 CPU,按最佳性能来编译:
1 | ./install.sh |
脚本会自动完成:
- 自动检测 CPU 能力(AMX、AVX512_VNNI、AVX512_BF16)
- 安装系统依赖(
cmake、libhwloc-dev、pkg-config) - 为你的 CPU 专门构建优化二进制(使用
-march=native) - 对不支持 VNNI/BF16 的 CPU 自动启用软件兜底
可选:分两步安装
1 | ./install.sh deps # 仅安装依赖 |
各后端的 CPU 要求:
| 后端 | 最低 CPU 要求 | 示例 CPU | 说明 |
|---|---|---|---|
| LLAMAFILE | AVX2 | Intel Haswell(2013+)、AMD Zen+ | 通用兼容性 |
| RAWINT4 | AVX512F + AVX512BW | Intel Skylake-X(2017+)、Ice Lake、Cascade Lake | 为 VNNI/BF16 提供软件兜底 |
| AMXINT4/INT8 | AMX | Intel Sapphire Rapids(2023+) | 最佳性能,需 AMX 硬件 |
| FP8 | AVX512F + AVX512BW + AVX512_BF16 + AVX512_VBMI | Intel Cooper Lake(2020+)、Sapphire Rapids(2023+);AMD Zen 4+(如 EPYC 9355) | 原生精度(如 DeepSeek V3.2、MiniMax M2.1) |
| BF16 | AVX512F + AVX512BW + AVX512_BF16 | Intel Cooper Lake(2020+)、Sapphire Rapids(2023+);AMD Zen 4+(如 EPYC 9355) | 原生精度(如 Qwen3-235B-A22B、GLM-4.7) |
软件兜底支持(AVX512 后端):
- ✅ VNNI 兜底:使用 AVX512BW 指令
- ✅ BF16 兜底:使用 AVX512F 指令
- ✅ 较老的 AVX512 CPU(Skylake-X、Cascade Lake)可通过兜底运行 RAWINT4
⚠️ 可移植性提醒: 默认构建只针对你这颗 CPU 优化,换台机器或换到更老的 CPU 上可能就跑不起来。要做可移植构建或二进制分发,看下文手动配置。
⚠️ 用 AMD BLIS 后端的话: AMD 平台的装法见这份指南。
验证
装完先确认 CLI 能用:
1 | kt version |
预期输出:
1 | KTransformers CLI v0.x.x |
也可以直接验证 Python 模块:
1 | python -c "from kt_kernel import KTMoEWrapper; print('✓ kt-kernel installed successfully')" |
KT CLI 概览
kt 命令行工具把「跑模型」和「管模型」的事都收到一个入口下:
| 命令 | 说明 |
|---|---|
kt run |
以自动优化参数启动模型推理服务 |
kt chat |
跟正在跑的模型服务聊天 |
kt model |
管理模型与存储路径 |
kt doctor |
诊断环境问题并检查系统兼容性 |
kt config |
管理 CLI 配置 |
kt version |
显示版本信息 |
快速开始示例:
1 | # 启动模型服务(自动检测硬件并应用最优设置) |
想看更多选项就跑 kt --help,想看某个命令的细节就跑 kt <command> --help。
与 SGLang 集成
KT-Kernel 可以单独用(直接调 Python API),也可以接进 SGLang 做生产部署。这一节讲怎么接 SGLang,从而开启 CPU-GPU 异构推理:「热」专家放在 GPU 上,「冷」专家放在 CPU 上,资源才用得最划算。
安装步骤
1. 安装 SGLang
装 kvcache-ai 维护的 SGLang 分支(kt-kernel 要靠它):
1 | # 方式 A:一键安装(在 ktransformers 根目录执行,安装 sglang + kt-kernel) |
重要:请使用
sglang-kt(kvcache-ai 分支),不要使用官方sglang包。如果已安装官方版本,请先卸载:pip uninstall sglang -y
2. 准备权重
异构推理得准备两份权重:GPU 权重和 CPU 侧的专家权重。用什么格式取决于后端:
GPU 权重(所有后端通用):
就是 SGLang 做 GPU 推理要用的那份模型权重(比如 Hugging Face 上的原始模型目录,或者已经量化好的目录)。
CPU 权重(AMX 后端:AMXINT4 / AMXINT8): 使用提供的脚本将权重转换为 AMX 优化的 INT4/INT8 格式:
1 | python scripts/convert_cpu_weights.py \ |
--input-path:GPU 侧原始权重路径--input-type:取决于你的 GPU 权重类型(fp8、fp16或bf16)
接进 SGLang 时,--kt-weight-path 指向转换好的 CPU 权重目录。
支持的输入格式: FP8、FP16、BF16 → INT4/INT8。
CPU 权重(LLAMAFILE 后端:LLAMAFILE): LLAMAFILE 直接在 CPU 侧使用预量化的 GGUF 权重,无需运行 convert_cpu_weights.py。你需要:
- 直接从网上下载 GGUF 模型(例如 Hugging Face / Modelscope 上的 GGUF 仓库);
- 在 SGLang 集成中,将该 GGUF 目录作为
--kt-weight-path。KT-Kernel 支持Q4_KM、Q4_K、Q5_K等多种 GGUF 量化格式,可按延迟与精度需求选择。
3. 启动 SGLang 服务
用你平时的 SGLang 参数启动服务,再补上下面这几个 KT-Kernel 专用参数,就能走 CPU-GPU 异构推理:
需要追加的 KT-Kernel 参数:
--kt-method:后端方法(AMXINT4、AMXINT8 或 LLAMAFILE)--kt-weight-path:转换后的 CPU 权重路径--kt-cpuinfer:CPU 推理线程数(设为物理核心数)--kt-threadpool-count:线程池数量(设为 NUMA 节点数)--kt-num-gpu-experts:保留在 GPU 上的专家数量--kt-max-deferred-experts-per-token:用于流水线执行的延迟专家数
示例:
1 | python -m sglang.launch_server \ |
参数该怎么调,下面 KT-Kernel 参数 一节有详细说明。
完整示例:Qwen3-30B-A3B
这个例子把「下权重 → 起服务」的全流程走一遍,同时给出 Native 后端、AMX 后端 和 LLAMAFILE 后端 三种选择。
硬件配置:
- GPU:NVIDIA RTX 4090 24GB
- CPU:2x Intel Xeon Gold 6454S(共 64 个物理核心、128 线程、2 个 NUMA 节点)
- 模型:Qwen3-30B-A3B
如何确认系统配置:
1 | # 检查 CPU 配置 |
参数取值理由:
--kt-cpuinfer 64:设为物理核心数(64),而非超线程数(128)--kt-threadpool-count 2:检测到 2 个 NUMA 节点(双路系统)--kt-num-gpu-experts 32:24GB 显存下,这个模型大概能把 32 个专家放在 GPU 上(具体看模型架构和实际占用)--kt-max-deferred-experts-per-token 2:启用流水线执行;让 CPU 在 GPU 完成当前批次时就开始处理下一批次--kt-gpu-prefill-token-threshold 2048:token 数超过 2048 时使用逐层预填充策略(仅原生后端)
方式 A:原生后端(BF16)
适合支持 BF16 的 AVX512 CPU。
第 1 步:下载模型权重
1 | # 如未安装 huggingface-cli 请先安装 |
第 2 步:启动 SGLang 服务
1 | python -m sglang.launch_server \ |
方式 B:AMX 后端(AMXINT8)
适合支持 AMX 指令集的 Intel CPU。
第 1 步:下载模型权重
1 | # 如未安装 huggingface-cli 请先安装 |
第 2 步:转换为 CPU 权重(AMXINT8)
1 | python scripts/convert_cpu_weights.py \ |
第 3 步:启动 SGLang 服务
1 | python -m sglang.launch_server \ |
方式 C:LLAMAFILE 后端(GGUF)
适合普通 CPU(不需要 AMX),直接用预量化的 GGUF 权重。
第 1 步:下载 GPU 权重(原始模型)
1 | pip install huggingface-hub |
第 2 步:下载 CPU 权重(GGUF 格式)
1 | huggingface-cli download Qwen/Qwen3-30B-A3B-GGUF Qwen3-30B-A3B-Q4_K_M.gguf \ |
第 3 步:启动 SGLang 服务
1 | python -m sglang.launch_server \ |
KT-Kernel 参数
| 参数 | 说明 | 示例值 |
|---|---|---|
--kt-method |
CPU 推理后端方法 | AMXINT4、AMXINT8、RAWINT4、FP8、FP8_PERCHANNEL、BF16 或 LLAMAFILE |
--kt-weight-path |
量化 CPU 权重路径 | /path/to/cpu-weights |
--kt-cpuinfer |
CPU 推理线程数 | 64(按 CPU 核心数调整) |
--kt-threadpool-count |
并行执行的线程池数量 | 2(通常 1-4) |
--kt-num-gpu-experts |
保留在 GPU 上的专家数量 | 32(其余专家放到 CPU) |
--kt-max-deferred-experts-per-token |
每个 token 中延迟执行以形成流水线的专家数 | 2(0 表示关闭,建议 1-4) |
--kt-gpu-prefill-token-threshold |
预填充策略的 token 数阈值(仅原生后端) | 约 1024-4096 |
--kt-enable-dynamic-expert-update |
依据实际路由统计在预填充期间动态更新专家放置 | (标志位,无需取值) |
--kt-expert-placement-strategy |
初始 GPU 专家放置策略 | uniform、frequency、front-loading 或 random |
参数取值指南:
kt-method:按 CPU 与权重格式选择:AMXINT4:在支持 AMX 的 CPU 上配合 INT4 量化权重性能最佳(部分模型可能出现较大精度下降,例如 Qwen3-30B-A3B)AMXINT8:在 AMX CPU 上使用 INT8 量化权重,精度更高RAWINT4:CPU 与 GPU 共享原生 INT4 权重(目前支持 Kimi-K2-Thinking 模型)。详见 Kimi-K2-Thinking 原生教程。FP8、FP8_PERCHANNEL:CPU 与 GPU 共享 FP8 权重BF16:CPU 与 GPU 共享 BF16 权重LLAMAFILE:基于 GGUF 的后端
kt-cpuinfer:设为物理 CPU 核心数(不是超线程数)。- 查看物理核心数:
lscpu | grep -E "^CPU(s)|Thread(s) per core" - 物理核心数 = CPU(s) / Thread(s) per core
- 示例:若 CPU(s)=128、Thread(s) per core=2,则物理核心数为 64
- 重要:不要设为超线程数——那会导致性能下降
- 查看物理核心数:
kt-threadpool-count:设为 NUMA 节点数。- 查看 NUMA 数量:
lscpu | grep "NUMA node(s)" - 或使用:
numactl --hardware | grep "available" - 注意:NUMA 节点数不必然等于物理 CPU 数
- 它表示内存域,可能在单个 CPU 内划分,也可能跨多个 CPU
- 以
lscpu显示的 NUMA 节点数为准,与物理 CPU 数量无关
- 典型取值:单路 1-2,双路 2-4
- 这样可以在各 NUMA 域之间更好地利用内存带宽
- 查看 NUMA 数量:
kt-num-gpu-experts:根据显存与 profiling 结果确定:- GPU 专家越多 = 延迟越低但显存占用越高(可能导致 OOM)
kt-max-deferred-experts-per-token:启用流水线执行:0:同步执行(更简单,延迟更高)1-4:延迟执行(推荐区间;延迟与质量平衡较好,需要调优)5-7:延迟降低最多,但可能带来明显精度损失,谨慎使用
kt-gpu-prefill-token-threshold(仅 FP8 与 RAWINT4):控制原生 FP8 与 INT4 推理的预填充策略:- ≤ 阈值:使用 CPU+GPU 混合预填充。不需要额外显存,但随 token 数增加性能会逐渐下降。
- > 阈值:使用逐层 GPU 预填充。长序列下性能扩展更好,但需要多一层 MoE 的显存(例如 Kimi-K2-Thinking 约 9GB+,MiniMax-M2.1 约 3.6GB)。
- 仅在
--kt-method RAWINT4或--kt-method FP8时生效。
kt-enable-dynamic-expert-update:在推理期间启用动态专家放置更新。- 在逐层预填充过程中,系统收集真实路由统计并据此重新分配 GPU 专家。
- 需要设置
--kt-gpu-prefill-token-threshold,且预填充长度必须 ≥ 该阈值。 - 在较低的 GPU 专家比例(10%-70%)下尤其有效,可显著优于静态策略。
- 基准数据与细节见专家调度教程。
kt-expert-placement-strategy:决定服务启动时哪些专家放到 GPU。uniform:把所有 MoE 层均分。默认选项,无需先验统计。frequency:把激活最频繁的专家放到 GPU。有激活统计时性能最佳;需要--init-expert-location指向.pt统计文件。front-loading:从第一个 MoE 层开始依次填满 GPU 专家。random:以固定随机种子(42)随机选择专家。- 策略对比见专家调度教程。
直接使用 Python API
不想用 SGLang 的话,也可以直接调 Python API:
1 | from kt_kernel import KTMoEWrapper |
高级选项
1 | # 使用额外选项初始化 |
手动配置(进阶)
要做可移植构建、二进制分发,或者跨机器部署,就得手动指定目标指令集:
1 | # 通用分发(可运行在 2017 年以来的任意 AVX512 CPU 上) |
可选:覆盖 VNNI/BF16 检测
1 | # 强制启用/禁用 VNNI 与 BF16(用于测试兜底路径) |
可选:在非 AMX 的 AVX512 CPU 上使用 oneDNN INT8 BRGEMM
1 | # 需要已安装 oneDNN >= 3.9: |
全部可选参数见 ./install.sh --help。
构建配置
手动安装(不使用 install.sh)
如果你想抛开 install.sh 自己手动装:
1. 安装系统依赖
前置条件:
cmake(推荐:conda install -y cmake)libhwloc-dev与pkg-config
2. 设置构建配置
核心选项:
| 变量 | 可选值 | 说明 |
|---|---|---|
CPUINFER_CPU_INSTRUCT |
NATIVE、AVX512、AVX2、FANCY |
使用的 CPU 指令集 |
CPUINFER_ENABLE_AMX |
ON、OFF |
启用 Intel AMX 支持 |
CPUINFER_ENABLE_ONEDNN_VNNI |
ON、OFF |
在非 AMX 的 AVX512 CPU 上启用 oneDNN INT8 BRGEMM |
CPUINFER_ONEDNN_SOURCE_DIR |
路径 | 可选的 oneDNN >= 3.9 源码树 |
CPUINFER_BUILD_TYPE |
Release、Debug、RelWithDebInfo |
构建类型(默认:Release) |
CPUINFER_PARALLEL |
数字 | 并行构建任务数(默认自动检测) |
CPUINFER_VERBOSE |
0、1 |
详细构建输出(默认:0) |
指令集细节:
| 选项 | 目标 CPU | 使用场景 |
|---|---|---|
NATIVE |
仅你的特定 CPU | 本地构建(性能最佳,默认) |
AVX512 |
Skylake-X、Ice Lake、Cascade Lake、Zen 4+ | 通用分发 |
AVX2 |
Haswell(2013)及更新 | 最大兼容性 |
FANCY |
Ice Lake+、Zen 4+ | 具备完整 AVX512 扩展的现代 CPU |
配置示例:
1 | # 本地使用——性能最佳(默认行为) |
3. 构建并安装
1 | # 可编辑安装(用于开发) |
错误排查
找不到 CUDA
1 | -- Looking for a CUDA compiler - NOTFOUND |
先确认装好了 CUDA toolkit,而且 nvcc 在系统 PATH 里。
可以试试 export CMAKE_ARGS="-D CMAKE_CUDA_COMPILER=$(which nvcc)" 之后再装一遍。
找不到 hwloc
Debian 系系统直接 sudo apt install libhwloc-dev;其他系统从源码编译:https://www.open-mpi.org/projects/hwloc/。
1 | wget https://download.open-mpi.org/release/hwloc/v2.12/hwloc-2.12.2.tar.gz |
权重量化
AMX 后端(AMXINT4 / AMXINT8)得先用脚本把 CPU 侧专家转成 AMX 友好的 INT4/INT8:
1 | python scripts/convert_cpu_weights.py \ |
支持的格式: FP8、FP16、BF16 → INT4/INT8
LLAMAFILE 后端(LLAMAFILE)的 CPU 侧专家直接读 GGUF 权重,不用跑 AMX 转换脚本。从网上下一个 GGUF 模型(比如 Hugging Face 上的 GGUF 仓库),再把 weight_path / SGLang 的 --kt-weight-path(有些场景用 --model)指向那个 GGUF 目录就行。KT-Kernel 支持 Q4_KM、Q4_K、Q5_K 等多种 GGUF 量化类型。
更多细节、进阶选项和低内存模式见 scripts/README.md。
提交代码之前!
提交信息请按 Conventional Commits 规范来写:https://www.conventionalcommits.org/
提交前先把代码格式化:
1 | cmake -B build |
需要比较新的 clang-format(至少 18 版)。conda 环境里这样装:
1 | conda install -c conda-forge clang-format=18 |
另外建议装个 black,用来格式化 Python 代码:
1 | conda install black |
KTransformers 微调 × LLaMA-Factory 集成 – 用户指南
MadSys Lab、KVCache-AI 团队、Approaching AI、LLaMA-Factory 团队
简介
从 DeepSeek-V3/R1 到 Qwen3-MoE、Kimi-K2,每一波开源大模型都把性能和规模往上推了一大截。可另一面是 GPU 太贵、模型动辄几百亿上千亿参数,资源有限时想微调超大模型几乎无路可走。为了填上这个坑,我们给出一条很实在的路子:把 KTransformers 和 LLaMA-Factory 接起来。2–4 张 RTX 4090 加一台大内存的 CPU 机器,就能微调 DeepSeek-671B 这类超大 MoE 模型。
我们想让资源紧张的研究者也能在本地摸一摸超大模型的微调,顺便给 14B/30B 这类小模型留一条快速定制的路子。方案用风格化对话、西式翻译腔和医疗问答三个代表性任务做了验证,几个小时内就能完成个性化适配。
如下图所示,LLaMA-Factory 管着整个微调流程的编排与配置——数据、训练调度、LoRA 注入、推理接口都归它。KTransformers 则作为一个可插拔的高性能后端,在训练配置不变的前提下接管 Attention/MoE 这些核心算子,让 GPU 和 CPU 一起干活。

在 LLaMA-Factory 里,我们拿 HuggingFace、Unsloth、KTransformers 三种后端的 LoRA 微调做了对比。671B 这种超大 MoE,KTransformers 是目前唯一能在 4090 级硬件上跑通的方案;换成 DeepSeek-14B 这类小一点的 MoE,它吞吐更高、显存也更省。
| 在 LoRA(BF16)+ NekoQA-10K 风格化对话 下 | HuggingFace 后端 | Unsloth 后端 | KTransformers 后端 |
|---|---|---|---|
| [14B-DeepSeekV2-Lite] LoRA 微调吞吐 | 303.58 token/s | 455.37 token/s | 530.38 token/s |
| [14B-DeepSeekV2-Lite] 显存 | 32.12 GB | 9.64 GB | 6.08 GB |
| [671B-DeepSeekV3] LoRA 微调吞吐 | 规模太大无法运行 | 不支持 | 40.35 token/s |
| [671B-DeepSeekV3] 显存(各 GPU 合计) | 理论值 1400 GB † | 不支持 | 70 GB † |
† 1400 GB 是按 FP16 全参数常驻算出来的理论值(实际上跑不起来)。70 GB 是用 KT 策略(Attention 留在 GPU + MoE 分层卸载)实测到的峰值。

微调效果(示例)
风格化对话(猫娘语气)
数据集:NekoQA-10K。目标是让风格更一致、更好辨认。
图里是基座模型和微调后模型的回复对比。微调后的模型能更稳地保持目标语气和称呼(红框处),说明风格迁移微调确实有效。

基准评测
我们使用:
(1) Translational-Style-ChatLLM,要的是那种夸张的西式翻译腔——定制目标很清晰,也很风格化。
(2) AfriMed-QA(ACL 2025),面向非洲医疗场景的数据集,领域特征很强,既有选择题也有简答题——拿来评估垂直领域微调正合适。
下表是 LoRA 微调前后的指标对比,各项都涨了一大截,说明微调确实起了作用:
| Translational-Style 数据集 | BLEU-1 | BLEU-2 | BLEU-3 | BLEU-4 | ROUGE-1 | ROUGE-2 | ROUGE-L |
|---|---|---|---|---|---|---|---|
| V2-Lite(无 LoRA) | 20.66 | 8.33 | 4.54 | 2.89 | 22.71 | 4.52 | 19.19 |
| KT-LoRA 微调后的 V2-Lite | 35.41 | 22.44 | 15.42 | 11.18 | 42.03 | 18.38 | 33.10 |
| V3 基座(无 LoRA) | 8.49 | 3.34 | 1.62 | 0.96 | 15.91 | 2.55 | 10.07 |
| KT-LoRA 微调后的 V3 | 37.02 | 23.70 | 16.21 | 11.49 | 43.43 | 18.96 | 34.54 |
| AfriMed-QA(简答) | BLEU-1 | BLEU-2 | BLEU-3 | BLEU-4 | ROUGE-1 | ROUGE-2 | ROUGE-L |
|---|---|---|---|---|---|---|---|
| V2-Lite(无 LoRA) | 13.58 | 11.12 | 9.10 | 7.23 | 22.48 | 7.81 | 11.73 |
| KT-LoRA 微调后的 V2-Lite | 35.90 | 27.63 | 22.99 | 19.15 | 35.25 | 17.50 | 28.44 |
| V3 基座(无 LoRA) | 12.75 | 10.27 | 8.05 | 5.99 | 20.33 | 5.65 | 10.11 |
| KT-LoRA 微调后的 V3 | 42.42 | 34.12 | 28.95 | 24.54 | 41.97 | 22.37 | 33.28 |
| AfriMed-QA(选择题) | 准确率 |
|---|---|
| V2-Lite(无 LoRA) | 0.0645 |
| KT-LoRA 微调后的 V2-Lite | 0.4812 |
| V3 基座(无 LoRA) | 0.5833 |
| KT-LoRA 微调后的 V3 | 0.7930 |
就算是超大 MoE 模型,用 KTransformers 微调也能很快练出很强的任务表现。
快速开始
这一节讲怎么装、怎么用 LLaMA-Factory + KTransformers 做微调和推理:
- 环境准备
- 使用 KTransformers 后端微调超大 MoE 模型
- 加载微调后的模型(基座 + LoRA 适配器)来聊天/推理
- 批量推理与指标评估
环境准备
照着下面的例子,把 KTransformers 和 LLaMA-Factory 两个环境一起装好。这次为了省掉本地编译的麻烦,KTransformers 直接用 PyPI 上的包。步骤如下:(注意:本地的 Python、Torch、CUDA 版本要和装的包对得上。)
1 | # 1. 创建 conda 环境 |
使用提示: 在 LLaMA-Factory 的 YAML 中设置 use_kt: true 并选择一个 kt_optimize_rule 文件,即可让 KTransformers 接管核心计算。下面的特性展示了几种典型配置。
核心特性 1:使用 KTransformers 后端微调超大 MoE 模型
运行命令:USE_KT=1 ACCELERATE_USE_KT=true accelerate launch --config_file examples/ktransformers/accelerate/fsdp2_kt_bf16.yaml -m llamafactory.cli train examples/ktransformers/train_lora/deepseek_v3_lora_sft_kt.yaml。
注意:模型必须是 BF16。DeepSeek-V3-671B 官方发布的是 FP8,先用 DeepSeek-V3/inference/fp8_cast_bf16.py 转一下。
1 | ### model |
kt_optimize_rule 决定放置策略,规则文件都在 ktransformers/optimize_rules。看文件名基本就能猜到用途(* 是通配符):
| 命名模式 | 含义 |
|---|---|
| DeepSeek-V2-Lite-Chat-* / DeepSeek-V3-Chat-* | 目标模型变体 |
| -sft- | 用于微调的策略;其余为推理策略 |
| -amx- | CPU 上使用 AMX;否则使用 llamafile |
| -multi-gpu-X | 在 X 张 GPU 上模型并行(省略 X 则默认 2 张) |
比如 DeepSeek-V3-Chat-sft-amx-multi-gpu.yaml,意思是 V3-Chat 微调、开 AMX、两张卡做模型并行。
能用 AMX 就尽量用(lscpu | grep amx 看一眼)。AMX 支持 BF16/INT8。示例:
1 | - match: |
训练结果会写到 output_dir,safetensors 格式,外加适配器元数据,后面加载要用。

核心特性 2:与微调后的模型对话(基座 + LoRA 适配器)
运行命令:llamafactory-cli chat examples/inference/qwen3_lora_sft.yaml。
拿 KT 训出来的 safetensors 适配器直接推理就行。
1 | model_name_or_path: opensourcerelease/DeepSeek-V3-bf16 |
GGUF 适配器也支持:safetensors 就把 adapter_name_or_path 填成目录,GGUF 就填文件路径。
加载时 LLaMA-Factory 会把层名映射成 KT 的命名,日志里能看到类似 Loaded adapter weight: XXX -> XXX 的行:

核心特性 3:批量推理 + 指标评测(基座 + LoRA 适配器)
运行 API_PORT=8000 llamafactory-cli api examples/inference/qwen3_lora_sft.yaml,用 KT 微调出的适配器对外提供 API;其他 API 的用法和原生 LLaMA-Factory 完全一样。
1 | model_name_or_path: opensourcerelease/DeepSeek-V3-bf16 |
KT 微调速度(用户视角)
端到端性能
定义
step_time:一个完整优化步的墙钟时间(张量搬运 + Attention + MoE + 其他计算)。tokens_per_step = GAS × qlen;token/s = tokens_per_step / step_time。
设置: GAS=16、qlen=512(→ tokens_per_step = 8192);LoRA(r=8, alpha=32, dropout=0.1);启用 AMX;GPU:RTX 4090,CPU:Intel Xeon Platinum 8488C。
实测
- DeepSeek-V3-671B:
step_time = 203 s→token/s ≈ 8192 / 203 ≈ 40.35 - DeepSeek-V2-Lite-14B:
step_time = 36 s→token/s ≈ 8192 / 36 ≈ 227.6
GPU/CPU 内存占用
- DeepSeek-V3(671B;61 层中 58 层为 MoE):GPU 显存合计约 70 GB(多卡),CPU 内存约 1.2–1.3 TB。
- DeepSeek-V2-Lite(14B;27 层中 26 层为 MoE):GPU 显存约 5.5 GB,CPU 内存约 30 GB。
结论
把 KTransformers LoRA 微调接进 LLaMA-Factory,等于给 MoE 大模型的训练和部署配了一份实用说明书。KT 负责前沿优化(DeepSeek/Qwen/Kimi 都能跑,还有 AMX 加速 kernel),LoRA 让很低显存下的定制成为可能,LLaMA-Factory 则提供了一套顺手的统一接口。
这么一接(有点像 Unsloth 那种提速思路),几百亿到上千亿参数的模型也能在普通硬件上微调、以低延迟上线。省内存、跑得快、还好用,三样都占。下一个 MoE 项目不妨试试 LLaMA-Factory + KT,照着这份指南走;有问题也欢迎反馈。
KTransformers SFT 文档
- Kimi K2.5:PyPI 安装、LoRA 训练、断点续训与部署(中文)
- KTransformers × LlamaFactory MoE 微调 Cookbook
- KTransformers × LlamaFactory MoE 微调 Cookbook(中文)
- v0.6.1 快速开始
- 微调用户指南
- KT-FT 微调与推理闭环
- DeepSeek-V4-Flash LoRA 快速开始
- DeepSeek-V4-Flash MXFP4 LoRA 训练与静态部署
- 开发者技术说明
- DPO 教程
- 注入教程
KTransformers × LlamaFactory MoE 微调 Cookbook
论文: KTransformers-FineTune (KT-FT) · PDF。
从 Qwen3.5 到 DeepSeek-V4、Kimi-K3、GLM-5.2,每一个新的超大规模开源模型,能力和规模都上了一个大台阶。可高端 GPU 的价格摆在那儿,很多人和团队还是没法在有限资源下微调这些模型。KTransformers 和 LlamaFactory 给出一条更现实的路:凑 1–4 张 RTX 4090,再加一台内存够大的 CPU 机器,就能微调 DeepSeek-V3/V4 系列、Kimi-K2.5、GLM-5.2 这些万亿参数级别的 MoE 模型。
KTransformers 接进了 LlamaFactory,同时没打断它原来的训练流程。数据处理、训练编排、LoRA 注入、推理集成,仍然统一由 LlamaFactory 来配置和调度。GPU 上跑 Attention 和 Shared Expert,Routed Experts 交给 KTransformers 放在 CPU 内存里,GPU 和 CPU 配合着跑。

技术概览: KTransformers 把计算密集的 Attention 与共享模块放在 GPU,把体量大但稀疏激活的 Routed Experts 存放在 CPU 内存。这样无需反复通过 PCIe 传输庞大的专家权重,CPU 运行时还能根据权重格式与可用指令集自动选择优化后端。

指南速览: 首次运行时,从 原生 BF16 + LoRA 或全量微调 + kt_backend: auto 开始。这条路径无需权重转换,只需两个 YAML 文件即可启动。如果模型提供原生 FP8 checkpoint 且训练方式为 LoRA,KTransformers 可以直接加载原生 FP8 专家权重以降低主机内存占用。仅当主机内存仍是瓶颈、且已准备好相匹配的转换产物时,才使用转换后的 INT8 或 AMXINT4 权重。
目录
- 检查硬件并安装
- 选择微调方案
- 自定义 YAML:进阶设置
- 性能与资源估算
- 附录:完整配置与问答
1. 检查硬件并安装
1.1 检查硬件资源
先看 CPU 指令集,确定能用哪个加速后端:
1 | lscpu | grep -i -E 'Model name|Socket|NUMA|avx512|amx' |
再看显存、主机内存和磁盘空间:
1 | nvidia-smi |
请确认两项要求:
- 指令集兼容性: 原生 FP8 要的是带 AVX512F、AVX512_BF16、AVX512_VNNI、AVX512_VBMI 的 AMD/x86 CPU。INT8 的话,
auto能选 AMX-INT8 或 AVX512-VNNI 实现。AMXINT4 需要 AMX 硬件加配套的转换权重。有 AMX 时,原生 BF16 跑得最好。 - 容量充足: 主机内存需容纳专家权重,并为激活、梯度与优化器状态留出空间。磁盘容量也需覆盖 checkpoint 与临时文件。
1.2 安装环境
环境用干净的 Python 3.11。装 LlamaFactory 之前先把 PyTorch 固定到 2.9.1,KT 的依赖放到最后装,免得标准版 transformers 或 accelerate 把 KT 的变体覆盖掉:
1 | conda create -n kt-sft python=3.11 -y |
装完检查一下依赖是否一致,再看 Python 实际导入的是哪些版本:
1 | python -m pip check |
一份能用的环境,版本大概是这样的:
1 | No broken requirements found. |
2. 选择微调方案
先定专家权重格式,再定 LoRA 还是全量微调。两个都定下来,就用下面对应的训练 YAML 和 Accelerate YAML。
2.1 选择专家权重格式
原生精度/转换精度说的是专家权重格式;AMX(Advanced Matrix Extensions)和 AVX512(Advanced Vector Extensions 512-bit)说的是 CPU 指令集和后端——这两件事不在一个维度上。
| 权重选项 | 何时使用 | 要求与取舍 |
|---|---|---|
| 原生 BF16 checkpoint | 主机内存充足,且优先考虑稳定、直接的训练路径 | 无需权重转换。有 AMX 时,auto 会选择当前最快的 AMXBF16 路径 |
| 原生 FP8(8 位浮点) | 模型提供原生 FP8 checkpoint,且希望保持原始权重格式 | 目前用于基座专家冻结的 LoRA。需要完整的 AVX512 FP8 扩展集;AMX 不支持这条原生 FP8 路径 |
| KT 转换的 INT8 | 原生专家权重放不进主机内存 | 需要相互匹配的一对 INT8 路由专家权重与 BF16 非专家缓存。auto 可选择 AMX-INT8 或 AVX512-VNNI |
| KT 转换的 AMXINT4 | 内存压力更严重,且可接受额外的精度风险 | 需要 AMX 与相匹配的 AMXINT4 权重。请在代表性评测集上验证质量 |
主机内存够的话,优先用原生 BF16 或原生 FP8。只有在已经备好配套的转换权重、又确实要压专家内存时,才上 INT8 或 AMXINT4。
2.2 选择 LoRA 或全量微调
专家权重格式和「更新哪些参数」是两件独立的事,但能搭配的组合有明确边界。原生 BF16 既能 LoRA 也能全量微调。原生 FP8、INT8、AMXINT4 这几套配方都是基座专家冻结的 LoRA。全量微调走 BF16。
| 方式 | 何时使用 | 资源与产出 |
|---|---|---|
| LoRA(Low-Rank Adaptation) | 默认推荐,用于快速任务适配、反复实验或资源受限场景 | 显存、主机内存与磁盘开销更低。产出 LoRA 适配器与 KT 专家 LoRA 产物 |
| 全量微调 | 任务需要更新全部目标参数,且能承担更高的训练与 checkpoint 开销 | 需要更多显存、主机内存与磁盘容量。产出完整模型 checkpoint |
2.3 两个 YAML 文件的职责
每次跑都要两个 YAML。训练 YAML 定义任务,KTransformers 的所有设置也都写在这里。Accelerate YAML 只管分布式执行和 FSDP2。目前 LlamaFactory 不接受在 Accelerate YAML 里写 kt_config。
| 文件 | 职责 | 常见字段 |
|---|---|---|
| 训练 YAML | 模型、数据、LoRA 或全量微调、批大小、序列长度、输出目录以及全部 KT 设置 | model_name_or_path、dataset、finetuning_type、lora_*、cutoff_len、output_dir、use_kt、kt_cpu_activation、kt_weight_path、kt_non_expert_weight_path、kt_config |
| Accelerate YAML | GPU 进程数、FSDP2(Fully Sharded Data Parallel 2)与全局混合精度 | num_processes、mixed_precision、fsdp_config |
启动前先核对三件事:
CUDA_VISIBLE_DEVICES中的 GPU 数量必须等于num_processes。- 如果在训练 YAML 中手动设置了
kt_config.kt_model_max_length,它必须覆盖cutoff_len加上运行时 token 余量。 - LoRA rank 只写在训练 YAML 顶层。LlamaFactory 会推导 KTransformers 内部使用的字段。全量微调时请删除仅 LoRA 需要的字段。
2.4 四种常见方案的基础 YAML
从附录 A.1 和 A.2 抄完整配置,再把所选方案对应的字段替换掉。每个代码块都标了是训练 YAML 还是 Accelerate YAML。kt_config 一律写在训练 YAML 里。
2.4.1 原生 BF16 + LoRA
1 | # File 1: training YAML |
2.4.2 原生 FP8 + LoRA
1 | # File 1: training YAML |
2.4.3 INT8 / AMXINT4 + LoRA
1 | # File 1: training YAML |
2.4.4 原生 BF16 + 全量微调
1 | # File 1: training YAML |
2.5 启动
1 | CUDA_VISIBLE_DEVICES=0,1 accelerate launch --main_process_port 0 --config_file qwen35_fsdp2_2gpu.yaml src/train.py qwen35_397b_bf16_lora.yaml |
3. 自定义 YAML:进阶设置
基础方案能跑起来之后,再按训练目标和资源瓶颈调下面这些参数。没有明确理由就保持推荐值,也别一次动好几组。
(1) LoRA 容量:lora_rank、lora_alpha、lora_target、lora_dropout
这四个字段只在训练 YAML 顶层改。KTransformers 内部用的 rank、alpha、dropout 由 LlamaFactory 自动推导,不用在 kt_config 或 Accelerate YAML 里再写一遍。起步建议 lora_rank: 8、lora_alpha: 16、lora_target: all、lora_dropout: 0.0。
要是任务适配不够,先把 rank 提到 16,再提到 32,alpha 保持在 rank 的两倍左右。小数据集出现过拟合,就把 dropout 提到 0.05。
(2) 序列长度:cutoff_len
按大多数样本的实际 token 长度来设,别为了几条长样本就直接用数据集的最大长度。序列越长,激活和 KT 缓冲区占得越多,主机内存和显存需求一起往上走。
KT 的模型长度容量是从 cutoff_len 推出来的。想手动加大,就在训练 YAML 的 kt_config 里设 kt_model_max_length,它得大于 cutoff_len,还要给运行时的额外 token 留点余量。
(3) 批大小:per_device_train_batch_size、gradient_accumulation_steps
两个都在训练 YAML 里设。超大 MoE 从 per_device_train_batch_size: 1 起步,确认显存和主机内存够用了,再往上加 micro batch。显存不够就把 micro batch 压回 1,靠梯度累积把有效批大小做上去。
1 | effective batch size = per_device_train_batch_size × number of GPUs × gradient_accumulation_steps |
(4) 激活重算与 CPU 激活复用:disable_gradient_checkpointing、kt_cpu_activation
训练 YAML 里 disable_gradient_checkpointing: false 会打开梯度 checkpointing,用多算一点换取更低的激活内存。设成 true 会保留更多中间结果,可能更快,但也更吃内存。
主机内存够的话,可以在同一个训练 YAML 里加上这个顶层字段:
1 | kt_cpu_activation: retain |
这个开关会在 checkpoint 重算时保留 CPU 专家激活,用更多主机内存换掉重复的 CPU 计算。开了梯度 checkpointing 又没写这个字段,CPU 和 GPU 的激活都会被重算。kt_cpu_activation 管的是 CPU 专家激活保不保留,disable_gradient_checkpointing 管的是整体的重算策略——别当成一个开关用。
(5) CPU 专家复用与线程:kt_share_backward_bb、kt_num_threads
这两个都在训练 YAML 的 kt_config 里。kt_share_backward_bb: true 保持打开,CPU 专家反向计算要用的缓冲区就能复用。它和 kt_cpu_activation 是两回事;除非当前模型的配置明确要求,别关它。
kt_num_threads 填这个任务能用的物理核心数,不是含 SMT 的逻辑核心总数。如果数据预处理也占同一批 CPU,记得给 DataLoader 和系统进程留几个核。
kt_threadpool_count 由 NUMA 拓扑自动推导。确认过 CPU socket 和 NUMA 布局之后,再手动改它。
(6) 从 checkpoint 续训:resume_from_checkpoint
在训练 YAML 里把它设成目标 checkpoint-* 目录。全新训练就不写这个字段。output_dir 始终指向当前任务的输出目录,别指到基座模型目录去;overwrite_output_dir: false 也保持住,免得把已有结果盖掉。
4. 性能与资源估算
下表基于 2K 上下文(sequence length = 2048)、单卡批大小 1、梯度累积 1,且只包含完成真实 LoRA 训练的、被接受的 KTransformers BF16 运行结果。吞吐包含前向、loss、反向与优化器步骤。
| 模型与权重 | GPU 数 | 全局批大小 | 单卡显存最低参考 | 主机内存最低参考 | 微调吞吐(tokens/s) |
|---|---|---|---|---|---|
| Qwen3-235B-2507 BF16 LoRA | 2 | 2 | ≥ 27.14 GiB | ≥ 545.36 GiB | 147.91 |
| Qwen3.5-397B BF16 LoRA | 8 | 8 | ≥ 20.37 GiB | ≥ 1075.68 GiB | 215.25 |
显存那列是实测里单卡的最高峰值,主机内存那列是训练进程树的峰值 CPU RSS(统一折成 GiB)。这些是实测配置的最低参考值,不是安全余量。数据加载、缓存、存 checkpoint、系统进程,都得另外留出空间。
不同 GPU 数量的结果没法直接拿来做线性外推。cutoff_len、批大小、KT 缓存深度,任何一个往上加,资源占用都跟着涨。全量微调还得额外准备梯度、master 权重、优化器状态和完整 checkpoint 的空间。
附录
A.1 Qwen3.5-397B BF16 LoRA 训练 YAML
存成 qwen35_397b_bf16_lora.yaml:
1 | ### model |
A.2 FSDP2 Accelerate YAML
存成 qwen35_fsdp2_2gpu.yaml:
1 | compute_environment: LOCAL_MACHINE |
A.3 问答
A.3.1 为什么原生 FP8 checkpoint 不能使用转换后的 INT8 配置?
两者的权重格式和加载路径都不一样。原生 FP8 保留 checkpoint 里的 FP8 权重和 scale,走 AVX512 原生精度后端。INT8 配方读的是配套的一对 INT8 路由专家权重加 BF16 非专家缓存,再由 auto 选 AMX-INT8 还是 AVX512-VNNI。原生 FP8 的 checkpoint 别往 kt_weight_path 里塞。
A.3.2 auto 没有选到预期的后端
把 lscpu 输出和启动日志留好,先确认容器或虚拟化没把需要的指令集藏起来。有 AMX 时,原生 BF16 会选 AMXBF16;原生 FP8 应该选 AVX512。CPU 或权重格式不支持的后端,别硬指定。
A.3.3 主机内存不足
先把并发数据加载、序列长度、缓存深度降下来,再确认专家权重没被加载成两份。还是不够,就去准备转换后的 INT8 或 AMXINT4 权重。全量微调的话,梯度、master 权重、优化器状态的内存要单独算。
A.3.4 GPU OOM
OOM 就是显存或主机内存不够。先降 cutoff_len、单卡批大小和激活占用,再把 gradient_accumulation_steps 提上去,保住全局批大小。num_processes、可见 GPU 数量、实际模型放置,三者必须一致。
A.3.5 kt_model_max_length 与 cutoff_len 不匹配
调大 cutoff_len 的时候,kt_model_max_length 也要跟着调大,并给运行时的有效序列长度留出余量。值太小会报缓冲区或形状错误;值大得没必要,又白白吃主机内存。
使用 SGLang-KT 部署 Qwen3.5 MoE 的 KT LoRA
最后更新:2026-06-23
这份文档梳理 Qwen3.5 MoE 现在的 KT-FT 闭环:先用 KT SFT 训练,把输出转换一次,再用 SGLang 通过一条合并后的适配器路径把微调结果跑起来。
1 | KT SFT raw output |
训练侧的 KT SFT 文档另有说明。这一页只讲怎么把训好的 LoRA 产物接到在线推理上。
1. 适用范围
当前支持并验证过的流程:
- 基座模型:Qwen3.5 MoE,例如
Qwen3.5-35B-A3B - KTransformers 版本:v0.6.3 或更新
- KT 专家权重:AMX/BF16 SFT 兼容的 KT CPU 专家路径
- 面向用户的部署输入:一个转换后的合并适配器目录
- 运行时拆分:专家 LoRA 走 KT CPU 专家路径;非专家 LoRA 走 SGLang 的 LoRA 管理器。该拆分在服务启动时自动完成。
- 该工作流针对 KT MoE 专家 LoRA 产物。标准的稠密模型 PEFT LoRA 适配器通常不需要这个转换器。
2. 各阶段的产物
原始 KT SFT 输出
用 LLaMA-Factory + KT 训完之后,输出目录里有两个 LoRA 产物:
1 | <KT_SFT_OUTPUT_DIR>/ |
这个原始目录别直接丢给 SGLang 部署。
转换后的合并适配器
跑一次转换器,生成部署用的输入:
1 | <MERGED_ADAPTER_DIR>/ |
这个合并目录在一个 PEFT 风格适配器里同时装了专家和非专家 LoRA 张量。传给 --lora-paths 的只该是它。
3. 转换一次
1 | python kt-kernel/scripts/convert_kt_to_sglang_adapter.py \ |
示例:
1 | python kt-kernel/scripts/convert_kt_to_sglang_adapter.py \ |
转换器会读 fused_expert_lora.safetensors 和已有的非专家 adapter_model.safetensors,然后写出一个合并适配器目录。
如果原始 KT SFT 输出里没有带 lora_alpha 的 adapter_config.json,就用 --lora-alpha <value> 显式传进去。转换器不会把 LoRA 缩放折进张量,运行时缩放仍然是 lora_alpha / r。
想调试的话,也可以把专家和非专家分开输出:
1 | python kt-kernel/scripts/convert_kt_to_sglang_adapter.py \ |
正常部署只需要 <MERGED_ADAPTER_DIR>。
4. 启动 SGLang
用本仓库里的 KTransformers SGLang 分支,并把 PYTHONPATH 同时指向 kt-kernel/python 和 third_party/sglang/python。
1 | cd /path/to/ktransformers |
要点:
- 只通过
--lora-paths传入一个合并适配器。 - 在正常用户工作流中不要同时传
--kt-expert-lora-path。 - 启动时,服务会识别合并的 KT MoE 适配器,在内部完成拆分,并把运行时缓存目录写到
$TMPDIR/sglang_kt_lora_cache/(若设置了$SGLANG_KT_LORA_CACHE_DIR则写到该处)。 - Qwen3.5 全量 LoRA 生成建议使用
--lora-backend triton。
当前约束:
- 仅支持单个合并的 KT 复合适配器
--kt-num-gpu-experts 0- 不要启用
--kt-enable-dynamic-expert-update - 不要使用
--kt-gpu-prefill-token-threshold --max-running-requests必须至少为 2- 使用 AMX/BF16 SFT 兼容的 KT 方法,例如
AMXINT4、AMXINT8、AMXBF16或BF16
5. 请求语义
OpenAI 兼容请求里的 model 字段填的是名称,不是路径。
1 | --served-model-name qwen3.5-kt-ft |
现在这套单适配器实现下,请求行为是这样的:
1 | model=qwen3.5-kt-ft |
: 后面的后缀必须和 --lora-paths 左边的名字对上。
想做一个只走基座的对照,就另起一个不带 --lora-paths 的服务。
6. 冒烟测试
1 | curl -sS http://127.0.0.1:30006/v1/chat/completions \ |
启动日志里应该有类似这几行:
1 | Prepared merged KT LoRA adapter ... for runtime: expert=... nonexpert=... |
7. 进阶:手动拆分部署
老的分体运行时约定还能用,主要留给调试:
1 | --kt-expert-lora-path <EXPERT_ADAPTER_DIR> \ |
这不是推荐给用户的路子。普通用户只通过 --lora-paths 传一个合并适配器目录就够了。
8. 故障排查
Got LoRA adapter that has never been loaded: lora0
请求里的适配器名必须和 --lora-paths 左边的名字一致。启动时写的是 qwen35b_lora=...,请求就得写 model=qwen3.5-kt-ft:qwen35b_lora,不是 :lora0。
看不到适配器效果
确认你部署的是转换器产出的合并适配器目录,不是原始 KT SFT 输出目录,也不是别的测试适配器。
connection refused
看看服务是不是监听在你 curl 的那个端口上;另外注意上面示例绑的是 127.0.0.1,不是 0.0.0.0。
服务解析到上游 SGLang 而不是本仓库
1 | python - <<'PY' |
这个路径应该来自本仓库的 third_party/sglang。
教程:逐步注入算子
作者:Azure-Tang
TL;DR
本教程带你把自定义算子注入模型,例子用 DeepSeekV2-Chat,一步一步来。涵盖这些内容:
- TL;DR
- 如何编写注入规则
- 理解模型结构
- 基于矩阵吸收的 MLA 注入
- 路由专家的注入
- 线性层注入
- 带预计算 Buffer 的模块注入
- 为模块指定运行设备
- 多 GPU
- 如何编写新算子并注入模型
如何编写注入规则
Inject 框架的注入规则,基本长这样:
1 | - match: |
- match:该字段标记匹配规则,可以以 name 和 class 两种形式出现。这两种匹配规则可以同时出现,也可以单独出现;只有同时满足两个条件时才会匹配。
- replace:
- class:可导入的 Python 类,用于替换目标模块。如果不想替换,可设为 default。
- kwargs:模块初始化所需的参数列表。
- generate_device:这个模块挂在哪个设备上,可以填 “cpu”、”cuda”、”cuda:1” 等。
- recursive:要不要递归注入这个模块的子模块,默认是 True。
关于 recursive:有些模块本身带着一堆子模块,比如自注意力模块里通常有 q/k/v/o 四个线性层。替换了自注意力模块,又不希望内部的线性层被别的规则接管,就把这条规则的 recursive 设成 False。
理解模型结构
拿 deepseek-ai/DeepSeek-V2-Lite-Chat 当例子,可以按上面的规则一步步把自定义模块注进去跑起来。KTransformers 给的灵活度很高,基础算子随你替换、随你实验;代价是,你得清楚自己正在跑的模型是什么结构。
好在弄清楚结构并不难。打开 deepseek-ai/DeepSeek-V2-Lite 主页的文件列表,能看到这几个文件:

.saftensors 文件里能看到每一层权重的名字,对应注入规则里的 match.name;modeling_deepseek.py 里能看到各个模块类的具体实现,类名对应 match.class。
从 .saftensors 和 modeling_deepseek.py 看,DeepSeekV2 的结构是这样的:

支持的算子与对应的类如下:
| match | replace | backends | descriptions |
|---|---|---|---|
| Linear | KTransformersLinear | KLinearMarlin | 以 Marlin 为后端 |
| KLinearTorch | 以 pytorch 为后端 | ||
| KLinearCPUInfer | 以 llamafile 为后端 | ||
| KLinearFP8 | Triton fp8_gemm kernel。要求 GPU 具备 fp8 计算能力 | ||
| experts | KTransformersExperts | KExpertsTorch | 以 pytorch 为后端 |
| KExpertsMarlin | 以 Marlin 为后端 | ||
| KExpertsCPU | 以 llamafile 为后端 | ||
| Attention | KDeepseekV2Attention | KDeepseekV2Attention | MLA 实现 |
| MoE | KMistralSparseMoEBlock | KQwen2MoeSparseMoeBlock | 用于 Qwen2 的 MoE |
| KDeepseekV2MoE | KDeepseekV2MoE | 用于 DeepseekV2 的 MoE | |
| Model | KQwen2MoeModel | KQwen2MoeModel | 用于 Qwen2 的 Model |
| KDeepseekV2Model | KDeepseekV2Model | 用于 DeepseekV2 的 Model | |
| RoPE | RotaryEmbedding | RotaryEmbedding | RoPE 模块 |
| YarnRotaryEmbedding | YarnRotaryEmbedding | RoPE 模块 |
接下来一步步注入自定义模块,目标是:
- 将 linear 模块替换为自定义的 Marlin linear 模块。
- 将自注意力模块替换为自定义的基于矩阵吸收的 MLA 模块。
- 将 experts 模块替换为自定义的 Experts 模块。
- 将 MoE 模块替换为自定义的 MoE 模块。
- 将 RoPE 模块替换为自定义的 RoPE 模块。
- 为每个模块设置运行设备。
注入规则的完整实现见此处。
基于矩阵吸收的 MLA 注入
注入 Attention 模块很简单:用正则匹配 transformers 里的模块名,替换成我们自己的 MLA 实现。YAML 规则如下:
1 | - match: |
可以看到,YAML 里每条规则都分两块:match 和 replace。match 指定要替换哪个模块,replace 指定注入的模块以及它的初始化参数。
路由专家的注入
路由专家(也就是图里的 exps)注入的是 CPUInfer,外面包了一层 KTransformersExperts。这层封装有几种实现,得用参数告诉它用哪种、怎么用。
transformer 源码里 MoE 是用 nn.ModuleList 实现的。我们不希望 KTransformers 把列表里的子模块一个个遍历、逐个注入,所以这条规则里设了 recursive: False,阻止它递归往下走。YAML 规则如下:
1 | - match: |
把路由专家当成自定义模块注入之后,原来 nn.ModuleList 的接口就用不了了,FFN 模块里的 forward 得改。最省事的办法是写个带自定义 forward 的新模块,再把它注进去。
1 | - match: |
线性层注入
剩下的线性层,我们希望换成量化算子,既省存储又更快。但 MLA 和量化放在一起用目前还没有研究,所以不想往 MLA 算子里注入 linear。于是可以改正则,并在规则的 match 部分加类型判断:只有名字和类都对上的模块才会被注入。这里同样要传一些关键字,和注入路由专家时类似。YAML 规则如下:
1 | - match: |
带预计算 Buffer 的模块注入
为了初始化被注入的原始模型时不占资源,我们用 torch 的 meta device 来建原始模型。RoPE 模块初始化时会预先算一些 buffer,可 meta device 下什么都不会算。所以加载模型时得把这块补上。做法很简单:往旋转位置编码模块里注入一个自定义模块,让它在加载时做预计算。YAML 规则如下:
1 | - match: |
为模块指定运行设备
最后,给所有模块兜底设一个基础属性 generate_device:
1 | - match: |
这两条规则把之前没匹配上的层(连同子模块)和 lm_head 放到 cuda 上,embedding 放到 cpu 上。注意模块的属性由它匹配到的第一条规则决定:比如你后面又在某个注入模块里写了新的 replace.kwargs.generate_device,先设的那个仍然生效。机器上有多张卡的话,也可以把模型摊到多张卡上。
多 GPU
有多张 GPU 的话,可以把不同模块放到不同卡上。DeepseekV2-Chat 一共 60 层,两张卡就每张分 30 层。完整的多 GPU 规则示例见此处。

首先,多 GPU 下必须注入一个新算子 KDeepseekV2Model,并把层划分到不同 GPU。我们这里要在 KDeepseekV2Model 里这样设 transfer_map:
1 | - match: |
而且还得给模型里每个模块都指定设备。
比如 routed experts,单卡的 yaml 是这样:
1 | - match: |
但换成两张卡,就得逐个模块指定设备。
1 | # allcate 0-29 layers‘s out_device to cuda:0 |
其他模块也照这个办法设。
如何编写新算子并注入模型
这一节拿实现一个新的 linear 举例,讲讲怎么写出一个能注入的算子。
首先,所有可注入算子都要继承 BaseInjectedModule,它带着注入框架需要的一些属性。初始化函数要满足这个基本格式:
1 | class LinearTorchInject(BaseInjectedModule): |
如果你还有其他参数要传进去,也可以加到 init 里,然后在 yaml 的 kwargs 里传。比如想让算子接收一个 my_param,init 可以这么写:
1 | class LinearTorchInject(BaseInjectedModule): |
那么注入规则就可以写成:
1 | - match: |
linear 模块还得从 gguf 文件读权重。我们提供了 KLinearBase 类帮忙读,你只需要继承它并实现 load、unload、forward。一个能完整注入的 linear 类大概长这样:
1 | class LinearTorchInject(BaseInjectedModule, KLinearBase): |
注意 self.load_weight 是 KLinearBase 提供的,用来把 gguf 里的权重读进模块。KLinearBase 的实现细节在 GITHUB 上。
KTransformers 微调 × LLaMA-Factory 集成 – 开发者技术说明
MadSys Lab、KVCache-AI 团队、Approaching AI、LLaMA-Factory 团队
简介
最近这一波开源大模型——从 DeepSeek-V3/R1 到 Qwen-MoE、Kimi-K2——性能和规模都往上跳了一大截。但算力和内存卡在那儿,普通研究者很难微调万亿参数级别的模型。所以我们把 KTransformers 和 LLaMA-Factory 接在一起:2–4 张 RTX 4090 加足够大的 CPU 内存,就能微调 DeepSeek-671B 这类超大 MoE 模型。
这套架构把资源上的缺口填上了,超大模型的本地微调成为可能,14B/30B 这个量级的场景定制也能高效完成。我们用风格化对话、西式翻译腔和医疗问答做了验证,几个小时就能适配好。
架构上,LLaMA-Factory 负责数据、配置、训练编排、LoRA 插入和推理;KTransformers 是可插拔的高性能算子后端,在同一份训练代码下接管 Attention 和 MoE,让 GPU 和 CPU 异构协作,既提速又省显存。

相同设置、相同数据下,我们对比了 HuggingFace 默认、Unsloth 和 KTransformers 三种后端的 LoRA 微调。671B 级 MoE,KTransformers 是目前唯一能在 2–4×24GB 4090 上跑通的方案;14B 的 MoE 上,它吞吐更高、显存更省。
| 在 LoRA(BF16)+ NekoQA-10K 风格化对话 下 | HuggingFace 后端 | Unsloth 后端 | KTransformers 后端 |
|---|---|---|---|
| [14B-DeepSeekV2-Lite] LoRA 微调吞吐 | 303.58 token/s | 455.37 token/s | 530.38 token/s |
| [14B-DeepSeekV2-Lite] 显存 | 32.12 GB | 9.64 GB | 6.08 GB |
| [671B-DeepSeekV3] LoRA 微调吞吐 | 规模太大无法运行 | 不支持 | 40.35 token/s |
| [671B-DeepSeekV3] 显存(各 GPU 合计) | 理论值 1400 GB † | 不支持 | 70 GB † |
† 1400 GB 是 FP16 全参数常驻的理论值(跑不起来)。70 GB 是用 KT(Attention 放 GPU + MoE 分层卸载)实测的峰值。
从表里能看出来:14B 模型上,KTransformers 后端比默认 HuggingFace 方案吞吐高约 75%,显存只用到约五分之一。671B 模型上,HuggingFace 和 Unsloth 在单张 4090 上都跑不起来,KTransformers 能以 40 tokens/s 做 LoRA 微调,显存压在 70 GB 以内。

KT 微调框架总览
下面说说 KTransformers 是怎么接管 LLaMA-Factory 微调框架里的核心算子、把 Attention 和 MoE 优化掉的。
DeepSeek-V3/V2 这类 MoE 模型,一半是参数不多的稠密 Attention,一半是参数庞大的稀疏 MoE。以 DeepSeek-V2-Lite-Chat 的第 2 层为例(每层都是 Attention + MoE 的组合):Attention 计算和 KV cache 主要在 GPU 上,重量级的 MoE 部分主要在 CPU 上跑。先说 Attention 的替换与继承,再说 MoE 的封装与后端对接,最后说 多 GPU 放置。
Attention(LoRA + KT 共存)
KTransformers 提供算子注入能力(BaseInjectedModule),PEFT 负责插 LoRA 层。为了微调,我们写了 KTransformersLinearLora,同时继承 KTransformersLinear 和 LoraLayer:
- 继承:
KTransformersLinearLora保留 KT 的高性能路径(prefill_linear/generate_linear),同时接受 LoRA 参数(lora_A/lora_B)。 - 替换: 在准备阶段,我们把原有的
KTransformersLinear层(Q/K/V/O)替换为KTransformersLinearLora,既保留 KT 优化,又让 LoRA 可训练。

替换完成之后,LoRA 落在 Q/K/V/O 这几处线性变换上(左图),KTransformersLinearLora 里既有 KT 的快速路径,也有 LoRA 矩阵(右图)。

MoE(算子封装 + 反向)
封装
参数大、计算又稀疏,所以专家计算被我们封装成一个可微的黑盒算子——上游看起来是透明的,下游随时能换。
- 上游(PyTorch 计算图): 我们注册自定义 Autograd Function,使 MoE 层在图中表现为单个节点。在左图(红框)中只能看到
KSFTExpertsCPU;右图则是未封装时展开的路由、分发与 FFN 专家。封装后,MoE 层就像一个带梯度的标准nn.Module。 - 下游(后端): 在 Autograd Function 内部,通过 pybind11 调用 C++ 扩展完成前向/反向。存在多个可插拔后端(AMX BF16/INT8;llamafile)。可通过 YAML 切换后端(例如
"backend": "AMXBF16"与"llamafile")。

反向(CPU)
MoE 反向经常要用转置后的权重 $W^\top$。为了不在运行时反复转置,我们在加载时就把 $W^\top$ 预先算好并缓存(蓝框)。必要的中间激活也会缓存(比如专家投影,红框),反向时直接复用,少算一遍。llamafile 和 AMX(INT8/BF16) 的反向实现我们都有,还做了 NUMA 感知优化。

多 GPU 加载/训练:用放置策略代替 DataParallel
要在 2–4 张 GPU 上把单卡显存峰值压下来,我们走的是模型并行 + 显式放置,而不是 DataParallel(后者会在每张卡上复制整个模型)。
关键改动:
- KTrainer: 接管
.to(device),防止”把整个模型搬到单张 GPU”。借助 KT 的 optimize-rule YAML,每一层声明device: cuda:0/cuda:1/...,并直接在目标 GPU 上构造(无额外拷贝)。 - 禁用自动 DataParallel: 当
USE_KT=1时,我们禁用 LLaMA-Factory/HF Trainer 的自动 DP 包装,避免复制,并完全掌控分片。 - 梯度聚合: 梯度归约到
cuda:0。中间激活留在本地,只传输必要的张量,降低通信与激活开销。
这样,多 GPU 微调下 KT 的放置策略照样生效。用户挑一个带 multi-gpu 的 kt_optimize_rule 就行。DeepSeek-671B 上,DeepSeek-V3-Chat-sft-amx-multi-gpu.yaml 是典型的双卡方案:KV/attention 分在各卡上,MoE 专家分片放在 CPU,两张卡一起分担。
KT-LoRA 微调评测
设置
编排用 LLaMA-Factory,后端是 KTransformers,LoRA 取 rank=8、α=32、dropout=0.1、BF16,GAS=16、qlen=512,KT optimize 规则与训练时一致。评测两件事:(a) 风格化对话迁移;(b) 两个小规模但有代表性的基准:Translational-Style(生成式)和 AfriMed-QA(医疗垂直,SAQ 与 MCQ)。开 AMX;GPU 是 2×48GB RTX 4090,CPU 是 Intel Xeon Platinum 8488C。
结果
风格化对话(猫娘语气)
数据集:NekoQA-10K。跟中性、理性的基座比(蓝框),微调后的模型稳定地带着目标风格(红框)。这说明 KT-LoRA 用很低的 GPU 成本,就把风格特征注进了生成分布。

Translational-Style 基准(生成式)
数据集:Translational-Style-ChatLLM。指标:BLEU-1/2/3/4、ROUGE-1/2/L。
| Translational-Style 数据集 | BLEU-1 | BLEU-2 | BLEU-3 | BLEU-4 | ROUGE-1 | ROUGE-2 | ROUGE-L |
|---|---|---|---|---|---|---|---|
| V2-Lite(无 LoRA) | 20.66 | 8.33 | 4.54 | 2.89 | 22.71 | 4.52 | 19.19 |
| KT-LoRA 微调后的 V2-Lite | 35.41 | 22.44 | 15.42 | 11.18 | 42.03 | 18.38 | 33.10 |
| V3 基座(无 LoRA) | 8.49 | 3.34 | 1.62 | 0.96 | 15.91 | 2.55 | 10.07 |
| KT-LoRA 微调后的 V3 | 37.02 | 23.70 | 16.21 | 11.49 | 43.43 | 18.96 | 34.54 |
从上面的测试结果看,同一套工作流和放置策略下,两个规模的模型微调后都有稳定提升,说明「KT 后端 + LoRA 微调」这套组合在生成式风格控制上确实能用、也确实有效。这同时说明 KT 的异构放置和算子优化,能稳稳撑住风格领域的小样本适配。
医疗垂直基准(AfriMed-SAQ/MCQ)
数据集用 AfriMed-QA(ACL 2025),面向非洲医疗的领域数据集,场景定制特征明显,分选择题(MCQ)和简答题(SAQ)两种形式,这里拿来评估垂直领域微调。指标上,SAQ 用 BLEU/ROUGE,MCQ 用 Accuracy。
| AfriMed-QA(SAQ) | BLEU-1 | BLEU-2 | BLEU-3 | BLEU-4 | ROUGE-1 | ROUGE-2 | ROUGE-L |
|---|---|---|---|---|---|---|---|
| V2-Lite(无 LoRA) | 13.58 | 11.12 | 9.10 | 7.23 | 22.48 | 7.81 | 11.73 |
| KT-LoRA 微调后的 V2-Lite | 35.90 | 27.63 | 22.99 | 19.15 | 35.25 | 17.50 | 28.44 |
| V3 基座(无 LoRA) | 12.75 | 10.27 | 8.05 | 5.99 | 20.33 | 5.65 | 10.11 |
| KT-LoRA 微调后的 V3 | 42.42 | 34.12 | 28.95 | 24.54 | 41.97 | 22.37 | 33.28 |
| AfriMed-QA(MCQ) | 准确率 |
|---|---|
| V2-Lite(无 LoRA) | 0.0645 |
| KT-LoRA 微调后的 V2-Lite | 0.4812 |
| V3 基座(无 LoRA) | 0.5833 |
| KT-LoRA 微调后的 V3 | 0.7930 |
从表里看:(1) DeepSeek-V3(671B)经 KT-LoRA 微调后,MCQ 和 SAQ 上都明显好于微调后的 DeepSeek-V2-Lite(14B),也超过了 V3 基座。在我们这个偏小的设置下,这至少初步说明:超大参数模型做 KT-LoRA 微调,在垂直领域是有实际意义的。
(2) SAQ 和 MCQ 两个子任务上,KT-LoRA 都带来一致提升,说明在 KT 的异构放置和后端算子支持下,LoRA 微调能有效把医疗这类垂直领域的关键知识灌进模型。
局限性
目前测试大多只跑了单个数据集,规模也小(≤ 20k 样本)。我们要给的是 KT-LoRA 微调系统有效性的存在性证据,而不是关于算法泛化性或缩放律的普适结论。报告里主要还是代表性数据;想撑起更强的算法论断,得靠更大的样本量、多语言/多领域数据集和多随机种子重复实验——这些不在本文范围内。
我们也热忱欢迎大家一起参与开源 LLaMA-Factory KT 微调项目。如果你有额外的测试结果,特别欢迎记录到下方的共享表格中,并附上对应的 kt_optimize_rule 文件、数据集样例、训练/评测 YAML,以及详细的显存与 CPU 配置,供社区参考与复现~!
速度测试
端到端性能
定义
step_time:一个优化步要多久(张量搬运 + Attention + MoE + 其他)。
tokens_per_step = GAS × qlen,token/s = tokens_per_step / step_time。这里取 GAS=16、qlen=512,所以 tokens_per_step=8192。
实测
| 模型 | step_time (s) | tokens/step | token/s |
|---|---|---|---|
| DeepSeek-V3-671B | 203 | 8192 | 40.35 |
| DeepSeek-V2-Lite-14B | 36 | 8192 | 227.6 |
MoE 计算(DeepSeek-V3-671B)
理论
- 每层、每 token 的 MoE FLOPs(前向+反向)约为:$$ \text{FLOPs}_{\text{per-layer, per-token}} \approx c \cdot k \cdot H \cdot I $$
其中 $k = 8$(Top-k),$H = 7168$(hidden size),$I = 2048$(intermediate size),$c\approx16$(约 6 次前向 + 约 10 次反向矩阵乘)。
- 每个 step 跨所有 MoE 层:$$ \text{FLOPs}{\text{per-step}} \approx c \cdot qlen \cdot k \cdot H \cdot I \cdot L{\text{MoE}} $$
代入 $c=16, qlen=512, k=8, H=7168, I=2048, L_{MoE}=58$,得 $\text{FLOPs}_{\text{per-step}} \approx 55.8\ \text{TFLOPs}$。
实测(CPU 上的 MoE TFLOPS)
若单个 step 中仅 MoE 的耗时为 t_moe(秒),则 $\text{TFLOPS} = \text{FLOPs}_{\text{per-step}} / \text{step_per_second}.$
算 MoE 吞吐要用 MoE 那一段的耗时,不是完整的 step_time。
| TFLOPS | 前向 | 反向 |
|---|---|---|
| 平均 | 17.55 | 18.41 |
内存占用
- DeepSeek-V3(671B;61 层中 58 层为 MoE):GPU 合计约 70 GB,主机内存约 1.2–1.3 TB。
- DeepSeek-V2-Lite(14B;27 层中 26 层为 MoE):GPU 约 5 GB,主机内存约 30 GB。
结论
把 KTransformers LoRA 接进 LLaMA-Factory,等于给 MoE 大模型的高效训练和部署铺了一条实用路子。KT 贡献放置策略和算子优化(DeepSeek/Qwen/Kimi 都能跑,带 AMX 加速 kernel),LoRA 让很低显存下的定制成为可能,LLaMA-Factory 则给出一套一致的接口。
也就是说,几百亿到上千亿参数的 MoE 模型,也能在普通硬件上微调、以低延迟上线。省内存、速度快、好用,这套方案把三者都兼顾到了,超大模型也就真成了开发者能上手的工具。
使用 LLaMA-Factory 进行 DPO 训练
这篇教程讲怎么用直接偏好优化(DPO)配合 LLaMA-Factory 微调语言模型。DPO 是拿人类偏好来训练模型的法子,训出来的输出更对齐,也更贴近用户想要的样子。
安装
第 1 步:创建 conda 环境并适配 KTransformers
1 | conda create -n Kllama python=3.12 # choose from : [3.11, 3.12, 3.13] |
第 2 步:安装 LLaMA-Factory 环境
1 | git clone --depth 1 https://github.com/hiyouga/LLaMA-Factory.git |
第 3 步:安装 KTransformers
方式 1:从 https://github.com/kvcache-ai/ktransformers/releases/tag/v0.4.4 安装与你 Torch、Python 版本匹配的 KTransformers wheel
(注意:实际 CUDA 版本和 wheel 文件名里写的不一定一样。)
1 | pip install ktransformers-0.4.4+cu128torch28fancy-cp312-cp312-linux_x86_64.whl |
方式 2:从源码安装 KTransformers
1 | git clone --depth 1 https://github.com/kvcache-ai/ktransformers.git |
第 4 步:从 https://github.com/Dao-AILab/flash-attention/releases 安装与你 Torch、Python 版本匹配的 flash-attention wheel
1 | # abi=True/False can find from below |
第 5 步:(可选)如果你想使用 flash_infer(否则默认使用 triton)
1 | git clone https://github.com/kvcache-ai/custom_flashinfer.git |
准备模型
这里拿 deepseek-ai/DeepSeek-V2-Lite 举例,换成 Kimi K2 之类的模型也一样。
如何启动
1 | # For LoRA SFT |
示例的 YAML 文件如下:
(1)examples/train_lora/deepseek2_lora_dpo_kt.yaml
1 | ### model |
kt_optimize_rule 的更多细节见 https://github.com/kvcache-ai/ktransformers/blob/main/doc/en/KTransformers-Fine-Tuning_User-Guide.md
之后就能像 SFT 训练那样,用 saves/Kllama_deepseekV2_DPO 里存下来的 LoRA 适配器做推理。比如:
1 | model_name_or_path: DeepSeek-V2-Lite-Chat |
KT-CLI
⚠️ 注意: 该功能目前仍在积极开发中,许多功能尚未完成,正在持续改进,请关注后续更新。
设计理念
KT-CLI 的设计目标很直接:尽量少让人去翻文档。与其让你读一大篇说明,不如让 CLI 主动问你:
交互模式:不带参数运行命令即可获得逐步引导提示
直接模式:直接传入参数,便于自动化与脚本化
💡 提示: 参数与此前的 SGLang + KTransformers 方式完全兼容,可以无缝迁移。
敲一条命令,CLI 就一步步带着你走完。
用法
想看用法,执行 kt --help:
1 | kt [OPTIONS] COMMAND [ARGS]... |
KTransformers CLI —— KTransformers 的统一命令行入口。
选项
| 选项 | 说明 |
|---|---|
--help |
显示该帮助信息并退出。 |
命令
| 命令 | 说明 |
|---|---|
version |
显示版本信息 |
chat |
与运行中的模型交互式对话 |
quant |
量化模型权重 |
bench |
运行完整基准测试 |
microbench |
运行微基准测试 |
doctor |
诊断环境问题 |
model |
管理模型与存储路径 |
config |
管理配置 |
sft |
使用 LlamaFactory 微调 |
GLM-5.3-flash:1M 上下文,KTransformers 原生支持
1. 1M 上下文与原生多模态
GLM-5.3-flash 原生支持最长 100 万 token 的上下文。一个请求就能吃下大型代码库、长文档,或者一次跑很久的智能体任务,不用把上下文反复切开。
它还支持图像、视频、推理和工具调用,通过 OpenAI 兼容 API 就能直接被编码智能体调用。GLM-5.3-flash 约有 321B 参数,45 层里有 34 层 Linear Attention、11 层 DSA。
2. 原生精度的 KTransformers 支持
KTransformers(KT)直接读官方的 GLM-5.3-flash FP8 权重,不用转换模型,也不用对专家权重再做一轮量化。
FP8 模型大约占 306 GiB,系统内存至少留出 350 GB。当前实现支持:
- NVIDIA SM89 与 SM120 GPU(RTX 40 与 50 系列)
- AVX-512 FP8 CPU 专家 kernel
- CPU-GPU 异构专家推理与逐层预填充(Layerwise Prefill)
- 最长 1M token 的上下文窗口
- 多模态:文本、多张图片、视频
- 工具调用
3. 安装
准备一个干净的 Python 3.11 环境,执行:
1 | pip install "ktransformers[sglang]" |
这条命令会把版本互相匹配的 KT Kernel、SGLang-KT 和 Transformers-KT 一起装上。
4. 启动
把 /path/to/GLM-5.3-flash 换成你的模型目录。下面的配置默认打开逐层预填充、多模态输入和解码 CUDA Graph。模型最长支持 1M 上下文,示例用的是验证过的 501025 token 配置。
4.1 四卡启动
1 | MODEL_PATH=/path/to/GLM-5.3-flash |
4.2 单卡启动
1 | MODEL_PATH=/path/to/GLM-5.3-flash |
对 GLM-5.3-flash 开逐层预填充时,当前实现会把常驻 GPU 专家数归零。所以四卡示例里的 --kt-num-gpu-experts 40,在逐层预填充期间并不会真的保留 40 个常驻专家。
服务默认监听 http://localhost:30000。启动后可以这样确认:
1 | curl http://localhost:30000/v1/models |
OpenAI 兼容端点为:
1 | http://localhost:30000/v1/chat/completions |
5. 多模态请求边界
- 一个请求可以只含文本,或文本加最多八张图片。
- 一个请求也可以是文本加一个视频。
- 图片与视频不能出现在同一个请求中。
- 视频走常规的混合预填充路径,而不是逐层预填充。解码 CUDA Graph 仍受支持。
在 AVX2 CPU 上运行 KTransformers
这篇教程讲怎么在只支持 AVX2(没有 AVX512、也没有 AMX)的机器上跑 KTransformers。
目录
- 支持的精度格式
- 硬件要求
- 安装
- 验证
- 启动推理服务
- 示例:Qwen3-30B-A3B(BF16)
- 示例:Qwen3.5-35B-A3B-FP8(FP8)
- 示例:Qwen3-30B-A3B-GPTQ-Int4(GPTQ_INT4)
- 示例:Kimi-K2.5(RAWINT4)
- 发送请求
- 性能调优
- 常见问题
支持的精度格式
--kt-method |
精度 | 说明 |
|---|---|---|
BF16 |
BF16 原生精度 | 零精度损失,直接使用 BF16 权重 |
FP8 |
FP8 block 量化 | |
GPTQ_INT4 |
INT4 GPTQ | |
RAWINT4 |
带 BF16 scale 的原始 INT4 | 由 Kimi-K2.5 使用;权重以压缩的 SafeTensor 格式存储 |
硬件要求
- CPU:x86-64 + AVX2 + FMA(Intel Haswell 2013+ / AMD Zen+)
- GPU:NVIDIA 24GB+ 显存(RTX 3090/4090/5090 等)
- 内存:至少等于模型权重大小(例如 Qwen3-30B-A3B BF16 需要 64GB+)
- 操作系统:Linux
安装
从源码构建安装(kt-kernel + SGLang 一条命令搞定):
1 | git clone https://github.com/kvcache-ai/ktransformers.git |
机器本身支持 AVX512 或 AMX 的话,也可以手动强制按 AVX2 编译:
1 | export KT_RAWINT4_BACKEND=avx2 |
验证
1 | # 检查 CPU 是否支持 AVX2 |
启动推理服务
用 --kt-method BF16、FP8、GPTQ_INT4 或 RAWINT4。AVX512/AMX 不可用时,KT-Kernel 会自己检测并退到 AVX2 后端。
示例:Qwen3-30B-A3B(BF16)
1 | # 下载模型 |
示例:Qwen3.5-35B-A3B-FP8(FP8)
1 | # 下载模型 |
示例:Qwen3-30B-A3B-GPTQ-Int4(GPTQ_INT4)
1 | # 下载模型 |
示例:Kimi-K2.5(RAWINT4)
注意:以下命令针对 4x RTX PRO 6000 Blackwell(每张 96GB)+ AMD Threadripper PRO 5995WX(64 核、1 个 NUMA 节点)+ 256GB 内存优化。
1 | # 下载模型 |
发送请求
1 | # 交互式对话 |
性能调优
--kt-cpuinfer:设为物理核心数--kt-threadpool-count:设为 NUMA 节点数--kt-num-gpu-experts:值越大 CPU 负载越低,但显存占用越高- 内存带宽往往是瓶颈;高频 DDR5 内存帮助明显
常见问题
GPU OOM
- 减小
--kt-num-gpu-experts、--chunked-prefill-size、--max-total-tokens - 降低
--mem-fraction-static
更多问题见常见问题。
常见问题
1. SGLang 启动时出现 “Using default MoE kernel config” 警告
在 SGLang 里用 kt-kernel 时,可能会看到这样的警告:
1 | [2026-05-15 20:31:38] Using default MoE kernel config. Performance might be sub-optimal! |
这条警告在预期之内,可以直接忽略。kt-kernel 用自己的 CPU/GPU 混合调度替掉了 SGLang 内置的 MoE 实现,SGLang 那套 fused-MoE Triton kernel 配置根本用不上。警告是 SGLang 在 kt-kernel 接手 MoE 之前打出来的,不影响性能,也不影响正确性。
2. 在哪里可以获得更多帮助?
可以翻一翻已有的 issue,或者新开一个。
来自: Ktransformers 官方文档