Kaiky Maia commited on
Commit
0fc3526
·
verified ·
1 Parent(s): f7bafee

Publish Laya PT/ES NLI checkpoint

Browse files
.gitattributes CHANGED
@@ -33,3 +33,4 @@ saved_model/**/* 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
 
 
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
ATTRIBUTIONS.md ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ # Attributions
2
+
3
+ This checkpoint derives from `convaiinnovations/laya-multilingual`, revision `052592a15d198d9ad47da779604259b10b47b7aa`. Its Hugging Face model card declares the Apache License 2.0.
4
+
5
+ Portuguese training and evaluation data came from InferBR by Lucas Bencke and contributors. The pinned source revision is `b6c5e0b27e52477bbc5433d130b0a0e825cf74dc`. InferBR is licensed under the MIT License.
6
+
7
+ Spanish training and evaluation data came from InferES by Venelin Kovatchev and contributors. The pinned source revision is `c371a1915e6902b40182b2ae83c5ec7fe5e6cbd2`. InferES is licensed under Creative Commons Attribution 4.0 International.
8
+
9
+ No source dataset rows, source audio, or third-party model documentation are redistributed in this repository.
10
+
README.md ADDED
@@ -0,0 +1,177 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ license: apache-2.0
3
+ library_name: laya
4
+ base_model: convaiinnovations/laya-multilingual
5
+ pipeline_tag: text-classification
6
+ language:
7
+ - pt
8
+ - es
9
+ datasets:
10
+ - venelin/inferes
11
+ tags:
12
+ - laya
13
+ - mmbert
14
+ - natural-language-inference
15
+ - portuguese
16
+ - spanish
17
+ - calibrated-decisions
18
+ - rlcd
19
+ - audio-adapter-compatible
20
+ model-index:
21
+ - name: Laya PT/ES NLI
22
+ results:
23
+ - task:
24
+ type: text-classification
25
+ name: Three-way natural language inference
26
+ dataset:
27
+ type: custom
28
+ name: Fixed InferBR and InferES test sample
29
+ config: 256 Portuguese and 256 Spanish examples, seed 42
30
+ split: test
31
+ metrics:
32
+ - type: accuracy
33
+ value: 0.8671875
34
+ name: Accuracy
35
+ - type: f1
36
+ value: 0.8669693326424834
37
+ name: Macro F1
38
+ - type: accuracy
39
+ value: 0.8673734610123119
40
+ name: Balanced accuracy
41
+ ---
42
+
43
+ # Laya PT/ES NLI
44
+
45
+ This checkpoint fine-tunes `convaiinnovations/laya-multilingual` for three-way natural language inference in Portuguese and Spanish. It predicts `contradiction`, `entailment`, or `neutral` in one non-autoregressive forward pass.
46
+
47
+ The checkpoint keeps the original 322M-parameter Laya architecture. It adds no inference module. It also preserves exact `input_ids` and `inputs_embeds` parity, which is required by the separate audio-adapter experiment.
48
+
49
+ ## Use
50
+
51
+ ```bash
52
+ pip install laya
53
+ ```
54
+
55
+ ```python
56
+ import laya
57
+
58
+ agent = laya.load("YOUR_NAMESPACE/laya-pt-es-nli")
59
+ questions = {
60
+ "relation": {
61
+ "type": "choice",
62
+ "instructions": "Qual é a relação lógica entre o estado e a hipótese: Um animal está dormindo.",
63
+ "criteria": {
64
+ "contradiction": "o estado torna a hipótese falsa",
65
+ "entailment": "o estado confirma a hipótese",
66
+ "neutral": "o estado não confirma nem contradiz a hipótese",
67
+ },
68
+ }
69
+ }
70
+ result = agent.predict({"state": "Um gato dorme no sofá."}, questions)
71
+ print(result["answers"]["relation"])
72
+ ```
73
+
74
+ Use localized instructions and option descriptions. The training and evaluation label order is `contradiction`, `entailment`, `neutral`.
75
+
76
+ ## Evaluation
77
+
78
+ The main comparison uses the same 512 held-out examples for every target. It contains 256 InferBR examples and 256 InferES examples. Sampling uses seed 42. The sample-ID digest is `da18f9ec812db66ceb731299b2986d629121334b0565d0d1ea721b25e396d25e`. Local results and latency come from `four-model-nli-r2`. TypeSafe results come from `typesafe-comparison-r1` on the same sample IDs.
79
+
80
+ | Model | PT macro F1 | ES macro F1 | Overall macro F1 | Balanced accuracy | Brier | ECE | p50 | p95 | Peak VRAM |
81
+ |---|---:|---:|---:|---:|---:|---:|---:|---:|---:|
82
+ | **Laya PT/ES NLI** | **0.9295** | **0.8028** | **0.8670** | **0.8674** | 0.2185 | 0.0611 | 31.7 ms | 34.0 ms | 0.66 GiB |
83
+ | Laya Multilingual base | 0.6054 | 0.5150 | 0.5622 | 0.5583 | 0.5926 | 0.1191 | 31.2 ms | 35.0 ms | 0.66 GiB |
84
+ | OpenJEV v2 | 0.9248 | 0.7943 | 0.8601 | 0.8591 | **0.2057** | 0.0515 | 120.4 ms | 143.5 ms | 9.21 GiB |
85
+ | TypeSafe JEV API | 0.9532 | 0.8366 | 0.8950 | 0.8944 | 0.1518 | **0.0188** | 585.6 ms | 668.5 ms | not available |
86
+
87
+ ECE uses ten equal-width bins and top-label confidence. Brier is the sum across the three classes. Laya and TypeSafe use localized typed-choice prompts. OpenJEV uses its native premise and hypothesis template.
88
+
89
+ The complete sealed test contains 3,315 examples. This checkpoint has 0.8657 macro F1 overall, 0.9324 in Portuguese, and 0.7914 in Spanish. Its option-order agreement is 0.9741. The fitted choice temperature is 6.737636.
90
+
91
+ ## Latency and memory
92
+
93
+ The local benchmark ran on a Modal `A100-40GB` worker. The image used Python 3.12, PyTorch 2.13.0, and Transformers 5.14.1. Each latency value measures one warm batch-size-one call. It excludes model load time.
94
+
95
+ | Model | p50 | p95 | Peak VRAM | Load time |
96
+ |---|---:|---:|---:|---:|
97
+ | **Laya PT/ES NLI** | **31.7 ms** | **34.0 ms** | **0.66 GiB** | 54.8 s |
98
+ | Laya Multilingual base | 31.2 ms | 35.0 ms | 0.66 GiB | 41.5 s |
99
+ | OpenJEV v2 | 120.4 ms | 143.5 ms | 9.21 GiB | 23.7 s |
100
+ | TypeSafe JEV API | 585.6 ms | 668.5 ms | not available | not applicable |
101
+
102
+ TypeSafe latency includes the remote network. It is not an apples-to-apples local-model latency result. Local measurements use 64 examples after two warm-up calls.
103
+
104
+ ## Training
105
+
106
+ Training updated the complete encoder and decision head. It did not use LoRA or an adapter. The objective was RLCD plus cross-entropy. RLCD used four perturbations, log plus spherical reward, and a linear noise schedule from 0.4 to 0.1.
107
+
108
+ The run trained independent 4-, 8-, and 16-epoch candidates from the same pinned base revision. Validation selected the 8-epoch checkpoint. The selection key was mean PT/ES macro F1, then weakest-language macro F1, then negative NLL.
109
+
110
+ The selected run used these values:
111
+
112
+ - batch size: 16
113
+ - gradient accumulation: 4
114
+ - encoder learning rate: 2.5e-5
115
+ - head learning rate: 1e-4
116
+ - AdamW weight decay: 0.01
117
+ - cosine learning-rate schedule, minimum 1e-6
118
+ - gradient clip: 1.0
119
+ - BF16 autocast and saved BF16 weights
120
+ - gradient checkpointing with non-reentrant execution
121
+ - seed: 42
122
+ - train, validation, and sealed test sizes: 13,971, 1,275, and 3,315
123
+
124
+ Portuguese and Spanish had equal sampling weight. Each epoch balanced all six language-label buckets. The fitted validation temperature was saved in `rl_agent_config.json`.
125
+
126
+ A Spanish-focused continuation tested 1, 2, and 4 additional epochs with a 2:1 Spanish-to-Portuguese sampling weight. No candidate passed the fixed promotion gate. This release therefore uses the original 8-epoch checkpoint.
127
+
128
+ The exact run command was:
129
+
130
+ ```bash
131
+ uv run modal run modal_laya_finetune.py::app.train_laya_multilingual \
132
+ --run laya-nli-pt-es-r1 \
133
+ --epoch-budgets 4,8,16 \
134
+ --batch-size 16 \
135
+ --gradient-accumulation 4
136
+ ```
137
+
138
+ The comparison command was:
139
+
140
+ ```bash
141
+ uv run modal run modal_benchmarks.py::app.run_nli_benchmark \
142
+ --run four-model-nli-r1
143
+ ```
144
+
145
+ ## Data and license
146
+
147
+ The Portuguese source is [InferBR](https://github.com/lbencke/InferBR) at revision `b6c5e0b27e52477bbc5433d130b0a0e825cf74dc`, licensed under MIT. The Spanish source is [InferES](https://huggingface.co/datasets/venelin/inferes) at revision `c371a1915e6902b40182b2ae83c5ec7fe5e6cbd2`, licensed under CC BY 4.0.
148
+
149
+ InferES provides train and test files. The run removed train/test duplicate pairs. It then made a deterministic 10% per-class validation split from the remaining train data with seed 42. InferBR rows marked as low quality were excluded. All splits were deduplicated and checked for pair overlap.
150
+
151
+ The base checkpoint declares Apache 2.0. This derivative is released under Apache 2.0. InferES attribution remains required. See `ATTRIBUTIONS.md` and `provenance.json`. This repository does not redistribute any training dataset or audio.
152
+
153
+ ## Audio compatibility
154
+
155
+ The compatibility gate used 768 pairs from 256 MLS and Common Voice clips. Direct embedding lookup and split-state splice matched the token-ID path exactly in FP32 and BF16. Maximum logit, marker-state, and action-logit differences were zero. Label and layout agreement were 1.0.
156
+
157
+ This is not an audio model. It contains no audio encoder or trained audio adapter. The compatibility result only confirms that an external adapter can enter through `inputs_embeds` without changing Laya's decision path.
158
+
159
+ ## Limitations
160
+
161
+ - Spanish is materially weaker than Portuguese on both validation and test data.
162
+ - Calibration is domain-specific. Refit temperature on a held-out target-domain set before using probabilities as risk scores.
163
+ - The 512-example comparison has no confidence intervals and does not establish superiority over OpenJEV or TypeSafe.
164
+ - The checkpoint was trained only for three-way NLI. Other Laya question types were not retrained or validated.
165
+ - The local latency results apply to the stated software and GPU. CPU and other GPU results can differ.
166
+ - Dataset artifacts can contain annotation errors and social biases from their source corpora.
167
+ - Do not use this model as the sole basis for medical, legal, financial, or safety-critical decisions.
168
+
169
+ ## Files
170
+
171
+ - `model.safetensors`: full fine-tuned model weights.
172
+ - `encoder/` and `tokenizer/`: pinned model configuration and tokenizer.
173
+ - `rl_agent_config.json`: Laya runtime configuration and calibrated temperature.
174
+ - `training.json`: training configuration, validation metrics, history, and source manifest.
175
+ - `evaluation_results.json`: compact sealed-test and comparison results.
176
+ - `provenance.json`: base revision, dataset revisions, runtime, and compatibility gates.
177
+ - `SHA256SUMS`: release integrity manifest.
SHA256SUMS ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ cf3d6c3d6fcddd7b9087fa011c8c181bd67ec0d3f81c8dfc79e6b816edf7e10b ATTRIBUTIONS.md
2
+ f16153096e4e0e5b74162c36c5d7b8b59f50f8cf699f354ad36997fd56a9aac0 README.md
3
+ 212544c8358591ff7ed19a4a80cca59340cbd594729c8698dee9cd5eea5f253d encoder/config.json
4
+ ec1602d9559791fd5c66472a2ccd116d453d5b2771bd53f564c9934abf0d7d6b evaluation_results.json
5
+ 94c5ade6106cba72e07987d6a2fb977e7e7d1532f23e54f6ec2bfa7bbfe719be model.safetensors
6
+ 328300408c2332c1aa42a0bfaee9e6480f2a1b2e31948cf2cf0f39d30a4fab7b provenance.json
7
+ 9438ec88dab246eca6b84c11cb89cdb4447b4828e1705d725fcf88ce1cda01f0 publish.py
8
+ b86ac53abcb1eeeaf90feae206e395f043b1b089e4d0f526200728b140040b0d rl_agent_config.json
9
+ 609d8f4c067cd3950f88594c5a802616cea245823836ef5848ee4fc40aab5b6f tokenizer/tokenizer.json
10
+ cb01c24cdc73e85640cb6bcde2469cc4b05b7c184664cb57f6ccfc7b5a45d779 tokenizer/tokenizer_config.json
11
+ f256ccb3930b045a5202e3afba5d0537cd133b494f8ee3788d81c26e6a9e7688 training.json
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.14.1",
78
+ "vocab_size": 256000
79
+ }
evaluation_results.json ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "schema_version": 1,
3
+ "label_order": ["contradiction", "entailment", "neutral"],
4
+ "sealed_test": {
5
+ "n_examples": 3315,
6
+ "temperature": 6.737636089324951,
7
+ "accuracy": 0.8663650155067444,
8
+ "macro_f1": 0.8657161857755229,
9
+ "nll": 0.4384844899177551,
10
+ "brier": 0.22188593447208405,
11
+ "ece": 0.061342481945757754,
12
+ "option_order_agreement": 0.9740573167800903,
13
+ "by_language": {
14
+ "pt": {"n_examples": 1705, "accuracy": 0.9325513243675232, "macro_f1": 0.9324053374823894, "nll": 0.2746226489543915, "brier": 0.12065495550632477, "ece": 0.05137685628142208},
15
+ "es": {"n_examples": 1610, "accuracy": 0.7962732911109924, "macro_f1": 0.7914361746136098, "nll": 0.6120151281356812, "brier": 0.3290901780128479, "ece": 0.09335547377122566}
16
+ }
17
+ },
18
+ "fixed_512_comparison": {
19
+ "local_run": "four-model-nli-r2",
20
+ "typesafe_run": "typesafe-comparison-r1",
21
+ "seed": 42,
22
+ "per_language": 256,
23
+ "sample_sha256": "da18f9ec812db66ceb731299b2986d629121334b0565d0d1ea721b25e396d25e",
24
+ "latency_examples": 64,
25
+ "warmup_calls": 2,
26
+ "models": {
27
+ "laya_pt_es": {"accuracy": 0.8671875, "balanced_accuracy": 0.8673734610123119, "macro_f1": 0.8669693326424834, "pt_macro_f1": 0.9295275148432717, "es_macro_f1": 0.8027949622344871, "brier": 0.2185381066577995, "ece": 0.061121337406802964, "option_order_agreement": 0.9921875, "p50_s": 0.03165481199999931, "p95_s": 0.034017716150002285, "peak_vram_bytes": 707878400},
28
+ "laya_multilingual": {"accuracy": 0.55859375, "balanced_accuracy": 0.5583447332421341, "macro_f1": 0.5621945405613227, "pt_macro_f1": 0.6054199410298268, "es_macro_f1": 0.5150492462700995, "brier": 0.5925970264745448, "ece": 0.11910045781405645, "option_order_agreement": 0.830078125, "p50_s": 0.031237861000001033, "p95_s": 0.035027764200007985, "peak_vram_bytes": 704986624},
29
+ "openjev_v2": {"accuracy": 0.859375, "balanced_accuracy": 0.8591427268581852, "macro_f1": 0.8600981307482297, "pt_macro_f1": 0.9248010163075886, "es_macro_f1": 0.7942985329442359, "brier": 0.20570788629959827, "ece": 0.05154871946433563, "p50_s": 0.12035475150000252, "p95_s": 0.14351390009999243, "peak_vram_bytes": 9890091008},
30
+ "typesafe_jev": {"accuracy": 0.89453125, "balanced_accuracy": 0.8944140446876426, "macro_f1": 0.895036364601582, "pt_macro_f1": 0.9531952992402649, "es_macro_f1": 0.8365977013371774, "brier": 0.151828515625, "ece": 0.018828125000000022, "option_order_agreement": 0.986328125, "p50_s": 0.5855838539999354, "p95_s": 0.6685402502499754, "network_included": true}
31
+ }
32
+ }
33
+ }
model.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:94c5ade6106cba72e07987d6a2fb977e7e7d1532f23e54f6ec2bfa7bbfe719be
3
+ size 643835692
provenance.json ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "schema_version": 1,
3
+ "run": "laya-nli-pt-es-r1",
4
+ "selected_candidate_epochs": 8,
5
+ "candidate_epoch_budgets": [4, 8, 16],
6
+ "spanish_continuation": {"candidate_additional_epochs": [1, 2, 4], "selected_additional_epochs": 0, "promotion": false},
7
+ "base_model": {"repo_id": "convaiinnovations/laya-multilingual", "revision": "052592a15d198d9ad47da779604259b10b47b7aa", "declared_license": "apache-2.0"},
8
+ "training_runtime": {"provider": "Modal", "gpu_request": "A100-40GB", "python": "3.12", "torch": "2.13.0", "transformers": "5.14.1", "accelerate": "1.14.0", "peft": "0.20.0"},
9
+ "split_sizes": {"train": 13971, "validation": 1275, "test": 3315},
10
+ "dataset_assets": [
11
+ {"dataset": "InferBR", "revision": "b6c5e0b27e52477bbc5433d130b0a0e825cf74dc", "license": "MIT", "files": {"LICENSE": "b1cd6172bf8061abcbd7917e9246ddeded210339482e802e3413b74cc7e0de38", "train.csv": "ccce8f72fae244729833bc2a2bf86bce7cff18d8383c07ec4389b1cd453b85f4", "val.csv": "45a855012940750694b37616dfc346325aadff7e661a75ddabc8b90a4375d3aa", "test.csv": "50d16e4c6d951349c188547f54c73f5699e8be0abb88780b55d3666a755dc32d"}},
12
+ {"dataset": "InferES", "revision": "c371a1915e6902b40182b2ae83c5ec7fe5e6cbd2", "license": "CC-BY-4.0", "files": {"README.md": "c590a3ed872bde10e3f9f81e6963644d45587a422bb6c985a0e5aa03ee69c59e", "train.csv": "6e7fcef798b3d37522588dbcb5c88e574139aae4cb334fc163168744f12bbe7c", "test.csv": "faa73fb8567b7664cf03f5f01cf4aae1e0c940a64dc57ad8b36d1fcaeaeffc1a"}}
13
+ ],
14
+ "audio_compatibility_gate": {"n_clips": 256, "n_pairs": 768, "triplet_manifest_sha256": "f6f20be86141370fc0e12ad8ec674718210e5a60e5d421e3a302b2cd7205d0b3", "dtypes": ["float32", "bfloat16"], "max_abs_logits": 0.0, "max_abs_marker_states": 0.0, "max_abs_act_logits": 0.0, "label_agreement": 1.0, "layout_agreement": 1.0, "passed": true},
15
+ "redistributed_training_data": false,
16
+ "redistributed_audio": false
17
+ }
18
+
publish.py ADDED
@@ -0,0 +1,91 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """Validate and publish this bundle without storing or printing HF_TOKEN."""
3
+
4
+ from __future__ import annotations
5
+
6
+ import argparse
7
+ import hashlib
8
+ import json
9
+ import os
10
+ from pathlib import Path
11
+
12
+
13
+ BUNDLE = Path(__file__).resolve().parent
14
+ REQUIRED = {
15
+ "README.md",
16
+ "ATTRIBUTIONS.md",
17
+ "SHA256SUMS",
18
+ "encoder/config.json",
19
+ "evaluation_results.json",
20
+ "model.safetensors",
21
+ "provenance.json",
22
+ "rl_agent_config.json",
23
+ "tokenizer/tokenizer.json",
24
+ "tokenizer/tokenizer_config.json",
25
+ "training.json",
26
+ }
27
+
28
+
29
+ def digest(path: Path) -> str:
30
+ value = hashlib.sha256()
31
+ with path.open("rb") as handle:
32
+ for chunk in iter(lambda: handle.read(1024 * 1024), b""):
33
+ value.update(chunk)
34
+ return value.hexdigest()
35
+
36
+
37
+ def validate() -> None:
38
+ missing = sorted(name for name in REQUIRED if not (BUNDLE / name).is_file())
39
+ if missing:
40
+ raise SystemExit(f"Missing release files: {', '.join(missing)}")
41
+ for name in ("encoder/config.json", "evaluation_results.json", "provenance.json", "rl_agent_config.json", "tokenizer/tokenizer_config.json", "training.json"):
42
+ with (BUNDLE / name).open(encoding="utf-8") as handle:
43
+ json.load(handle)
44
+ lines = (BUNDLE / "SHA256SUMS").read_text(encoding="utf-8").splitlines()
45
+ expected = {}
46
+ for line in lines:
47
+ checksum, name = line.split(" ", 1)
48
+ expected[name] = checksum
49
+ for name, checksum in expected.items():
50
+ path = BUNDLE / name
51
+ if not path.is_file() or digest(path) != checksum:
52
+ raise SystemExit(f"Checksum mismatch: {name}")
53
+ if not (BUNDLE / "README.md").read_text(encoding="utf-8").startswith("---\n"):
54
+ raise SystemExit("README.md has no Hugging Face YAML metadata")
55
+ print(f"Validated {len(expected)} checksums in {BUNDLE}")
56
+
57
+
58
+ def main() -> None:
59
+ parser = argparse.ArgumentParser()
60
+ parser.add_argument("--check-only", action="store_true")
61
+ parser.add_argument("--repo-id", help="Defaults to <authenticated-user>/laya-pt-es-nli")
62
+ args = parser.parse_args()
63
+ validate()
64
+ if args.check_only:
65
+ return
66
+ token = os.environ.get("HF_TOKEN")
67
+ if not token:
68
+ raise SystemExit("HF_TOKEN is required for upload")
69
+ from huggingface_hub import HfApi
70
+
71
+ api = HfApi(token=token)
72
+ identity = api.whoami()
73
+ owner = str(identity["name"])
74
+ repo_id = args.repo_id or f"{owner}/laya-pt-es-nli"
75
+ requested_owner, separator, name = repo_id.partition("/")
76
+ allowed = {owner, *(str(org["name"]) for org in identity.get("orgs", []))}
77
+ if not separator or name != "laya-pt-es-nli" or requested_owner not in allowed:
78
+ raise SystemExit("repo-id must be <authenticated-user-or-org>/laya-pt-es-nli")
79
+ api.create_repo(repo_id=repo_id, repo_type="model", private=False, exist_ok=True)
80
+ api.upload_folder(
81
+ repo_id=repo_id,
82
+ repo_type="model",
83
+ folder_path=BUNDLE,
84
+ commit_message="Publish Laya PT/ES NLI checkpoint",
85
+ ignore_patterns=["__pycache__/**", "*.pyc"],
86
+ )
87
+ print(f"Published https://huggingface.co/{repo_id}")
88
+
89
+
90
+ if __name__ == "__main__":
91
+ main()
rl_agent_config.json ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ 6.737636089324951,
15
+ 1.0,
16
+ 1.0
17
+ ],
18
+ "temperature_by_options": {},
19
+ "training": {
20
+ "updates": 15987,
21
+ "epochs_completed": 4,
22
+ "hours": 4.97,
23
+ "world_size": 1,
24
+ "fine_tuned_from_checkpoint": false
25
+ },
26
+ "fine_tuned": true
27
+ }
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,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ "local_files_only": false,
11
+ "mask_token": "<mask>",
12
+ "model_input_names": [
13
+ "input_ids",
14
+ "attention_mask"
15
+ ],
16
+ "model_max_length": 8192,
17
+ "pad_token": "<pad>",
18
+ "padding_side": "right",
19
+ "sep_token": "<eos>",
20
+ "spaces_between_special_tokens": false,
21
+ "tokenizer_class": "PreTrainedTokenizerFast",
22
+ "unk_token": "<unk>"
23
+ }
training.json ADDED
@@ -0,0 +1,258 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "config": {
3
+ "epochs": 8,
4
+ "batch_size": 16,
5
+ "gradient_accumulation": 4,
6
+ "encoder_lr": 2.5e-05,
7
+ "head_lr": 0.0001,
8
+ "weight_decay": 0.01,
9
+ "group_size": 4,
10
+ "sigma_start": 0.4,
11
+ "sigma_end": 0.1,
12
+ "spherical_weight": 0.75,
13
+ "cross_entropy_weight": 1.0,
14
+ "grad_clip": 1.0,
15
+ "seed": 42,
16
+ "max_steps": null
17
+ },
18
+ "validation": {
19
+ "temperature": 6.737636089324951,
20
+ "overall": {
21
+ "n_examples": 1275,
22
+ "accuracy": 0.869019627571106,
23
+ "macro_f1": 0.8684708751770857,
24
+ "per_class": [
25
+ {
26
+ "precision": 0.8637469586374696,
27
+ "recall": 0.8352941176470589,
28
+ "f1": 0.8492822966507177
29
+ },
30
+ {
31
+ "precision": 0.8669950738916257,
32
+ "recall": 0.8669950738916257,
33
+ "f1": 0.8669950738916257
34
+ },
35
+ {
36
+ "precision": 0.8755458515283843,
37
+ "recall": 0.9031531531531531,
38
+ "f1": 0.8891352549889135
39
+ }
40
+ ],
41
+ "confusion": [
42
+ [
43
+ 355,
44
+ 29,
45
+ 41
46
+ ],
47
+ [
48
+ 38,
49
+ 352,
50
+ 16
51
+ ],
52
+ [
53
+ 18,
54
+ 25,
55
+ 401
56
+ ]
57
+ ],
58
+ "nll": 0.4360364079475403,
59
+ "brier": 0.2183937281370163,
60
+ "ece": 0.04733535635750741
61
+ },
62
+ "by_language": {
63
+ "pt": {
64
+ "n_examples": 633,
65
+ "accuracy": 0.9431279897689819,
66
+ "macro_f1": 0.9430095871700123,
67
+ "per_class": [
68
+ {
69
+ "precision": 0.943127962085308,
70
+ "recall": 0.943127962085308,
71
+ "f1": 0.943127962085308
72
+ },
73
+ {
74
+ "precision": 0.9490740740740741,
75
+ "recall": 0.9534883720930233,
76
+ "f1": 0.951276102088167
77
+ },
78
+ {
79
+ "precision": 0.9368932038834952,
80
+ "recall": 0.9323671497584541,
81
+ "f1": 0.9346246973365618
82
+ }
83
+ ],
84
+ "confusion": [
85
+ [
86
+ 199,
87
+ 3,
88
+ 9
89
+ ],
90
+ [
91
+ 6,
92
+ 205,
93
+ 4
94
+ ],
95
+ [
96
+ 6,
97
+ 8,
98
+ 193
99
+ ]
100
+ ],
101
+ "nll": 0.25479501485824585,
102
+ "brier": 0.10705043375492096,
103
+ "ece": 0.058824770618230104
104
+ },
105
+ "es": {
106
+ "n_examples": 642,
107
+ "accuracy": 0.795950174331665,
108
+ "macro_f1": 0.7919974927113839,
109
+ "per_class": [
110
+ {
111
+ "precision": 0.78,
112
+ "recall": 0.7289719626168224,
113
+ "f1": 0.7536231884057971
114
+ },
115
+ {
116
+ "precision": 0.7736842105263158,
117
+ "recall": 0.7696335078534031,
118
+ "f1": 0.7716535433070866
119
+ },
120
+ {
121
+ "precision": 0.8253968253968254,
122
+ "recall": 0.8776371308016878,
123
+ "f1": 0.8507157464212678
124
+ }
125
+ ],
126
+ "confusion": [
127
+ [
128
+ 156,
129
+ 26,
130
+ 32
131
+ ],
132
+ [
133
+ 32,
134
+ 147,
135
+ 12
136
+ ],
137
+ [
138
+ 12,
139
+ 17,
140
+ 208
141
+ ]
142
+ ],
143
+ "nll": 0.6147370338439941,
144
+ "brier": 0.3281761407852173,
145
+ "ece": 0.07957642641849816
146
+ }
147
+ }
148
+ },
149
+ "history": [
150
+ {
151
+ "epoch": 1.0,
152
+ "sigma": 0.4,
153
+ "loss": 0.3529272115014159,
154
+ "ce_loss": 0.4184872030187943,
155
+ "reward": 0.2136233496819178
156
+ },
157
+ {
158
+ "epoch": 2.0,
159
+ "sigma": 0.35714285714285715,
160
+ "loss": 0.22856930547368215,
161
+ "ce_loss": 0.2664471471820005,
162
+ "reward": 0.45009025061397756
163
+ },
164
+ {
165
+ "epoch": 3.0,
166
+ "sigma": 0.3142857142857143,
167
+ "loss": 0.44020914059830374,
168
+ "ce_loss": 0.4539933671216609,
169
+ "reward": 0.4695609428467806
170
+ },
171
+ {
172
+ "epoch": 4.0,
173
+ "sigma": 0.27142857142857146,
174
+ "loss": 0.3634551393018673,
175
+ "ce_loss": 0.3668573111245656,
176
+ "reward": 0.5148424091975824
177
+ },
178
+ {
179
+ "epoch": 5.0,
180
+ "sigma": 0.22857142857142856,
181
+ "loss": 0.2925769820513702,
182
+ "ce_loss": 0.29792355096248074,
183
+ "reward": 0.5659681633840992
184
+ },
185
+ {
186
+ "epoch": 6.0,
187
+ "sigma": 0.1857142857142857,
188
+ "loss": 0.21010468557679843,
189
+ "ce_loss": 0.2128874539987309,
190
+ "reward": 0.6190930930116952
191
+ },
192
+ {
193
+ "epoch": 7.0,
194
+ "sigma": 0.14285714285714285,
195
+ "loss": 0.16850203610472006,
196
+ "ce_loss": 0.16884397977840113,
197
+ "reward": 0.6464318029771307
198
+ },
199
+ {
200
+ "epoch": 8.0,
201
+ "sigma": 0.09999999999999998,
202
+ "loss": 0.12187420110390038,
203
+ "ce_loss": 0.12067060629254318,
204
+ "reward": 0.6735549877755358
205
+ }
206
+ ],
207
+ "datasets": [
208
+ {
209
+ "name": "inferbr-LICENSE",
210
+ "url": "https://raw.githubusercontent.com/lbencke/InferBR/b6c5e0b27e52477bbc5433d130b0a0e825cf74dc/LICENSE",
211
+ "sha256": "b1cd6172bf8061abcbd7917e9246ddeded210339482e802e3413b74cc7e0de38",
212
+ "license": "MIT",
213
+ "revision": "b6c5e0b27e52477bbc5433d130b0a0e825cf74dc"
214
+ },
215
+ {
216
+ "name": "inferbr-train.csv",
217
+ "url": "https://raw.githubusercontent.com/lbencke/InferBR/b6c5e0b27e52477bbc5433d130b0a0e825cf74dc/train.csv",
218
+ "sha256": "ccce8f72fae244729833bc2a2bf86bce7cff18d8383c07ec4389b1cd453b85f4",
219
+ "license": "MIT",
220
+ "revision": "b6c5e0b27e52477bbc5433d130b0a0e825cf74dc"
221
+ },
222
+ {
223
+ "name": "inferbr-validation.csv",
224
+ "url": "https://raw.githubusercontent.com/lbencke/InferBR/b6c5e0b27e52477bbc5433d130b0a0e825cf74dc/val.csv",
225
+ "sha256": "45a855012940750694b37616dfc346325aadff7e661a75ddabc8b90a4375d3aa",
226
+ "license": "MIT",
227
+ "revision": "b6c5e0b27e52477bbc5433d130b0a0e825cf74dc"
228
+ },
229
+ {
230
+ "name": "inferbr-test.csv",
231
+ "url": "https://raw.githubusercontent.com/lbencke/InferBR/b6c5e0b27e52477bbc5433d130b0a0e825cf74dc/test.csv",
232
+ "sha256": "50d16e4c6d951349c188547f54c73f5699e8be0abb88780b55d3666a755dc32d",
233
+ "license": "MIT",
234
+ "revision": "b6c5e0b27e52477bbc5433d130b0a0e825cf74dc"
235
+ },
236
+ {
237
+ "name": "inferes-README.md",
238
+ "url": "https://huggingface.co/datasets/venelin/inferes/resolve/c371a1915e6902b40182b2ae83c5ec7fe5e6cbd2/README.md",
239
+ "sha256": "c590a3ed872bde10e3f9f81e6963644d45587a422bb6c985a0e5aa03ee69c59e",
240
+ "license": "CC-BY-4.0",
241
+ "revision": "c371a1915e6902b40182b2ae83c5ec7fe5e6cbd2"
242
+ },
243
+ {
244
+ "name": "inferes-train.csv",
245
+ "url": "https://huggingface.co/datasets/venelin/inferes/resolve/c371a1915e6902b40182b2ae83c5ec7fe5e6cbd2/train.csv",
246
+ "sha256": "6e7fcef798b3d37522588dbcb5c88e574139aae4cb334fc163168744f12bbe7c",
247
+ "license": "CC-BY-4.0",
248
+ "revision": "c371a1915e6902b40182b2ae83c5ec7fe5e6cbd2"
249
+ },
250
+ {
251
+ "name": "inferes-test.csv",
252
+ "url": "https://huggingface.co/datasets/venelin/inferes/resolve/c371a1915e6902b40182b2ae83c5ec7fe5e6cbd2/test.csv",
253
+ "sha256": "faa73fb8567b7664cf03f5f01cf4aae1e0c940a64dc57ad8b36d1fcaeaeffc1a",
254
+ "license": "CC-BY-4.0",
255
+ "revision": "c371a1915e6902b40182b2ae83c5ec7fe5e6cbd2"
256
+ }
257
+ ]
258
+ }