openjev — Qwen3.5 trained as jev model
100
33 commits
updated Sep 17, 2026

Bigger jev: Qwen3.5-35B-A3B (MoE) as the backbone. Zero-shot, and with the backbone frozen plus a small MLP head on the
last-token latent (mlp_heads_35b/, one head per task, loadable with LatentMLPHead.load):

openjev is Qwen3.5 turned into a jev model: a single cross-encoder that reads a premise and a hypothesis and answers with entailment, contradiction or neutral. That one primitive is enough to rerank answers, grade them against a reference, guard content, and play games in real time: hand it the game state and a few statements about it, and the argmax entailment is the move. Doom above is played zero-shot, first from the text state and then straight from the pixels through the Qwen3.5 vision tower. Nothing is trained per task.
qwen3.5-4b-nli/ — the 4B jev checkpoint (Qwen3_5ForSequenceClassification, 3 labels: contradiction, entailment, neutral, last-token pooling, trained with plain cross-entropy over the three classes).modeling_openjev.py — OpenJevCrossEncoder: predict, rerank, grade, latents; LatentMLPHead for the per-task heads.modeling_qwen35_moe_seqcls.py — Qwen3_5MoeForSequenceClassification for the 35B-A3B backbone (transformers 5.15 ships none).mlp_heads_35b/<task>/ — head.pt + norm.npz + meta.json, the 35B latent + MLP heads behind the second radar.code/ — everything used here: the trainer, the multiple-choice harness, Flappy Bird and Doom (text and pixels), the radar.videos/ — Flappy Bird and Doom replays; results/ — raw JSON for every run and the full report.from modeling_openjev import OpenJevCrossEncoder
jev = OpenJevCrossEncoder("AlexWortega/openjev", subfolder="qwen3.5-4b-nli")
jev.predict([("The bird is 0.05 below the centre of the gap.", "The bird is below the centre of the gap.")])
# -> [[contradiction, entailment, neutral]] probabilities
jev.rerank("Which gas do plants absorb during photosynthesis?", ["oxygen", "carbon dioxide", "nitrogen"])
# -> index of the option with the highest entailment
Or with plain transformers:
from transformers import AutoModelForSequenceClassification, AutoTokenizer
tok = AutoTokenizer.from_pretrained("AlexWortega/openjev", subfolder="qwen3.5-4b-nli")
model = AutoModelForSequenceClassification.from_pretrained("AlexWortega/openjev", subfolder="qwen3.5-4b-nli")
text = model.config.nli_template.format(premise="...", hypothesis="...")
Reference point: dleemiller's NLI cross-encoders. Licence MIT.
33 commits
openjev — Qwen3.5 trained as jev model
100
33 commits
updated Sep 17, 2026

Bigger jev: Qwen3.5-35B-A3B (MoE) as the backbone. Zero-shot, and with the backbone frozen plus a small MLP head on the
last-token latent (mlp_heads_35b/, one head per task, loadable with LatentMLPHead.load):

openjev is Qwen3.5 turned into a jev model: a single cross-encoder that reads a premise and a hypothesis and answers with entailment, contradiction or neutral. That one primitive is enough to rerank answers, grade them against a reference, guard content, and play games in real time: hand it the game state and a few statements about it, and the argmax entailment is the move. Doom above is played zero-shot, first from the text state and then straight from the pixels through the Qwen3.5 vision tower. Nothing is trained per task.
qwen3.5-4b-nli/ — the 4B jev checkpoint (Qwen3_5ForSequenceClassification, 3 labels: contradiction, entailment, neutral, last-token pooling, trained with plain cross-entropy over the three classes).modeling_openjev.py — OpenJevCrossEncoder: predict, rerank, grade, latents; LatentMLPHead for the per-task heads.modeling_qwen35_moe_seqcls.py — Qwen3_5MoeForSequenceClassification for the 35B-A3B backbone (transformers 5.15 ships none).mlp_heads_35b/<task>/ — head.pt + norm.npz + meta.json, the 35B latent + MLP heads behind the second radar.code/ — everything used here: the trainer, the multiple-choice harness, Flappy Bird and Doom (text and pixels), the radar.videos/ — Flappy Bird and Doom replays; results/ — raw JSON for every run and the full report.from modeling_openjev import OpenJevCrossEncoder
jev = OpenJevCrossEncoder("AlexWortega/openjev", subfolder="qwen3.5-4b-nli")
jev.predict([("The bird is 0.05 below the centre of the gap.", "The bird is below the centre of the gap.")])
# -> [[contradiction, entailment, neutral]] probabilities
jev.rerank("Which gas do plants absorb during photosynthesis?", ["oxygen", "carbon dioxide", "nitrogen"])
# -> index of the option with the highest entailment
Or with plain transformers:
from transformers import AutoModelForSequenceClassification, AutoTokenizer
tok = AutoTokenizer.from_pretrained("AlexWortega/openjev", subfolder="qwen3.5-4b-nli")
model = AutoModelForSequenceClassification.from_pretrained("AlexWortega/openjev", subfolder="qwen3.5-4b-nli")
text = model.config.nli_template.format(premise="...", hypothesis="...")
Reference point: dleemiller's NLI cross-encoders. Licence MIT.
33 commits