让 AI 做决策提速 9 倍,开源 CLM 的 3 个坑先看清

现在让大模型干活,常见做法是让它一步步推理、边想边写。方向没错,代价也实在:一次决策动辄几百毫秒,智能体跑一轮下来,时间全花在"想"上面。

有个新路子反着来:不让它生成,只让它挑。CLM(Contrastive Language Models,对比式语言模型)干的就是这个活——把"当前处境"和"能做的动作"各压成一个向量,比一比谁跟谁最般配,直接选分最高的那个。从写字变成打分,速度自然不是一个量级。

这套东西最近刚开源,仓库星标已经涨到 1796,代码、权重、微调脚本全在里头。

一句话讲清它在做什么

训练时,用对比学习把两件事绑到一块:同一个处境下真正发生过的那个动作,向量要挨得近;没发生过的动作,向量一律推远。

用的时候,把当前处境和一堆候选动作各过一遍编码器,做个内积,谁分高就选谁。softmax 出来的那组概率,就是答案分布。

因为是打分而不是续写,它天生带举一反三的本事:一套权重在电脑操作、打游戏、调工具这些完全不同的任务上都能直接用,不用针对每个任务重新调一遍。

三种问法,够覆盖大部分决策需求

from clm import CLMClient, Choice, Noul, Score

client = CLMClient()
r = client.system_one(
    state="客户:我的账单被重复扣款了,电话也没人接!",
    questions={
        "urgency": Noul(instructions="这事儿急不急?"),
        "department": Choice(instructions="该转给哪个组?",
                             criteria={"billing": "扣款、发票、退款",
                                       "technical": "故障、宕机"}),
        "frustration": Score(instructions="客户有多上火?",
                             criteria=["平静", "有点急", "非常生气"]),
    },
)
print(r.answers["urgency"].noul)             # 0.41022   这句话成立的概率
print(r.answers["department"].choice)        # billing
print(r.answers["department"].probabilities) # {'billing': 0.93878, 'technical': 0.06122}
print(r.answers["frustration"].score)        # 1.98386   期望等级,0 到 2
print(r.usage.input_tokens, r.latency_ms)    # 38 58.1

整套东西其实建立在一个更基础的能力上:给一个处境和一堆候选项打分排序。想直接用这一层,也留了入口:

from clm import Engine

engine = Engine(emb_url="http://127.0.0.1:8090/v1/embeddings")
engine.rank("地球上为什么会涨潮?",
            ["月球的引力。", "植物的光合作用。", "因为地球是圆的。"])
# [{'rank': 1, 'candidate': "月球的引力。", 'prob': 0.997}, ...]

起服务就两步

pip install contrastive-lm

# 1. 编码器(Qwen3-8B 出向量)
vllm serve Qwen/Qwen3-8B --served-model-name qwen3-8b --runner pooling --max-model-len 2048 --port 8090 &

# 2. CLM 服务,跑在 8700 端口(首次启动会下 75 MB 的参考头)
clm-serve

不想写代码也有图形界面

clm-serve 顺带带了个网页版工作台。左边写当前处境,右边加几个带类型的问题,答案分布直接画出来;每次请求还会把对应的 JSON、curl 和 Python 三种写法一并展示,方便照抄。另有一个排序页签,能拿任意一组候选项排个先后,链接还能分享出去。

成绩单:跟同级模型打个平手,快 9 倍

在电脑操作、游戏、工具调用这几类任务上,CLM-8B 的表现跟对照模型 Jev 基本齐平,延迟却低了最多 9 倍。候选动作越多(比如网页竞速),或者动作在不同处境间反复复用(比如跑酷小游戏),提速越明显。跑酷那套测试就放在仓库里,能自己复现。

更有意思的是拿它当"裁判"。每个任务先采样出好几份候选解法(DeepSWE 用 Opus 5 采样,Terminal-Bench 2.1 用 Fable 5 采样),再让 CLM 或者 Jev 从中挑出最靠谱的那份。在 38 道留出的 DeepSWE 任务和 30 道留出的 Terminal-Bench 2.1 任务上,Jev 面对这种长链条任务根本当不了裁判,成绩还不如 pass@1;CLM 轻量微调之后,两个榜分别做到 81.6% 和 87.6%,刷新了当前最好成绩,同时比 Jev 快 4.1 到 5.7 倍。

快的底气:状态和动作分开算

关键点在于两个编码器是拆开的,向量能各自缓存、各自复用。智能体每次问的处境在变,可候选动作基本是那老几套,而且经常回访见过的处境。既然头没换,这些向量就不会变,服务启动时干脆像 vLLM 占显存那样,先划出一块地专门放它们。

命中缓存之后,编码器调用、数据拷贝、前向计算三样全省。单张 RTX 4090 上实测的服务端 p50:候选动作 50 个时,全新处境 28.8 毫秒降到 28.1 毫秒;回访过的处境 2.0 毫秒降到 0.7 毫秒。会来回走老路的循环大约快 2.8 倍,一路只见新处境的循环,编码器那份开销省不掉。

三段式训练,越往后越难

  1. 预训练:约 6000 万条问答对,问题当处境,答案当动作,先把语义底子打扎实
  2. 中期训练:约 3000 万条合成硬负样本,由 Gemini 2.5 Flash-Lite 造出来——看着像那么回事、其实答错的答案,掺进损失里练细微分辨力。千淘万漉虽辛苦,吹尽狂沙始到金,这一步淘的就是这种"差一点就对"的货
  3. 后训练:约 100 万条智能体轨迹,每一步都是"当时看到什么"配"当时决定做什么"

后训练那一步还掺了 40% 的问答回放。加了回放,硬负样本 top-1 准确率只从 69% 掉到 68.5%;要是光拿智能体数据训同样多步,直接掉到 56.2%。

那为什么不从一开始就上硬负样本? 在约 10 万道留出题上(每道 1 个正确答案、10 个硬负样本)实测:只做预训练,top-1 有 52.1%;补一段中期训练,升到 69.2%。而一上来就掺硬负样本,前期涨得飞快,到 62.4% 就见顶过拟合了。拔苗助长,说的就是这种情况——同等算力下,两阶段做法高出 7 个百分点。硬负样本适合当精修,不适合当主食。

缩放规律也给了条实用经验:固定算力下,最优头规模几乎随训练 token 数线性增长,比例大约 310 个 token 配 1 个参数。要把验证能力往上推,编码器规模是最划算的那个维度。

上手前先看这 3 处

下面这几处前人踩过,算是前车之鉴,动手前心里有个数:

  1. 状态超过 2048 token 会被截断。想放开就得两头一起抬:vllm serve 那边 --max-model-len 8192,clm-serve 这边 --max-tokens 8192,显存消耗跟着往上走
  2. 头不能随便换。只有在同一个编码器、同一种池化方式下训出来的头才配得上,换个 backbone 等于白练;换头时记得服务会自动热加载,别一边跑一边改文件
  3. `--cors` 默认是关的。一旦打开,任何网页都能朝你的服务发请求,而 API key 就放在请求头里,等于把钥匙递出去。要开,先想清楚服务暴露在什么环境

想拿自己的数据微调,仓库里有现成脚本和文档,一条命令就能复现 DeepSWE 那组结果。

总的来说,如果你手上的智能体卡在"每次决策都要想半天",这套方案值得一试:装上、起服务、把问题换成带类型的问法,剩下的交给打分。

原文链接:
https://github.com/Contrastive-LM/CLM

仓库地址:
github.com/Contrastive-LM/CLM

展开阅读全文

更新时间:2026-10-10

标签:科技   处境   编码器   动作   向量   样本   概率   智能   模型   答案   权重

1 2 3 4 5

上滑加载更多 ↓
推荐阅读:
友情链接:
更多:

本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828  

© CopyRight All Rights Reserved.
Powered By 61893.com 闽ICP备11008920号
闽公网安备35020302035593号

Top