自适应推理压缩 + 思考预算分配框架 —— 把「少想一点,还能答对」做成一套能跑、能训、能上线的完整工程。
TRAAC(Think Right with Adaptive, Attentive Compression)是微软研究院 2026-10-02 开源的一类推理效率方法:用强化学习找出「哪些推理步骤真正有用」,剪掉冗余步骤,再按任务难度动态分配「思考预算」。论文在 Qwen3-4B 上报告 +8.4% 精度、-36.8% 推理长度。本项目把它从一篇论文,落地成一个零依赖、可训练、带五后端、带 OpenAI 兼容 HTTP 服务、带 Docker/K8s/Helm/CI 的完整框架。
推理模型(o 系列、R1 类)为了答对一道题,会吐出一长串中间步骤。这串步骤里,大部分是冗余的:
- 有的步骤只是「把题目复述一遍」;
- 有的步骤是「试探性的、后来被推翻的」;
- 真正决定答案的,往往只有一条关键链(critical path)。
TRAAC 的思路很直接:与其每道题都花满 max_tokens,不如先判断这道题值多少思考量,再只保留关键步骤。省下来的 token 就是省下来的钱和延迟——而因为冗余步骤往往也是「噪声来源」,剪掉它们有时反而更准。
把「最终答案状态」当成 query,把每个中间步骤的隐状态当成 key/value,做一次 scaled dot-product attention:
attention(query=answer_state, keys=step_embeddings)
-> 每个步骤得到一个重要性权重
权重高的步骤 = 答案真正「关注」的步骤 = 关键链。这个权重就是剪枝依据。
对步骤重要性做软阈值过滤,同时挂两条护栏:
- 硬预算:来自预算分配器,限制最多保留多少 token;
- 安全地板(
min_keep_ratio):永远保留最低比例的步骤,防止把整条推理链剪空。
规则化特征(词数 / 数字密度 / 疑问词)先估一道题的难度 d ∈ [0,1],再线性映射到思考预算:
budget = base_tokens + difficulty_gain * d # 难的多想,容易的少想
这就是「动态算力」:同一套模型,简单题秒回、难题充分思考,而不是一律 max_tokens。
奖励函数是一行:
reward = accuracy - λ · length_ratio
accuracy 拉高正确率,length_ratio 拉低推理长度,λ 是二者张力。GRPO 用「组内相对优势」更新剪枝策略——这就是论文里「精度不降反升、长度大幅缩短」的来源。
def compute_reward(correct, length_ratio, length_penalty=0.5):
return (1.0 if correct else 0.0) - length_penalty * length_ratio任何「既要质量又要省算力」的场景(摘要、翻译、代码补全)都能套这个奖励形状,只要把
length_ratio换成你自己的成本度量。
要让训练真的起作用,Mock 后端的步骤重要性必须真正参与打分,且训练信号要单调:
importance = skill * is_critical + (1.0 - skill) * noise # noise ∈ [-0.5, 0.5]skill低 → 重要性接近噪声 → 压缩器留错步骤、丢关键步骤 → 准确率≈随机;skill→ 1.0 → 重要性 = 关键性 → 精确剪枝,准确率 1.0、长度最短。
训练时 skill 单调爬向 1.0(别用「对+1 错-1」的对称更新,会把 skill 压到 0)。
def _seed(key):
return int.from_bytes(hashlib.md5(str(key).encode()).digest()[:8], "big")别平铺 16 字节 digest——那样只有 2 个不同值周期重复、熵极低;前 8 字节做种子驱动 random.Random,又快又足。
托管 Python 可能没装 pyyaml。框架内置一个极简 YAML 子集解析器(traacforge/utils/yamlish.py),config.py 在 import yaml 失败时自动回退——生产环境少一个依赖就是少一个故障点。
# 1. 零依赖,直接跑(无需安装任何包)
python -m traacforge doctor # 体检:五后端 + 组件 + 基准
# 2. 压缩一条推理链
python -m traacforge compress "A train goes 60 km/h for 2.5 hours, then 80 km/h for 1.5 hours. How far?"
# 3. RL 训练压缩策略(看精度↑、长度↓)
python -m traacforge train
# 4. 跑基准
python -m traacforge evaluate
# 5. 起 OpenAI 兼容服务
python -m traacforge serve --host 127.0.0.1 --port 8000
curl http://127.0.0.1:8000/v1/chat/completions -H "Content-Type: application/json" -d '{"messages":[{"role":"user","content":"What is 3 + 4?"}],"reasoning_effort":"low"}'| 阶段 | skill | 准确率 | 长度占比(相对完整链) |
|---|---|---|---|
| 未训练压缩 | 0.50 | ~0.81 | ~0.22(误删关键步 → 答错) |
| 训练后压缩 | 1.00 | 1.00 | ~0.33 → 缩减 67% |
完整推理链长度 = 1.0。训练后的压缩策略把长度砍到 33%(缩减 67%),同时把被误删导致的准确率损失从 0.81 完全拉回 1.00。这就是「剪掉噪声、只留关键链」的核心收益。
traacforge/
├── core/ # 零依赖张量内核(tensor / ops / attention / nn)
├── reasoning/ # 推理链建模 + 注意力打分 + 自适应压缩
├── budget/ # 难度估计 + 预算分配 + 预算策略
├── model/ # 骨架 + 步骤打分头 + 主引擎
├── backends/ # mock(可训练) / cpu / openai / vllm / transformers
├── train/ # 奖励 + GRPO/PPO + 语料 + 训练器
├── bench/ # gsm8k / math / compression 基准
├── serving/ # OpenAI 兼容 stdlib HTTP 服务
├── cli/ # doctor / compress / train / evaluate / serve / budget
├── configs/ # default / traac-large / traac-flash
├── examples/ # 6 个可直接运行的演示
└── tests/ # 单元测试(unittest,无需 pytest)
| 后端 | 依赖 | 用途 |
|---|---|---|
mock |
无 | 确定性、可训练,跑通全流程 + RL 演示 |
cpu |
无 | 真实注意力打分,零依赖 CPU 推理 |
openai |
无(urllib) | 接任意 OpenAI 兼容网关 |
vllm |
vllm 服务 | 生产级批量推理 |
transformers |
torch+transformers | 进程内 HF 模型 |
docker build -f deploy/Dockerfile -t traacforge .
docker run -p 8000:8000 traacforge
# 或 K8s / Helm
helm install traacforge deploy/helm/traacforgeMIT。更多技术细节见 docs/。