开源jeff:GLiFormer在情感分类准确率追平jev

jeff 是 TypeSafe 公司 jev System One API 的自托管(self-hosted)替代实现,基于 GLiFormer(400M 参数)模型。可以直接配合官方 typesafe-sdk 使用——只需把 TYPESAFE_BASE_URL 指向 jeff 即可。

支持的功能

  • choice:从选项中选择
  • score:在有序等级上打分
  • noul:判断"是"的概率
你只需要改一行环境变量,就能把TypeSafe的jev账单砍到原来的六分之一!

每月烧在分类API上的钱,大半都花冤枉了!

开源项目jeff用四亿参数GLiFormer在本地GPU跑文本分类,将TypeSafe的jev API成本从每百万次请求十五点六美元压到两美元六,开发者只需修改一行TYPESAFE_BASE_URL环境变量即可零代码完成替换。


一行环境变量换掉万元账单

每天有成千上万封客户邮件涌进企业的客服系统,每一封都需要被快速归类:这封邮件是在投诉账单问题,还是在询问技术故障,语气是愤怒还是平静,紧急程度是低还是高。这种把一段文字扔进预定义类别的任务,在工程上叫做文本分类,而几乎所有中大型互联网公司都在用云端API来完成这件看似简单的事情。

TypeSafe是一家专门做结构化文本分类的公司,TypeSafe旗下的jev API提供了一个叫System One的接口,开发者把一段客户留言和一组分类问题发给jev,jev就会返回结构化的答案和置信度分数。比如你发一句"我被重复扣费了,请立刻处理",同时问三个问题:这是否涉及账单,语气是什么,紧急程度如何,jev就会返回"是账单问题、语气愤怒、紧急程度高"这样的结构化结果。jev的定价大约是每百万次单问题请求十五点六美元,对于一家每月处理一千万条客服工单的中型SaaS公司来说,光是分类这一项每月就要烧掉一百五十多美元,而且这笔钱会随着业务量线性增长。

jeff是一个开源的自托管替代方案,jeff的核心思路极其直接:用一个只有四亿参数的本地模型GLiFormer替代TypeSafe云端的大模型,把每百万次请求的成本从十五点六美元压到两美元六,降幅达到六倍。更关键的是,jeff完整复刻了jev的API协议,开发者不需要改动任何业务代码,只需要把环境变量TYPESAFE_BASE_URL从TypeSafe的云端地址改成http://localhost:8000,所有原本发给jev的请求就会自动路由到本地的jeff实例上!


jev的六倍溢价到底买到了什么

要理解jeff为什么能便宜六倍,你得先搞清楚jev的定价里到底包含了什么。jev的System One API虽然定位是"快速直觉判断",但jev底层依赖的是具备复杂推理能力的大语言模型,这类模型能理解反讽、能做多步推理、能读懂长文本里的隐含意思。换句话说,你花钱雇了一个能写法律文书的博士来帮你分拣快递,博士确实能把快递分得又快又准,但你为博士的法律技能付的那部分钱,在分拣快递这个场景里完全是浪费。

benchmark数据直接印证了这一点。在AG News新闻主题分类任务上(把新闻文章归入世界、体育、商业、科技四个类别),jev的准确率达到了百分之九十点五,而jeff只有百分之七十五点五,差距高达十五个百分点。但是在二分类情感判断(正面还是负面)和情绪分类(开心、悲伤、愤怒等)这两个任务上,jeff和jev的准确率几乎持平,差距小到可以忽略不计。

这就引出了一个被大多数团队忽视的关键问题:你的实际生产流量里,到底有多少比例的任务真正需要反讽检测和长篇阅读理解?如果百分之九十的分类请求都是"这张工单是关于账单还是技术"和"这个客户是生气还是平静"这类简单模式匹配,那你为jev的推理能力支付的六倍溢价,绝大部分都打了水漂!


四亿参数的GLiFormer凭什么够用

GLiFormer是一个基于DeBERTa架构的编码器模型,总参数量大约四亿。要理解四亿参数为什么能做文本分类,你需要先分清编码器模型和解码器模型的根本区别。

解码器模型(比如GPT-4、Claude、Llama)的工作方式是逐字生成文本,每生成一个字都要回头读一遍之前生成的所有内容,这种自回归机制让解码器模型擅长推理、写作和对话,但也让解码器模型变得又慢又贵。编码器模型(比如BERT、DeBERTa、GLiFormer)的工作方式完全不同,编码器模型一次性读入整段输入文本,然后输出一个固定长度的向量表示,整个过程只需要一次前向传播,不需要逐字生成。对于文本分类这种"读一段话、贴一个标签"的任务来说,编码器模型天然就是最合适的架构,用解码器模型做分类就像用挖掘机拧螺丝,能力过剩但效率极低。

GLiFormer的具体血统来自GLiNER(通用轻量级命名实体识别模型),GLiNER的核心能力是零样本分类:你不需要为每个新任务重新训练模型,只需要在推理时把候选标签(比如"愤怒""平静""中性")和输入文本一起喂给GLiFormer,GLiFormer就能在单次前向传播中给每个标签打出一个匹配分数。这意味着jeff不需要针对你的具体业务场景做微调,GLiFormer开箱即用就能处理任意分类任务,和jev的使用方式完全一致。

四亿参数听起来比动辄几千亿参数的大语言模型小了好几个数量级,但参数量本身就是一个误导性的指标。对于分类任务来说,决定准确率的不是模型有多大,而是模型在预训练阶段见过多少标注数据、是否学会了识别你关心的那些语言模式。GLiFormer在DeBERTa-v3的基础上用大量标注数据做了分类任务的专项训练,四亿参数对于模式匹配级别的分类任务来说绰绰有余!


改一个网址就能零代码切换jev

jeff最让工程团队心动的设计,是jeff完整实现了jev的System One API线协议。jeff的接口地址是POST /v1/systemone,请求格式和jev完全一致,响应格式和jev完全一致,jeff甚至把"jev-latest"和"jev"注册为模型名称别名,这样你现有的请求体里写的model字段不需要任何修改就能被jeff正确识别。

如果你的应用已经在使用TypeSafe官方的typesafe-sdk Python包,迁移过程只需要设置两个环境变量:


TYPESAFE_API_KEY=devkey
TYPESAFE_BASE_URL=http://localhost:8000

设置完成后,你代码里每一处调用client.system_one()的地方都会自动把请求发送到本地的jeff实例,而不是TypeSafe的云端服务器。不需要改SDK,不需要写适配层,不需要fork任何代码,整个迁移过程对业务逻辑完全透明。

这种零代码迁移路径是jeff区别于所有其他自托管分类方案的核心差异。你当然可以部署Hugging Face的zero-shot-classification管线,也可以自己微调一个BERT模型来做分类,但这些方案都不说jev的线协议,你需要重写整个集成层、重新定义请求和响应的数据结构、重新处理认证和限流逻辑。jeff把这些工程成本全部归零了,你付出的迁移成本就是改一行环境变量!


准确率掉十五个点到底值不值

jeff便宜六倍、部署简单、零代码迁移,但准确率确实比jev低。在包含一千六百条标注数据、覆盖八个数据集的基准测试中,jeff和jev的表现呈现出非常清晰的分层格局。

在简单模式匹配任务上,jeff几乎追平了jev。二分类情感判断(正面vs负面)的准确率差距在两个百分点以内,情绪分类(开心、悲伤、愤怒、恐惧等)的准确率几乎完全一致。这些任务的共同特征是:分类信号集中在少数关键词和短语上,模型不需要理解上下文就能做出正确判断,比如"太棒了"几乎总是正面,"垃圾"几乎总是负面。

但是在需要理解语境的任务上,jeff的短板暴露得非常明显。AG News主题分类差距十五个百分点,反讽检测jeff大幅落后于jev,阅读理解类任务jeff的表现更是显著低于jev。这些任务的共同特征是:分类信号分散在多个句子之间,模型需要理解上下文、语气转折和隐含意义才能做出正确判断,比如"哦真是太棒了,又扣了我一次费"这句话字面上有"太棒了",但实际情感是强烈的负面。

然而大多数团队从未认真审计过自己的生产流量分布。如果你的客服工单里百分之九十都是"我的密码重置不了""请帮我查一下账单"这类意图明确的短文本,jeff在这些任务上的准确率几乎等于jev,而你为此支付的成本只有jev的六分之一。只有当你的业务场景大量涉及反讽、隐喻和长篇阅读理解时,jev的推理能力才真正值回票价!


一张L4显卡撑起每秒五十次请求

jeff的推荐部署方式是在Modal平台上使用一张Nvidia L4 GPU。Modal是一个无服务器GPU平台,开发者不需要自己买显卡、装驱动、配环境,只需要写一个Python脚本就能把jeff部署到云端GPU上,按实际使用时间计费。

jeff在L4 GPU上的实测吞吐量是每容器每秒约五十次HTTP请求,从笔记本电脑客户端测量的p50延迟是一百五十一毫秒。jeff实现这个吞吐量的核心机制是动态批处理:jeff的服务器会把五毫秒内到达的所有请求收集起来(这个等待时间通过JEFF_MAX_WAIT_MS配置),打包成一个最多包含十六条请求的批次(通过JEFF_MAX_BATCH配置),然后把整个批次一次性送进GPU做前向传播。GPU并不是在逐条处理五十个独立请求,而是在处理几个十六条一批的矩阵运算,这就是GPU并行计算的威力所在。

对于没有GPU的场景,jeff也提供了ONNX Runtime的CPU部署方案。jeff会把GLiFormer的编码器部分导出为ONNX格式并做int8量化,循环神经网络和分类头仍然留在PyTorch里运行。但实测数据显示,八核Modal CPU部署的延迟和成本反而比jev的云端API更高,所以CPU方案只是一个兜底选项,生产环境强烈建议使用GPU。在Mac电脑上,jeff会自动检测并使用MPS(Metal Performance Shaders)加速,这是苹果芯片上跑GLiFormer的最佳方式!


你的分类任务真的配得上jev吗

jeff在配置层面做了大量精细的调优,其中最值得关注的是温度校准机制。jeff默认对GLiFormer输出的原始西格玛概率施加三点二的温度缩放,这个操作会拉大高概率和低概率之间的差距,让置信度分数更具区分度。在温度为一点零时,GLiFormer输出的概率分布比较平坦,很多标签的概率都挤在零点三到零点七之间,很难用来做决策;温度拉到三点二之后,高概率标签会被推到零点九以上,低概率标签会被压到零点一以下,置信度分数才真正变得可用。

jeff还实现了一个叫noul隔离的机制。jev的原始行为是让所有分类问题共享同一次编码器前向传播,这意味着不同问题之间会互相干扰:你同时问"这是否涉及账单"和"语气是否愤怒",两个问题的注意力权重会在编码器内部互相竞争。jeff默认对noul(是否概率)类型的问题单独做一次编码器前向传播,把noul问题和choice/score问题隔离开来,避免了跨问题的注意力污染。如果你想要完全隔离(每个问题都独立编码),可以设置JEFF_ISOLATE=all,但这会让计算成本翻倍。

jeff的bench目录里自带了一套完整的评估工具,你可以用自己的标注数据集跑一遍jeff和jev的对比测试,测量准确率、校准度和延迟,用数据来决定是否切换。但benchmark数据里有一个至今未被解释的矛盾现象:jeff的noul输出(二分类是否概率)在简单任务上校准良好,置信度分数和实际准确率高度吻合,但同一个GLiFormer编码器输出的score结果(有序等级评分如低/中/高)却出现了明显的校准偏差,即使noul和score共享同一次编码器前向传播。同一个编码器、同一批输入,为什么二分类概率校准良好而有序评分却严重偏离,这个问题在jeff截至二零二六年九月十九日的最新提交中仍然悬而未决!