Skip to main content

EdgeJev

在本地跑类型化决策模型

把开源 Jev 复现转成 ONNX,量化,部署到 CPU

PyPI License Python 3.9+


EdgeJev 把 layakevPlayJev 这些开源 Jev 复现统一成一条「转换 → 量化 → 部署」的路径。跑在普通 CPU 上,一台 4 vCPU 的机器单题 15.6 ms;运行时只要 onnxruntime、tokenizers、numpy 三个包,不装 torch。

Quick start

uv tool install "edgejev[build]"
edgejev build --backend laya --out ./jev-int8
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

转换那一步需要 torch,转完就可以卸掉。之后只装 edgejev 即可运行。

Model zoo

4 vCPU Intel Xeon Cascade Lake(AVX512-VNNI)。准确率由 edgejev eval --task all --n 400 跑出, AG News 4 分类、dair-ai emotion 6 分类,各 400 条,batch=1。

后端 模型 精度 体积 单题 三题 AG News emotion 构建命令
laya mmBERT-base 322M fp32 1290 MB 32.1 ms 84.1 ms 92.8% 54.0% --precision fp32
laya mmBERT-base 322M int8 324 MB 15.6 ms 44.8 ms 91.2% 48.2% 默认
playjev Qwen3.5-0.8B VLM fp32 2214 MB 1.2 s --backend playjev
kev Qwen + LoRA 0.5B–8B 导出器开发中

同一份权重的横向参照:laya 自己公布的是 T4 GPU 上 32.8 ms、CPU 上 200–500 ms; 官方 Jev 1.13 托管 API 实测中位 314 ms(含网络往返)。

官方 API 在同样 400 条上的成绩:AG News 85.5%、emotion 61.5%(Vercel AI Gateway,原生 criteria); 88.0% / 62.7%(classifier.dev,光标签)。laya 在 AG News 上高 5–7 点,emotion 上低 8–11 点。 laya 的 README 声称 DAIR Emotion 0.595 对 Jev 0.480,这个方向在上表里没有复现出来。

与上游的一致性

--precision fp32 与上游 laya(PyTorch)逐位一致。对拍覆盖 choice / score / noul 三种原语、 中英文、字符串与 dict 状态、带描述与不带描述的 criteria:

偏差
概率 0.00000
置信度 0.000000
input_tokens 完全相同

playjev 后端没有上游数值可对,改用分布核对:五个游戏画面给出不同的 argmax 与分布形状, max(p) 落在上游公开回放的区间内(167 步真实对局,最小 0.604 / 中位 0.827 / 最大 1.000)。

怎么选精度

下表由 quant_dataset.py 跑出,两个任务都用带描述的标签、batch=16,所以数值与上面的 zoo 表 不能直接比较,但档位之间可以横向比:

精度 体积 单题 AG News emotion 说明
fp32 1290 MB 32.1 ms 92.8% 47.0% 与上游逐位一致
int8 per-tensor 324 MB 15.6 ms 90.5% 52.2% 默认
int8 per-channel 325 MB 16.7 ms 90.2% 53.0% --precision int8-pc
int8 pc + reduce_range 325 MB 16.5 ms 91.0% 54.2% 两项都接近最好
int8 混合(决策路径 fp32) 366 MB 19.2 ms 90.2% 52.8% --precision mixed
uint8 per-channel 325 MB 27.9 ms 91.0% 48.5% 见下
int8 但嵌入表保持 fp32 915 MB 23.9 ms 91.0% 51.5% 见下
int8-static 326 MB 195 ms 25.8% 29.8% 不可用,见下

几条实测结论:

动态量化的结果依赖 batch。 激活的量化 scale 在运行时按实际张量计算,padding 一变 scale 就变。 同一条输入单独跑和跟别人一批跑,logits 最大差 2.43;fp32 ONNX 同样对比是 0.000。 Agent.system_one 是单请求路径,zoo 表的数字不受影响;自己写批量推理的固定 batch=1 或用 fp32。 edgejev build 会检查这一项并在不满足时警告。

int8-static 目前不能用。 它做到了批次无关(漂移 0.0e+00),但 MinMax 标定下精度掉到随机水平, 而且比动态量化慢约 4 倍。入口保留着,等换 Percentile 或 Entropy 标定。

QUInt8 没有理由选。 同样 8 bit、同样体积,x86 的 AVX512-VNNI 只对有符号 int8 有快路径。 ARM 走 SDOT,这一条不适用。

把嵌入表排除在量化之外没有收益。 322M 参数里 196.6M 是 256k 词表的嵌入表,看上去像精度损失的大头, 但保留它精度并不回升,体积从 324 MB 涨到 915 MB。

fp16 在 x86 CPU 上没有意义。 没有 avx512_fp16,ONNX Runtime 的 CPU EP 会转回 fp32 计算; 另外 onnxconverter_common 的 fp16 pass 处理不了 dynamo 导出图里的 _to_copy 节点,转出来加载失败。

起一个官方协议的服务

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 把代码写完再换本地。

CLI

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

后端

开源 Jev 复现的序列构造、注意力、读出方式各不相同。EdgeJev 把共性放进 edgejev/core/, 一个后端只声明四个维度:

SPEC = BackendSpec(
    name="kev",
    layout="packed_branches",
    attention="block_causal",
    readout="model_logits",
    runtime="onnx",
)
后端 布局 注意力 读出 运行时
laya 每题一行,[MASK] 标记位 bidirectional 打分头随模型进图 ONNX
kev 多题打包一条序列 block-causal + 选项隔离 PointerHead ONNX
playjev 画面 + 字母清单 causal 词表字母槽 torch

渲染、掩码、温度标定、置信度、答案组装都在 core 共用。laya.py 17 行、kev.py 20 行、playjev.py 32 行。

playjev 走 torch 而不是 ONNX:Qwen3.5 的文本塔是混合线性注意力,linear_attention 层依赖 causal_conv1d 和 flash-linear-attention 的递归状态核,没有对应的 ONNX 算子。

安装

uv tool install edgejev              # 全局命令
uv add edgejev                       # 或加进项目,跑的时候 uv run edgejev
uvx --from edgejev edgejev info      # 或临时跑一次
extra 什么时候需要
edgejev[build] edgejev build,需要 torch / transformers / laya
edgejev[vlm] playjev 后端,需要 torch / torchvision / pillow
edgejev[train] edgejev.train 训练模块

平台

平台 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 — 硬标签与软标签统一成目标分布。
  • model.py — 任意 HF 编码器 + 两层 transformer head + 标记位打分头,训完可被 edgejev build --backend laya 导出。

Acknowledgements

License

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

Release files for edgejev 0.2.1

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.1
File Size Uploaded
edgejev-0.2.1.tar.gz 40.1 kB Details

Built distribution (wheel)

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

Total release size: 84.7 kB

Release files / edgejev-0.2.1.tar.gz

Download URL edgejev-0.2.1.tar.gz
Size 40.1 kB
Tags Source
SHA-256 checksum
How to use checksums
1cdadab7b916127a2b682be7f313077573891679d92d57d0dfd3319cac5c9c51
BLAKE2b-256 checksum
How to use checksums
e3d12793ef91c6a78589d5f6b416e59caae6f48fafce4f8d29787677ac1c55c8
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.1-py3-none-any.whl

Download URL edgejev-0.2.1-py3-none-any.whl
Size 44.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
24d51765226a7b21915e6cdc174a462205838f2b338ee1af05a8af92490ac0ef
BLAKE2b-256 checksum
How to use checksums
c3a8cdd326ab6aaa47486d3a5d4e3efe53514eabdca3720c6c7e5a8278fa804e
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

This release

0.2.1 This release

2 release files

0.2.0

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