Skip to main content

EdgeJev

在自己的机器上跑类型化决策模型。4 核 CPU 单题 15.6 ms,比官方托管 API 快 20 倍。

PyPI License

from edgejev import Agent

ag = Agent("./jev-int8")
r = ag.system_one("我的信用卡被扣了两次款,麻烦退一笔。", {
    "dept":   {"type": "choice", "instructions": "该转给哪个组?",
               "criteria": {"billing": "支付、扣款、发票、退款",
                            "technical": "程序缺陷、报错",
                            "sales": "售前咨询、定价"}},
    "urgent": {"type": "noul",  "instructions": "这条消息表达了紧急或时间压力"},
    "anger":  {"type": "score", "instructions": "客户的不满程度",
               "criteria": ["平静陈述", "有情绪但讲道理", "非常愤怒"]},
})

r["answers"]["dept"]["choice"]          # 'billing'
r["answers"]["dept"]["probabilities"]   # {'billing': 0.92, 'technical': 0.08, 'sales': 0.00}
r["answers"]["anger"]["confidence"]     # 0.41 —— 置信度低,这条不要自动执行

为什么需要它

Jev 这类 System One 模型不生成文本。给一份 state 和几个带类型的问题, 一次前向答完,返回能直接 if 的值加一个校准概率。

它的用武之地是高频、低延迟、结果要落进代码分支的地方:Agent 每一步选哪个工具、 语音对话里要不要打断、请求入口的路由和内容护栏。这些场景的共同点是——决策层的延迟预算只有几十毫秒, 而且往往一轮要问好几个问题。

在这个预算下,现成的三条路都不够用:

  • 官方托管 API 每次决策一个网络往返。实测中位 314 ms,光这一项就吃掉整个预算。还要排 waitlist、绑信用卡,数据出内网。
  • 开源复现(laya、kev 等)权重是开放的,但都绑着 PyTorch,公布的延迟按 GPU 标。laya 自己的提示里写着 CPU 上 ~200-500 ms
  • 自己转 ONNX 听着简单,实际每家的序列构造、注意力掩码、读出方式都不一样,量化还有一串反直觉的坑(见限制)。

EdgeJev 把这条路铺平:一条命令转换 + 量化,一条命令起服务,运行时不依赖 torch。

快在哪

速度不来自更聪明的模型——跑的是同一份权重。省掉的是两样东西:

网络往返。 官方 API 实测中位 314 ms,真正的推理只占其中一小部分,其余是链路。本地跑直接归零。

框架与精度开销。 PyTorch → ONNX Runtime 的图优化拿到 1.7x;再上 INT8(走 x86 的 AVX512-VNNI 整数乘加)又拿到 1.2x。叠起来 2.06x,模型同时从 1290 MB 缩到 324 MB。

结果是决策层从 314 ms 压到 15.6 ms——这才塞得进语音对话那种 50–150 ms 的预算,也才谈得上「一轮问四个问题」。

EdgeJev(本地 int8) 原项目 laya(PyTorch) 官方 Jev 1.13 API
单题延迟 15.6 ms 32.8 ms(T4 GPU)
200–500 ms(自述 CPU)
314 ms(含网络)
三题一次请求 44.8 ms 314 ms(多题可并行)
模型体积 324 MB 1290 MB
运行时依赖 onnxruntime + tokenizers + numpy torch + transformers HTTP
每次调用成本 0 0 $0.042 / MTok 输入
准入门槛 waitlist / 绑卡
数据位置 本机 本机 出内网
离线可用

准确率

AG News(4 分类)与 dair-ai emotion(6 分类),各 400 条,edgejev eval 可复现:

AG News emotion
EdgeJev fp32 92.8% 54.0%
EdgeJev int8 91.0% 50.0%
官方 Jev 1.13(Vercel AI Gateway) 85.5% 61.5%
官方 Jev 1.13(classifier.dev) 88.0% 62.7%

两件需要摆明的事:

精度损失来自量化,不来自转换。 --precision fp32 与上游 PyTorch 逐位一致(最大概率偏差 0.00000, 覆盖三种原语、中英文、字符串与 dict 状态)。INT8 的代价是 AG News −1.8 点、emotion −4 点。要精度就用 fp32, 它依然比官方 API 快一个数量级。

开源模型不是全面胜过官方。 laya 在 AG News 上高 5–7 点,但在 emotion 上低 8–11 点。 laya 的 README 声称「DAIR Emotion 0.595 对 Jev 0.480」——各 400 条复现下来方向相反。 细粒度情绪分类这类任务,选型前必须在自己的数据上量一遍。

安装

uv

uv tool install edgejev              # 装成全局命令
uv add edgejev                       # 或加进当前项目(跑的时候 uv run edgejev)
uvx --from edgejev edgejev info      # 或临时跑一次,不装

不加 extra 时运行时只有 onnxruntime + tokenizers + numpy。按需加:

uv tool install "edgejev[build]"     # edgejev build 转 ONNX:torch / transformers / laya
uv tool install "edgejev[vlm]"       # playjev 视觉后端:torch / torchvision / pillow
uv add "edgejev[train]"              # 训练模块

没装 uv:curl -LsSf https://astral.sh/uv/install.sh | sh

上手

uv tool install "edgejev[build]"
edgejev build --backend laya --out ./jev-int8    # 转换 + 量化 + 多形状自检

然后就不再需要 torch 了,直接 Agent("./jev-int8")(见开头的例子),或者起一个官方协议的端点:

edgejev serve --model ./jev-int8 --port 8009
export TYPESAFE_BASE_URL=http://127.0.0.1:8009
export TYPESAFE_API_KEY=local

官方 SDK 改个 base_url 就切过来了——先用官方 API 把代码写完,再无痛换本地

命令 作用
edgejev build checkpoint → ONNX → 量化 → 多形状自检
edgejev serve POST /v1/systemone,官方协议兼容
edgejev eval AG News / emotion 上跑指标
edgejev bench 测延迟
edgejev info provider 与已注册后端

后端

开源 Jev 复现有十几家,序列构造、注意力、读出方式各不相同。EdgeJev 没有为每家抄一份适配器, 而是把它们的共性抽成四个维度,一个后端就是一份声明:

SPEC = BackendSpec(
    name="kev",
    layout="packed_branches",      # 多题打包一条序列
    attention="block_causal",      # 问题之间互相看不见
    readout="model_logits",        # 打分头随模型导进 ONNX
    runtime="onnx",
)
后端 骨干 布局 读出 运行时
laya mmBERT-base 322M 每题一行,[MASK] 标记位 打分头 ONNX
kev Qwen + LoRA 0.5B–8B 多题打包,block-causal PointerHead ONNX
playjev Qwen3.5-0.8B VLM 画面 + 字母清单 词表字母槽 torch

渲染带类型的问题、构造掩码、温度标定、置信度、组装答案都在 edgejev/core/ 里共用, 一处修复全体受益。加一个后端通常只要填这张表。

playjev 走 torch 而不是 ONNX:Qwen3.5 的文本塔是混合线性注意力,linear_attention 层依赖 causal_conv1d / flash-linear-attention 的递归状态核,没有对应的 ONNX 算子。 用它只统一 API 和 serve,拿不到量化加速。

限制

动态量化的结果依赖 batch。 激活的量化 scale 在运行时按实际张量算,padding 变了 scale 就变, 同一条输入跟谁同批会影响它的答案(实测 logits 最大差 2.43;fp32 是 0.000)。 Agent.system_one 是单请求路径,上面的指标不受影响;自己写批量推理的固定 batch=1 或用 fp32edgejev build 会检查这一项并在不满足时警告。

--precision int8-static 目前不可用。 它能做到批次无关,但 MinMax 标定下精度掉到随机水平 (AG News 25.8%,随机基线 25%),且比动态量化慢 4 倍。保留入口是为了后续换 Percentile / Entropy 标定。

不要用 QUInt8。 同样 8 bit、同样体积,但 x86 的 VNNI 只对有符号 int8 有快路径: QUInt8 27.9 ms vs QInt8 15.6 ms。ARM 走 SDOT,不适用此条。

fp16 在 x86 CPU 上没有意义。 没有 avx512_fp16,ONNX Runtime 的 CPU EP 会转回 fp32 算。

保留嵌入表不量化不划算。 322M 里 196.6M 是 256k 词表的嵌入表,看着像精度损失的大头, 但保留它精度并不回升(91.0% / 51.5%),体积却从 324 MB 涨到 915 MB。

平台

平台 Execution Provider
Linux / Windows x86 CPU(AVX512-VNNI / AVX2)
macOS Apple Silicon CoreML,不支持的算子回退 CPU
Linux ARM CPU(int8 走 SDOT)

edgejev info 看实际选用的;--provider cpuEDGEJEV_PROVIDER=cpu 强制。

训练自己的模型

edgejev.train 与推理共用同一个渲染器,训练序列和线上请求逐 token 相同。

  • losses.py —— 严格恰当评分规则(log score + spherical,score 型加 ranked probability score)。 优化的是概率校准而不是 argmax 正确:只有如实报告信念才能取得最优期望得分。另含 ECE 与可靠性分桶。
  • data.py —— 硬标签与软标签统一成目标分布。软标签(多人标注分歧、teacher 概率)是拿到好校准的关键。
  • model.py —— 任意 HF 编码器 + 两层 transformer head + 标记位打分头,训完直接能被 edgejev build --backend laya 导出。

许可

Apache-2.0。权重与 tokenizer 的许可归上游 layammBERTkevPlayJev 所有。本项目与 TypeSafe AI 无隶属关系。

Release files for edgejev 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for edgejev 0.2.0
File Size Uploaded
edgejev-0.2.0.tar.gz 41.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for edgejev 0.2.0
File Interpreter ABI Platform
edgejev-0.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 86.4 kB

Release files / edgejev-0.2.0.tar.gz

Download URL edgejev-0.2.0.tar.gz
Size 41.2 kB
Tags Source
SHA-256 checksum
How to use checksums
82df0b747fc057638dd730a2c3952ee6c3ca5d524fe94f42400516f722d45f3b
BLAKE2b-256 checksum
How to use checksums
afa5caa620053edff465749dd5192ccec2f9697f0e245eb768b4d3c9c97e048d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.3

Release files / edgejev-0.2.0-py3-none-any.whl

Download URL edgejev-0.2.0-py3-none-any.whl
Size 45.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
0c42aa21f237fffeb8395c137bfb966295e196ebdc26fefe72f854fefa4ce054
BLAKE2b-256 checksum
How to use checksums
db11ef0a3ac1d048e1380050e3d76d0bdf9603f4956341cf021be27fe1d3fbad
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.3

Release history Release notifications | RSS feed

0.2.1

2 release files

This release

0.2.0 This release

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page