逆向工程的 Jev 类模型
Reverse-engineered Jev-like model

原始链接: https://github.com/vinnylarouge/jevlike

本仓库提供了一个独立的开源“入门级” Jev 类模型实现。该模型执行单次分类,从动态文本选项列表中进行选择,而非逐个生成文本标记(token)。这种方法比传统的自回归解码速度快得多。 该模型通过将选项转换为关注上下文标记的查询向量来运作,并使用共享的点积来计算分数。用户可以使用默认的字节级编码器从头开始训练,也可以利用冻结的预训练 Hugging Face 模型以获得更好的语言理解能力。该系统包含用于训练、评估和可视化的工具,示例展示了其在多种任务中的通用性,例如《毁灭战士》(Doom)和国际象棋的游戏控制器映射,以及 Wikispeedia 中的链接预测。 性能在很大程度上取决于数据质量和编码器的选择;实验表明,该模型在保持高计算效率的同时,能够有效地优于随机对照组。此研究工具基于 MIT 许可证发布,专为可以在单次前向传播中对固定结果集进行评分的任务而设计。

这篇 Hacker News 讨论帖探讨了“类 Jev”模型(Jev-like models)的兴起——这是一种绕过逐词生成文本的推理新方法。这些模型接收一段文本和一组选项,并在单次处理中直接返回每个选项的概率权重。 支持者认为,这种方法在分类、决策和路由任务中非常高效,其运作更像是自动化的“系统 1”处理器,而非对话式聊天机器人。文中提到的应用示例包括游戏智能体(如玩《毁灭战士》)和快速 JSON 验证。 然而,对于该模型的可靠性仍存在质疑。一些用户指出,演示结果显示其表现不稳定,且空间推理能力有限。虽然有人认为小参数模型(如 1B 参数版本)不足以处理复杂任务,但另一些人则认为,对于确定性工作流(例如替代正则表达式或过滤噪声),并不需要高阶知识。参与者还讨论了相比新版本,人们更倾向于使用 Qwen 2.5 等旧版稳定模型,这往往是因为它们在定制推理管道中表现更好。归根结底,社区认为“类 Jev”架构是一个尚未被充分挖掘、在低延迟专用 AI 应用领域具有高潜力的方向。
相关文章

原文

Train a small model that chooses among a changing list of text options.

A Jev-like model takes a piece of text and a list of N text options. It returns one probability for each option. It does this in one pass instead of writing an answer word by word. Jev is TypeSafe's commercial model for this kind of task. TypeSafe has not published its design. This repository is an independent starter model with the same input and output shape.

The same option-attention head can score controller buttons from image patches. This ten-second film joins two selected five-second windows: live deadly_corridor combat on the seven Doom buttons, then a chess controller walking to and playing moves with five keys. The diagram shows the tensors used for each decision. The Doom window came from the supplied joint checkpoint, which averaged 0.60 kills and -97.50 reward across its ten recorded episodes. The chess window came from the stronger chess-only checkpoint, which scored 4 wins, 46 draws and 0 losses in 50 sampled games against a random mover, but 0 wins, 2 draws and 48 losses against Stockfish level 0. The windows were selected for activity and are not typical-play or competence claims.

Install the game extras and record a fresh 640 by 480 Doom trace from the released joint checkpoint:

uv pip install -e '.[games]'
python examples/doom/play.py examples/checkpoints/joint-imitation.pt --episodes 10 --game-seconds 35.3 --device cpu --capture-resolution 640x480 --output runs/doom.mp4 --trace runs/doom-trace.json

Render the trace in the same visual layout. This writes a silent film because the author-owned soundtrack source is not part of the repository.

(cd examples/film && npm install && npx playwright install chromium)
examples/film/make-film.sh runs/doom-trace.json runs/doom-film.mp4 10

The release includes the Doom example, the chess example, the single-game checkpoints and the shared 12-option checkpoint. Both games import the visual scorer from jevlike.vision; there is no second model copy in either example.

Each option becomes a query vector, which is a short list of numbers representing its text. The query assigns attention weights to the context tokens. Those weights make one context vector for that option. A shared dot product turns each option and context pair into one score. A softmax, which converts scores into probabilities that sum to one, runs across the options.

Each option queries the context, receives an attended context vector, and becomes one probability.

The default encoder learns byte embeddings from scratch. An encoder is the part that turns text into vectors. The optional Hugging Face path uses a frozen pretrained encoder, whose existing weights stay fixed while the small scorer learns.

Use one JSON object per line:

{"context":"The customer needs a refund.","options":["refund","sales","technical support"],"label":0}

label is the zero-based index of the correct option. Each row may have a different number of options, with a minimum of two.

Run these commands from the repository root. They create local synthetic data, train on it, evaluate the saved model and score one new menu.

uv venv
source .venv/bin/activate
uv pip install -e '.[dev]'

jevlike-data synthetic --output data/synthetic
jevlike-train data/synthetic/train.jsonl \
  --validation data/synthetic/validation.jsonl \
  --output runs/synthetic.pt
jevlike-eval runs/synthetic.pt data/synthetic/test.jsonl
jevlike-predict runs/synthetic.pt \
  --context "Choose the exact badge amber badger. Badge: amber badger." \
  --option "azure crane" \
  --option "amber badger" \
  --option "gold heron"

The evaluation prints top-1 accuracy, which is the fraction of correct first choices. Top-3 accuracy is the fraction with the right answer among the three highest scores. Expected calibration error compares confidence with observed accuracy. The command also prints a shuffled-context control, which pairs each menu with the wrong context. A useful model should beat that control.

  1. Export train, validation and test JSONL files in the format above.
  2. Keep all options that the model will see at prediction time in each row.
  3. Split related records together. For example, keep all records for one customer or one target page in one split. This prevents near-duplicates from leaking into the test set.
  4. Run jevlike-train with your train and validation files.
  5. Run jevlike-eval once on the held-out test file. Held-out means the file was never used for training or model selection.

The default byte encoder truncates context to 192 bytes and each option to 32 bytes. Raise --context-tokens or --option-tokens when your text needs more room. Training supports CPU, Apple MPS for a Mac GPU, and CUDA for an NVIDIA GPU through --device.

Use a frozen pretrained encoder

Install the optional dependency and name any compatible encoder from Hugging Face:

uv pip install -e '.[transformers]'
jevlike-train data/synthetic/train.jsonl \
  --validation data/synthetic/validation.jsonl \
  --output runs/qwen-head.pt \
  --encoder hf \
  --hf-model Qwen/Qwen2.5-0.5B \
  --rank 256 \
  --batch-size 8

The checkpoint stores the trained scorer head and the encoder name. It does not copy the frozen encoder weights. Loading the checkpoint therefore needs access to the same Hugging Face model.

--rank sets the width of the small scorer head. A wider head has more trainable weights and uses more memory.

scripts/get_wikispeedia.sh downloads the public SNAP archives and builds next-click JSONL files. The data stay outside this repository.

scripts/get_wikispeedia.sh
jevlike-train data/wikispeedia/jsonl/train.jsonl \
  --validation data/wikispeedia/jsonl/validation.jsonl \
  --output runs/wikispeedia.pt

Cite Robert West and Jure Leskovec, Human Wayfinding in Information Networks, WWW 2012. Review the source data terms on the SNAP dataset page.

In the experiments that led to this starter, the one-pass scorer reached about 98% accuracy on synthetic menus. On target-disjoint Wikispeedia next-click data, a frozen Qwen2.5-0.5B encoder plus the scorer reached 26%, against about 8% for shuffled and random-encoder controls. A small model trained from scratch on 40,000 clicks reached 29%. At eight options, one pass was about 100 times faster than a small decoder forced to write 400 tokens.

These numbers describe local experiments, not this quickstart run. We did not show equal quality with Jev or reproduce TypeSafe's private training method.

  • This is a research starter, not a copy of Jev.
  • Accuracy depends on data quality, split quality and the encoder.
  • The byte encoder is cheap but weak on language meaning.
  • The pretrained path may download a large model and needs more memory.
  • One-pass scoring requires the complete option list before prediction.
  • The speed comparison used a small local decoder rather than a large commercial model.

Code is released under the MIT License. Downloaded datasets and pretrained models keep their own terms.

联系我们 contact @ memedata.com