cderinbogaz commited on
Commit
ce95ef8
·
0 Parent(s):

Raya: Laya multilingual fine-tuned for 3-tier routing

Browse files
.gitattributes ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ *.7z filter=lfs diff=lfs merge=lfs -text
2
+ *.arrow filter=lfs diff=lfs merge=lfs -text
3
+ *.bin filter=lfs diff=lfs merge=lfs -text
4
+ *.bz2 filter=lfs diff=lfs merge=lfs -text
5
+ *.ckpt filter=lfs diff=lfs merge=lfs -text
6
+ *.ftz filter=lfs diff=lfs merge=lfs -text
7
+ *.gz filter=lfs diff=lfs merge=lfs -text
8
+ *.h5 filter=lfs diff=lfs merge=lfs -text
9
+ *.joblib filter=lfs diff=lfs merge=lfs -text
10
+ *.lfs.* filter=lfs diff=lfs merge=lfs -text
11
+ *.mlmodel filter=lfs diff=lfs merge=lfs -text
12
+ *.model filter=lfs diff=lfs merge=lfs -text
13
+ *.msgpack filter=lfs diff=lfs merge=lfs -text
14
+ *.npy filter=lfs diff=lfs merge=lfs -text
15
+ *.npz filter=lfs diff=lfs merge=lfs -text
16
+ *.onnx filter=lfs diff=lfs merge=lfs -text
17
+ *.ot filter=lfs diff=lfs merge=lfs -text
18
+ *.parquet filter=lfs diff=lfs merge=lfs -text
19
+ *.pb filter=lfs diff=lfs merge=lfs -text
20
+ *.pickle filter=lfs diff=lfs merge=lfs -text
21
+ *.pkl filter=lfs diff=lfs merge=lfs -text
22
+ *.pt filter=lfs diff=lfs merge=lfs -text
23
+ *.pth filter=lfs diff=lfs merge=lfs -text
24
+ *.rar filter=lfs diff=lfs merge=lfs -text
25
+ *.safetensors filter=lfs diff=lfs merge=lfs -text
26
+ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
27
+ *.tar.* filter=lfs diff=lfs merge=lfs -text
28
+ *.tar filter=lfs diff=lfs merge=lfs -text
29
+ *.tflite filter=lfs diff=lfs merge=lfs -text
30
+ *.tgz filter=lfs diff=lfs merge=lfs -text
31
+ *.wasm filter=lfs diff=lfs merge=lfs -text
32
+ *.xz filter=lfs diff=lfs merge=lfs -text
33
+ *.zip filter=lfs diff=lfs merge=lfs -text
34
+ *.zst filter=lfs diff=lfs merge=lfs -text
35
+ *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ tokenizer/tokenizer.json filter=lfs diff=lfs merge=lfs -text
README.md ADDED
@@ -0,0 +1,110 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ license: apache-2.0
3
+ library_name: laya
4
+ pipeline_tag: text-classification
5
+ base_model: convaiinnovations/laya
6
+ datasets:
7
+ - allenai/WildChat-1M
8
+ language: [en, de, fr, es, it, pt, nl, pl, tr, ru, ar, zh, ja, ko]
9
+ tags: [routing, llm-routing, model-selection, prompt-difficulty, laya, system-one, calibrated-decisions, multilingual]
10
+ ---
11
+
12
+ # Raya — a fast multilingual LLM router (Laya fine-tune)
13
+
14
+ **Raya picks which model tier should answer a prompt — a small fast model, a mid-tier model, or a
15
+ frontier model — in one ~17 ms forward pass, about 20× faster than a hosted routing API.**
16
+
17
+ - **Robust to how you phrase the routing question.** Raya scores 80–81% on all three question styles we
18
+ tested. On the difficulty-score style it beats TypeSafe Jev by ~10 points
19
+ (**80.3% vs 70.5%**, paired McNemar p < 0.001).
20
+ - **Matches or beats Jev on the minimal routing question in Japanese (90 vs 87), Polish (86 vs 83),
21
+ Spanish (87 vs 85), German (74 vs 72), English (86 vs 86), and Arabic (73 vs 73).**
22
+ - **Open and self-hostable.** A 300M-parameter model with no per-call cost, served through Laya's
23
+ Jev-compatible HTTP API.
24
+
25
+ Raya is [Laya](https://huggingface.co/convaiinnovations/laya)'s multilingual decision model
26
+ (mmBERT-base encoder), fine-tuned end-to-end for 3-tier routing. It is not affiliated with Convai
27
+ Innovations or TypeSafe.
28
+
29
+ ## Quick start
30
+
31
+ ```python
32
+ import laya # pip install laya (Raya was built and tested with laya 0.3.7)
33
+
34
+ raya = laya.Agent("TextCortex/raya", device="cuda") # or "mps" / "cpu"
35
+
36
+ ROUTE = {
37
+ "type": "choice",
38
+ "instructions": "Route this prompt to a model.",
39
+ "criteria": {
40
+ "small_model": "simple requests",
41
+ "medium_model": "moderately complex requests",
42
+ "frontier_model": "very hard requests",
43
+ },
44
+ }
45
+
46
+ out = raya.system_one({"prompt": "Schreibe eine professionelle E-Mail an einen Kunden …"}, {"route": ROUTE})
47
+ print(out["answers"]["route"])
48
+ # {'choice': 'medium_model', 'probabilities': {'small_model': 0.24, 'medium_model': 0.74, 'frontier_model': 0.03}, ...}
49
+ ```
50
+
51
+ Raya was trained on three routing questions: the minimal choice above, a detailed rubric choice, and a
52
+ 3-level difficulty score. Use one of those. Option order does not matter because options were shuffled in
53
+ training. Raya serves through Laya's Jev-compatible HTTP server (`POST /v1/systemone`).
54
+
55
+ ## Benchmark: 3-tier routing on real multilingual prompts
56
+
57
+ **Test set.** 563 first-turn prompts from WildChat-1M (shards never used for training), 14 languages,
58
+ ~40 per language, 75% natural traffic + 25% hard-leaning. Gold tier = the tier two independent blind
59
+ annotators (Claude Opus and Claude Sonnet, same written rubric) **both** assigned; the annotators agree on
60
+ 78% of prompts, which is the practical ceiling. Tier mix: 225 small / 317 medium / 21 frontier.
61
+
62
+ | Question style | Raya | TypeSafe Jev 1.13 | Laya 0.3.7 (stock) | Von 1.1 (stock) |
63
+ |---|---|---|---|---|
64
+ | Difficulty score (3 levels) | **80.3%** | 70.5% | 61.6% | 42.3% |
65
+ | Rubric choice | 81.0% | **84.2%** | 47.1% | 58.8% |
66
+ | Minimal choice | 80.8% | **84.5%** | 55.2% | 54.5% |
67
+ | **Latency (p50)** | **17 ms** (1× GPU, in-process) | ~330 ms (hosted API) | — | — |
68
+
69
+ Always answering "medium" scores 56.3%.
70
+
71
+ **Per language, minimal choice** (accuracy %, n = 31–53 per language):
72
+
73
+ | | ja | pl | es | de | en | ar | it | ko | nl | ru | fr | zh | pt | tr |
74
+ |---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
75
+ | Raya | **90** | **86** | **87** | **74** | 86 | 73 | 87 | 88 | 78 | 82 | 78 | 79 | 76 | 67 |
76
+ | Jev | 87 | 83 | 85 | 72 | 86 | 73 | **90** | **91** | **81** | **89** | **86** | **88** | **90** | **82** |
77
+
78
+ Confusion, minimal choice (rows = gold small/medium/frontier, cols = Raya): `[[169, 56, 0], [30, 279, 8], [0, 14, 7]]`.
79
+
80
+ **Limitations of these numbers.** On the choice questions Jev is ahead overall by 3–4 points. That gap
81
+ is not statistically significant at these sample sizes (p = 0.07 and 0.13), but it is consistent. Raya is
82
+ weakest in Turkish, Portuguese, and Chinese. Differences of less than ~10 points within a single language
83
+ are within noise. Like Jev, Raya rarely routes to the frontier tier (7 of 21). Gold labels come from LLM
84
+ annotators, not from measured downstream answer quality.
85
+
86
+ ## Training
87
+
88
+ - **Architecture:** Laya decision model — mmBERT-base encoder + 2-layer transformer decision head with
89
+ per-option `[MASK]` scoring, initialised from `convaiinnovations/laya` (`multilingual`) and fine-tuned
90
+ end-to-end.
91
+ - **Data (soft labels from two blind annotators; 50/50 target where they disagreed):** WildChat-1M
92
+ first-turn prompts (ODC-BY); synthetic hard / hard-looking prompts across the 14 languages (kept only
93
+ if a blind annotator confirmed the intended tier); additional in-house routing data.
94
+ - **Procedure:** soft-target cross-entropy, options shuffled, AdamW (encoder 2e-5, head 1e-4), batch 32,
95
+ sequences capped at 512 tokens, bf16, best epoch chosen by validation accuracy (86.7% on 659 held-out
96
+ validation prompts, minimal choice), per-question temperature fitted on validation. The seed was also
97
+ chosen on validation only.
98
+ - **Compute:** one NVIDIA RTX A6000, ~6 minutes.
99
+
100
+ ## Intended use and limitations
101
+
102
+ For choosing among 2–3 model tiers for chat/assistant traffic. Not for safety moderation or for more
103
+ than 3 tiers. Not validated on multi-turn context. Calibrate a confidence threshold on your own traffic
104
+ before auto-escalating.
105
+
106
+ ## Acknowledgements
107
+
108
+ Laya architecture, runtime, and base checkpoint by Convai Innovations (Apache-2.0). mmBERT by JHU CLSP
109
+ (MIT). WildChat-1M by AI2 (ODC-BY). Jev is a product of TypeSafe AI; its scores come from our own runs
110
+ via its API (September 2026).
encoder/config.json ADDED
@@ -0,0 +1,79 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "architectures": [
3
+ "ModernBertForMaskedLM"
4
+ ],
5
+ "attention_bias": false,
6
+ "attention_dropout": 0.0,
7
+ "bos_token_id": 2,
8
+ "classifier_activation": "gelu",
9
+ "classifier_bias": false,
10
+ "classifier_dropout": 0.0,
11
+ "classifier_pooling": "mean",
12
+ "cls_token_id": 1,
13
+ "decoder_bias": true,
14
+ "deterministic_flash_attn": false,
15
+ "dtype": "float32",
16
+ "embedding_dropout": 0.0,
17
+ "eos_token_id": 1,
18
+ "global_attn_every_n_layers": 3,
19
+ "gradient_checkpointing": false,
20
+ "hidden_activation": "gelu",
21
+ "hidden_size": 768,
22
+ "initializer_cutoff_factor": 2.0,
23
+ "initializer_range": 0.02,
24
+ "intermediate_size": 1152,
25
+ "layer_norm_eps": 1e-05,
26
+ "layer_types": [
27
+ "full_attention",
28
+ "sliding_attention",
29
+ "sliding_attention",
30
+ "full_attention",
31
+ "sliding_attention",
32
+ "sliding_attention",
33
+ "full_attention",
34
+ "sliding_attention",
35
+ "sliding_attention",
36
+ "full_attention",
37
+ "sliding_attention",
38
+ "sliding_attention",
39
+ "full_attention",
40
+ "sliding_attention",
41
+ "sliding_attention",
42
+ "full_attention",
43
+ "sliding_attention",
44
+ "sliding_attention",
45
+ "full_attention",
46
+ "sliding_attention",
47
+ "sliding_attention",
48
+ "full_attention"
49
+ ],
50
+ "local_attention": 128,
51
+ "mask_token_id": 4,
52
+ "max_position_embeddings": 8192,
53
+ "mlp_bias": false,
54
+ "mlp_dropout": 0.0,
55
+ "model_type": "modernbert",
56
+ "norm_bias": false,
57
+ "norm_eps": 1e-05,
58
+ "num_attention_heads": 12,
59
+ "num_hidden_layers": 22,
60
+ "pad_token_id": 0,
61
+ "position_embedding_type": "sans_pos",
62
+ "repad_logits_with_grad": false,
63
+ "rope_parameters": {
64
+ "full_attention": {
65
+ "rope_theta": 160000,
66
+ "rope_type": "default"
67
+ },
68
+ "sliding_attention": {
69
+ "rope_theta": 160000,
70
+ "rope_type": "default"
71
+ }
72
+ },
73
+ "sep_token_id": 1,
74
+ "sparse_pred_ignore_index": -100,
75
+ "sparse_prediction": false,
76
+ "tie_word_embeddings": true,
77
+ "transformers_version": "5.0.0",
78
+ "vocab_size": 256000
79
+ }
model.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:44a55826828b36f2b391364fad88741aa8d13605a4bae99215dab2c74a869b05
3
+ size 1287653720
rl_agent_config.json ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "encoder": "jhu-clsp/mmBERT-base",
3
+ "head_layers": 2,
4
+ "max_len": 1024,
5
+ "head_max_len": 256,
6
+ "max_prefixes": 6,
7
+ "act_costs": {
8
+ "escalate": 0.5
9
+ },
10
+ "cost_wrong_act": 3.0,
11
+ "amp_dtype": "bf16",
12
+ "model_name": "rl-agent",
13
+ "temperature": [
14
+ 1.0,
15
+ 1.0,
16
+ 1.0
17
+ ],
18
+ "temperature_by_options": {
19
+ "choice:3-5": 1.35,
20
+ "score:3-5": 1.35
21
+ },
22
+ "training": {
23
+ "updates": 15987,
24
+ "epochs_completed": 4,
25
+ "hours": 4.97,
26
+ "world_size": 1,
27
+ "fine_tuned_from_checkpoint": true,
28
+ "routing_finetune": {
29
+ "rows": 9214,
30
+ "synthetic_rows": 767,
31
+ "epochs": 2,
32
+ "select": "acc",
33
+ "best_val_criterion": -0.8558,
34
+ "temperatures": {
35
+ "Q1_rubric_choice": 1.3,
36
+ "Q2_minimal_choice": 1.4,
37
+ "Q3_difficulty_score": 1.35
38
+ },
39
+ "seed": 1
40
+ }
41
+ }
42
+ }
tokenizer/tokenizer.json ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:609d8f4c067cd3950f88594c5a802616cea245823836ef5848ee4fc40aab5b6f
3
+ size 34363188
tokenizer/tokenizer_config.json ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "bos_token": "<bos>",
3
+ "clean_up_tokenization_spaces": false,
4
+ "cls_token": "<bos>",
5
+ "eos_token": "<eos>",
6
+ "extra_special_tokens": {
7
+ "extra_0": "<start_of_turn>",
8
+ "extra_1": "<end_of_turn>"
9
+ },
10
+ "mask_token": "<mask>",
11
+ "model_input_names": [
12
+ "input_ids",
13
+ "attention_mask"
14
+ ],
15
+ "model_max_length": 8192,
16
+ "pad_token": "<pad>",
17
+ "padding_side": "right",
18
+ "sep_token": "<eos>",
19
+ "spaces_between_special_tokens": false,
20
+ "tokenizer_class": "PreTrainedTokenizerFast",
21
+ "unk_token": "<unk>"
22
+ }