Robotics
reward-model
Ayleea929 commited on
Commit
87f8154
·
verified ·
1 Parent(s): 7f90fbe

Upload folder using huggingface_hub

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
+ base/Wan-AI/Wan2.1-T2V-1.3B/google/umt5-xxl/tokenizer.json filter=lfs diff=lfs merge=lfs -text
README.md CHANGED
@@ -1,3 +1,104 @@
1
  ---
2
  license: apache-2.0
 
 
 
 
 
 
3
  ---
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  ---
2
  license: apache-2.0
3
+ base_model: Wan-AI/Wan2.2-TI2V-5B
4
+ datasets:
5
+ - RimbotAI/LOOM
6
+ tags:
7
+ - robotics
8
+ - reward-model
9
  ---
10
+
11
+ # NimCritic
12
+
13
+ NimCritic 根据机器人视频和任务指令,逐帧估计任务进度与是否完成。
14
+
15
+ [Project page](https://rimbot.com/en/research/nimcritic/) · [Paper](https://arxiv.org/abs/2610.32776)
16
+
17
+ ## 目录里有什么
18
+
19
+ | 路径 | 内容 |
20
+ |---|---|
21
+ | `infer_nimcritic.py` | 读帧、滑窗和命令行参数。 |
22
+ | `nimcritic_model.py` | 模型:video DiT、value DiT、VAE、文本编码器。 |
23
+ | `nimcritic_step_128000.pt` | step 128000。video expert 5.00B,value expert 1.02B,bfloat16。 |
24
+ | `base/` | Wan2.2 VAE、UMT5-XXL 编码器和分词器。不含 Wan2.2 DiT:video expert 的完整权重已经在 `.pt` 里。 |
25
+
26
+ `base/` 包含:
27
+
28
+ - `DiffSynth-Studio/Wan-Series-Converted-Safetensors/Wan2.2_VAE.safetensors`
29
+ - `DiffSynth-Studio/Wan-Series-Converted-Safetensors/models_t5_umt5-xxl-enc-bf16.safetensors`
30
+ - `Wan-AI/Wan2.1-T2V-1.3B/google/umt5-xxl/`(分词器)
31
+
32
+ 许可见 Apache-2.0。
33
+
34
+ ## 环境
35
+
36
+ Python 3.12+。在本目录安装推理依赖:
37
+
38
+ ```bash
39
+ uv sync
40
+ ```
41
+
42
+ 依赖写在 `pyproject.toml`:PyTorch、`transformers`(4.57,低于 4.58)、`safetensors`、`einops`、`opencv-python-headless`、`Pillow`、`numpy`、`tqdm`。
43
+
44
+ 模型代码在 `nimcritic_model.py`,权重与 `base/` 在同目录。推理不访问其他路径,也不下载额外文件。
45
+
46
+ ## 推理
47
+
48
+ 在本目录执行。默认读取同目录的 `nimcritic_step_128000.pt` 与 `base/`。
49
+
50
+ ```bash
51
+ uv run python infer_nimcritic.py \
52
+ --video clip.mp4 \
53
+ --task "pick up the cup" \
54
+ --output result.json
55
+ ```
56
+
57
+ 输入为视频文件时,按容器帧率采样至 2Hz(`--sample-hz`,默认 2),并保留最后一帧。输入已是 2Hz 帧序列时使用 `--frames`,不再按 2Hz 重采样:
58
+
59
+ ```bash
60
+ uv run python infer_nimcritic.py \
61
+ --frames frames_dir/ \
62
+ --task "pick up the cup" \
63
+ --output result.json
64
+ ```
65
+
66
+ `--base` 指向 `base/` 这一层,不是里面的 `DiffSynth-Studio/`。
67
+
68
+ 默认口径:帧拉到 256×448(`stretch`),progress 是相对当前窗口条件帧的增量,写回前还原成 0–1,`rollout_stride=1`,`distance` 聚合,20 步,seed 42。和论文短任务表同一口径时加上 `--rollout-stride 2`。
69
+
70
+ 每个参数的含义、可选项和默认值:
71
+
72
+ ```bash
73
+ uv run python infer_nimcritic.py --help
74
+ ```
75
+
76
+ 不加载权重、只检查抽帧和参数:
77
+
78
+ ```bash
79
+ uv run python infer_nimcritic.py --self-check
80
+ ```
81
+
82
+ GPU 推理建议预留不少于 24 GB 显存。CPU 推理通过 `--device cpu` 指定,耗时高于 GPU。
83
+
84
+ 结果 JSON 中,`progress` 与 `success` 为逐帧的 0–1 数值。`sampling` 记录所采用的帧下标。
85
+
86
+ ## 引用
87
+
88
+ ```bibtex
89
+ @article{xu2026nimcritic,
90
+ title = {Predictive Long-Horizon Progress Modeling with Action-Aware Quantification},
91
+ author = {Xu, Tianchi and Zheng, Yalin and Zhu, Yangxin and Ren, Ruonan and Fu, Zheng and Wang, Yunlong and Zhong, Yuanxin},
92
+ journal = {arXiv preprint arXiv:2610.32776},
93
+ year = {2026},
94
+ url = {https://arxiv.org/abs/2610.32776}
95
+ }
96
+ ```
97
+
98
+ 基准请同时引用 [LOOM][hf-benchmark]。
99
+
100
+ [hf-model]: https://huggingface.co/RimbotAI/NimCritic
101
+ [hf-benchmark]: https://huggingface.co/datasets/RimbotAI/LOOM
102
+ [arxiv]: https://arxiv.org/abs/2610.32776
103
+ [project]: https://rimbot.com/en/research/nimcritic/
104
+ [demo]: https://critic.rimbot.com/
base/DiffSynth-Studio/Wan-Series-Converted-Safetensors/Wan2.2_VAE.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:0e913a2ca571c75fcb63385a8edadcca73454af5842596cb1ad11e4142590996
3
+ size 1409401152
base/DiffSynth-Studio/Wan-Series-Converted-Safetensors/models_t5_umt5-xxl-enc-bf16.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:d92de679881d38af9c89eff7bb1b6d6c9d96cb2b69831e4027e9ecabdd38eb23
3
+ size 11361845432
base/Wan-AI/Wan2.1-T2V-1.3B/google/umt5-xxl/special_tokens_map.json ADDED
@@ -0,0 +1,308 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "additional_special_tokens": [
3
+ "<extra_id_0>",
4
+ "<extra_id_1>",
5
+ "<extra_id_2>",
6
+ "<extra_id_3>",
7
+ "<extra_id_4>",
8
+ "<extra_id_5>",
9
+ "<extra_id_6>",
10
+ "<extra_id_7>",
11
+ "<extra_id_8>",
12
+ "<extra_id_9>",
13
+ "<extra_id_10>",
14
+ "<extra_id_11>",
15
+ "<extra_id_12>",
16
+ "<extra_id_13>",
17
+ "<extra_id_14>",
18
+ "<extra_id_15>",
19
+ "<extra_id_16>",
20
+ "<extra_id_17>",
21
+ "<extra_id_18>",
22
+ "<extra_id_19>",
23
+ "<extra_id_20>",
24
+ "<extra_id_21>",
25
+ "<extra_id_22>",
26
+ "<extra_id_23>",
27
+ "<extra_id_24>",
28
+ "<extra_id_25>",
29
+ "<extra_id_26>",
30
+ "<extra_id_27>",
31
+ "<extra_id_28>",
32
+ "<extra_id_29>",
33
+ "<extra_id_30>",
34
+ "<extra_id_31>",
35
+ "<extra_id_32>",
36
+ "<extra_id_33>",
37
+ "<extra_id_34>",
38
+ "<extra_id_35>",
39
+ "<extra_id_36>",
40
+ "<extra_id_37>",
41
+ "<extra_id_38>",
42
+ "<extra_id_39>",
43
+ "<extra_id_40>",
44
+ "<extra_id_41>",
45
+ "<extra_id_42>",
46
+ "<extra_id_43>",
47
+ "<extra_id_44>",
48
+ "<extra_id_45>",
49
+ "<extra_id_46>",
50
+ "<extra_id_47>",
51
+ "<extra_id_48>",
52
+ "<extra_id_49>",
53
+ "<extra_id_50>",
54
+ "<extra_id_51>",
55
+ "<extra_id_52>",
56
+ "<extra_id_53>",
57
+ "<extra_id_54>",
58
+ "<extra_id_55>",
59
+ "<extra_id_56>",
60
+ "<extra_id_57>",
61
+ "<extra_id_58>",
62
+ "<extra_id_59>",
63
+ "<extra_id_60>",
64
+ "<extra_id_61>",
65
+ "<extra_id_62>",
66
+ "<extra_id_63>",
67
+ "<extra_id_64>",
68
+ "<extra_id_65>",
69
+ "<extra_id_66>",
70
+ "<extra_id_67>",
71
+ "<extra_id_68>",
72
+ "<extra_id_69>",
73
+ "<extra_id_70>",
74
+ "<extra_id_71>",
75
+ "<extra_id_72>",
76
+ "<extra_id_73>",
77
+ "<extra_id_74>",
78
+ "<extra_id_75>",
79
+ "<extra_id_76>",
80
+ "<extra_id_77>",
81
+ "<extra_id_78>",
82
+ "<extra_id_79>",
83
+ "<extra_id_80>",
84
+ "<extra_id_81>",
85
+ "<extra_id_82>",
86
+ "<extra_id_83>",
87
+ "<extra_id_84>",
88
+ "<extra_id_85>",
89
+ "<extra_id_86>",
90
+ "<extra_id_87>",
91
+ "<extra_id_88>",
92
+ "<extra_id_89>",
93
+ "<extra_id_90>",
94
+ "<extra_id_91>",
95
+ "<extra_id_92>",
96
+ "<extra_id_93>",
97
+ "<extra_id_94>",
98
+ "<extra_id_95>",
99
+ "<extra_id_96>",
100
+ "<extra_id_97>",
101
+ "<extra_id_98>",
102
+ "<extra_id_99>",
103
+ "<extra_id_100>",
104
+ "<extra_id_101>",
105
+ "<extra_id_102>",
106
+ "<extra_id_103>",
107
+ "<extra_id_104>",
108
+ "<extra_id_105>",
109
+ "<extra_id_106>",
110
+ "<extra_id_107>",
111
+ "<extra_id_108>",
112
+ "<extra_id_109>",
113
+ "<extra_id_110>",
114
+ "<extra_id_111>",
115
+ "<extra_id_112>",
116
+ "<extra_id_113>",
117
+ "<extra_id_114>",
118
+ "<extra_id_115>",
119
+ "<extra_id_116>",
120
+ "<extra_id_117>",
121
+ "<extra_id_118>",
122
+ "<extra_id_119>",
123
+ "<extra_id_120>",
124
+ "<extra_id_121>",
125
+ "<extra_id_122>",
126
+ "<extra_id_123>",
127
+ "<extra_id_124>",
128
+ "<extra_id_125>",
129
+ "<extra_id_126>",
130
+ "<extra_id_127>",
131
+ "<extra_id_128>",
132
+ "<extra_id_129>",
133
+ "<extra_id_130>",
134
+ "<extra_id_131>",
135
+ "<extra_id_132>",
136
+ "<extra_id_133>",
137
+ "<extra_id_134>",
138
+ "<extra_id_135>",
139
+ "<extra_id_136>",
140
+ "<extra_id_137>",
141
+ "<extra_id_138>",
142
+ "<extra_id_139>",
143
+ "<extra_id_140>",
144
+ "<extra_id_141>",
145
+ "<extra_id_142>",
146
+ "<extra_id_143>",
147
+ "<extra_id_144>",
148
+ "<extra_id_145>",
149
+ "<extra_id_146>",
150
+ "<extra_id_147>",
151
+ "<extra_id_148>",
152
+ "<extra_id_149>",
153
+ "<extra_id_150>",
154
+ "<extra_id_151>",
155
+ "<extra_id_152>",
156
+ "<extra_id_153>",
157
+ "<extra_id_154>",
158
+ "<extra_id_155>",
159
+ "<extra_id_156>",
160
+ "<extra_id_157>",
161
+ "<extra_id_158>",
162
+ "<extra_id_159>",
163
+ "<extra_id_160>",
164
+ "<extra_id_161>",
165
+ "<extra_id_162>",
166
+ "<extra_id_163>",
167
+ "<extra_id_164>",
168
+ "<extra_id_165>",
169
+ "<extra_id_166>",
170
+ "<extra_id_167>",
171
+ "<extra_id_168>",
172
+ "<extra_id_169>",
173
+ "<extra_id_170>",
174
+ "<extra_id_171>",
175
+ "<extra_id_172>",
176
+ "<extra_id_173>",
177
+ "<extra_id_174>",
178
+ "<extra_id_175>",
179
+ "<extra_id_176>",
180
+ "<extra_id_177>",
181
+ "<extra_id_178>",
182
+ "<extra_id_179>",
183
+ "<extra_id_180>",
184
+ "<extra_id_181>",
185
+ "<extra_id_182>",
186
+ "<extra_id_183>",
187
+ "<extra_id_184>",
188
+ "<extra_id_185>",
189
+ "<extra_id_186>",
190
+ "<extra_id_187>",
191
+ "<extra_id_188>",
192
+ "<extra_id_189>",
193
+ "<extra_id_190>",
194
+ "<extra_id_191>",
195
+ "<extra_id_192>",
196
+ "<extra_id_193>",
197
+ "<extra_id_194>",
198
+ "<extra_id_195>",
199
+ "<extra_id_196>",
200
+ "<extra_id_197>",
201
+ "<extra_id_198>",
202
+ "<extra_id_199>",
203
+ "<extra_id_200>",
204
+ "<extra_id_201>",
205
+ "<extra_id_202>",
206
+ "<extra_id_203>",
207
+ "<extra_id_204>",
208
+ "<extra_id_205>",
209
+ "<extra_id_206>",
210
+ "<extra_id_207>",
211
+ "<extra_id_208>",
212
+ "<extra_id_209>",
213
+ "<extra_id_210>",
214
+ "<extra_id_211>",
215
+ "<extra_id_212>",
216
+ "<extra_id_213>",
217
+ "<extra_id_214>",
218
+ "<extra_id_215>",
219
+ "<extra_id_216>",
220
+ "<extra_id_217>",
221
+ "<extra_id_218>",
222
+ "<extra_id_219>",
223
+ "<extra_id_220>",
224
+ "<extra_id_221>",
225
+ "<extra_id_222>",
226
+ "<extra_id_223>",
227
+ "<extra_id_224>",
228
+ "<extra_id_225>",
229
+ "<extra_id_226>",
230
+ "<extra_id_227>",
231
+ "<extra_id_228>",
232
+ "<extra_id_229>",
233
+ "<extra_id_230>",
234
+ "<extra_id_231>",
235
+ "<extra_id_232>",
236
+ "<extra_id_233>",
237
+ "<extra_id_234>",
238
+ "<extra_id_235>",
239
+ "<extra_id_236>",
240
+ "<extra_id_237>",
241
+ "<extra_id_238>",
242
+ "<extra_id_239>",
243
+ "<extra_id_240>",
244
+ "<extra_id_241>",
245
+ "<extra_id_242>",
246
+ "<extra_id_243>",
247
+ "<extra_id_244>",
248
+ "<extra_id_245>",
249
+ "<extra_id_246>",
250
+ "<extra_id_247>",
251
+ "<extra_id_248>",
252
+ "<extra_id_249>",
253
+ "<extra_id_250>",
254
+ "<extra_id_251>",
255
+ "<extra_id_252>",
256
+ "<extra_id_253>",
257
+ "<extra_id_254>",
258
+ "<extra_id_255>",
259
+ "<extra_id_256>",
260
+ "<extra_id_257>",
261
+ "<extra_id_258>",
262
+ "<extra_id_259>",
263
+ "<extra_id_260>",
264
+ "<extra_id_261>",
265
+ "<extra_id_262>",
266
+ "<extra_id_263>",
267
+ "<extra_id_264>",
268
+ "<extra_id_265>",
269
+ "<extra_id_266>",
270
+ "<extra_id_267>",
271
+ "<extra_id_268>",
272
+ "<extra_id_269>",
273
+ "<extra_id_270>",
274
+ "<extra_id_271>",
275
+ "<extra_id_272>",
276
+ "<extra_id_273>",
277
+ "<extra_id_274>",
278
+ "<extra_id_275>",
279
+ "<extra_id_276>",
280
+ "<extra_id_277>",
281
+ "<extra_id_278>",
282
+ "<extra_id_279>",
283
+ "<extra_id_280>",
284
+ "<extra_id_281>",
285
+ "<extra_id_282>",
286
+ "<extra_id_283>",
287
+ "<extra_id_284>",
288
+ "<extra_id_285>",
289
+ "<extra_id_286>",
290
+ "<extra_id_287>",
291
+ "<extra_id_288>",
292
+ "<extra_id_289>",
293
+ "<extra_id_290>",
294
+ "<extra_id_291>",
295
+ "<extra_id_292>",
296
+ "<extra_id_293>",
297
+ "<extra_id_294>",
298
+ "<extra_id_295>",
299
+ "<extra_id_296>",
300
+ "<extra_id_297>",
301
+ "<extra_id_298>",
302
+ "<extra_id_299>"
303
+ ],
304
+ "bos_token": "<s>",
305
+ "eos_token": "</s>",
306
+ "pad_token": "<pad>",
307
+ "unk_token": "<unk>"
308
+ }
base/Wan-AI/Wan2.1-T2V-1.3B/google/umt5-xxl/spiece.model ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:e3909a67b780650b35cf529ac782ad2b6b26e6d1f849d3fbb6a872905f452458
3
+ size 4548313
base/Wan-AI/Wan2.1-T2V-1.3B/google/umt5-xxl/tokenizer.json ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:6e197b4d3dbd71da14b4eb255f4fa91c9c1f2068b20a2de2472967ca3d22602b
3
+ size 16837417
base/Wan-AI/Wan2.1-T2V-1.3B/google/umt5-xxl/tokenizer_config.json ADDED
@@ -0,0 +1,2748 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "added_tokens_decoder": {
3
+ "0": {
4
+ "content": "<pad>",
5
+ "lstrip": false,
6
+ "normalized": false,
7
+ "rstrip": false,
8
+ "single_word": false,
9
+ "special": true
10
+ },
11
+ "1": {
12
+ "content": "</s>",
13
+ "lstrip": false,
14
+ "normalized": false,
15
+ "rstrip": false,
16
+ "single_word": false,
17
+ "special": true
18
+ },
19
+ "2": {
20
+ "content": "<s>",
21
+ "lstrip": false,
22
+ "normalized": false,
23
+ "rstrip": false,
24
+ "single_word": false,
25
+ "special": true
26
+ },
27
+ "3": {
28
+ "content": "<unk>",
29
+ "lstrip": false,
30
+ "normalized": false,
31
+ "rstrip": false,
32
+ "single_word": false,
33
+ "special": true
34
+ },
35
+ "256000": {
36
+ "content": "<extra_id_299>",
37
+ "lstrip": false,
38
+ "normalized": false,
39
+ "rstrip": false,
40
+ "single_word": false,
41
+ "special": true
42
+ },
43
+ "256001": {
44
+ "content": "<extra_id_298>",
45
+ "lstrip": false,
46
+ "normalized": false,
47
+ "rstrip": false,
48
+ "single_word": false,
49
+ "special": true
50
+ },
51
+ "256002": {
52
+ "content": "<extra_id_297>",
53
+ "lstrip": false,
54
+ "normalized": false,
55
+ "rstrip": false,
56
+ "single_word": false,
57
+ "special": true
58
+ },
59
+ "256003": {
60
+ "content": "<extra_id_296>",
61
+ "lstrip": false,
62
+ "normalized": false,
63
+ "rstrip": false,
64
+ "single_word": false,
65
+ "special": true
66
+ },
67
+ "256004": {
68
+ "content": "<extra_id_295>",
69
+ "lstrip": false,
70
+ "normalized": false,
71
+ "rstrip": false,
72
+ "single_word": false,
73
+ "special": true
74
+ },
75
+ "256005": {
76
+ "content": "<extra_id_294>",
77
+ "lstrip": false,
78
+ "normalized": false,
79
+ "rstrip": false,
80
+ "single_word": false,
81
+ "special": true
82
+ },
83
+ "256006": {
84
+ "content": "<extra_id_293>",
85
+ "lstrip": false,
86
+ "normalized": false,
87
+ "rstrip": false,
88
+ "single_word": false,
89
+ "special": true
90
+ },
91
+ "256007": {
92
+ "content": "<extra_id_292>",
93
+ "lstrip": false,
94
+ "normalized": false,
95
+ "rstrip": false,
96
+ "single_word": false,
97
+ "special": true
98
+ },
99
+ "256008": {
100
+ "content": "<extra_id_291>",
101
+ "lstrip": false,
102
+ "normalized": false,
103
+ "rstrip": false,
104
+ "single_word": false,
105
+ "special": true
106
+ },
107
+ "256009": {
108
+ "content": "<extra_id_290>",
109
+ "lstrip": false,
110
+ "normalized": false,
111
+ "rstrip": false,
112
+ "single_word": false,
113
+ "special": true
114
+ },
115
+ "256010": {
116
+ "content": "<extra_id_289>",
117
+ "lstrip": false,
118
+ "normalized": false,
119
+ "rstrip": false,
120
+ "single_word": false,
121
+ "special": true
122
+ },
123
+ "256011": {
124
+ "content": "<extra_id_288>",
125
+ "lstrip": false,
126
+ "normalized": false,
127
+ "rstrip": false,
128
+ "single_word": false,
129
+ "special": true
130
+ },
131
+ "256012": {
132
+ "content": "<extra_id_287>",
133
+ "lstrip": false,
134
+ "normalized": false,
135
+ "rstrip": false,
136
+ "single_word": false,
137
+ "special": true
138
+ },
139
+ "256013": {
140
+ "content": "<extra_id_286>",
141
+ "lstrip": false,
142
+ "normalized": false,
143
+ "rstrip": false,
144
+ "single_word": false,
145
+ "special": true
146
+ },
147
+ "256014": {
148
+ "content": "<extra_id_285>",
149
+ "lstrip": false,
150
+ "normalized": false,
151
+ "rstrip": false,
152
+ "single_word": false,
153
+ "special": true
154
+ },
155
+ "256015": {
156
+ "content": "<extra_id_284>",
157
+ "lstrip": false,
158
+ "normalized": false,
159
+ "rstrip": false,
160
+ "single_word": false,
161
+ "special": true
162
+ },
163
+ "256016": {
164
+ "content": "<extra_id_283>",
165
+ "lstrip": false,
166
+ "normalized": false,
167
+ "rstrip": false,
168
+ "single_word": false,
169
+ "special": true
170
+ },
171
+ "256017": {
172
+ "content": "<extra_id_282>",
173
+ "lstrip": false,
174
+ "normalized": false,
175
+ "rstrip": false,
176
+ "single_word": false,
177
+ "special": true
178
+ },
179
+ "256018": {
180
+ "content": "<extra_id_281>",
181
+ "lstrip": false,
182
+ "normalized": false,
183
+ "rstrip": false,
184
+ "single_word": false,
185
+ "special": true
186
+ },
187
+ "256019": {
188
+ "content": "<extra_id_280>",
189
+ "lstrip": false,
190
+ "normalized": false,
191
+ "rstrip": false,
192
+ "single_word": false,
193
+ "special": true
194
+ },
195
+ "256020": {
196
+ "content": "<extra_id_279>",
197
+ "lstrip": false,
198
+ "normalized": false,
199
+ "rstrip": false,
200
+ "single_word": false,
201
+ "special": true
202
+ },
203
+ "256021": {
204
+ "content": "<extra_id_278>",
205
+ "lstrip": false,
206
+ "normalized": false,
207
+ "rstrip": false,
208
+ "single_word": false,
209
+ "special": true
210
+ },
211
+ "256022": {
212
+ "content": "<extra_id_277>",
213
+ "lstrip": false,
214
+ "normalized": false,
215
+ "rstrip": false,
216
+ "single_word": false,
217
+ "special": true
218
+ },
219
+ "256023": {
220
+ "content": "<extra_id_276>",
221
+ "lstrip": false,
222
+ "normalized": false,
223
+ "rstrip": false,
224
+ "single_word": false,
225
+ "special": true
226
+ },
227
+ "256024": {
228
+ "content": "<extra_id_275>",
229
+ "lstrip": false,
230
+ "normalized": false,
231
+ "rstrip": false,
232
+ "single_word": false,
233
+ "special": true
234
+ },
235
+ "256025": {
236
+ "content": "<extra_id_274>",
237
+ "lstrip": false,
238
+ "normalized": false,
239
+ "rstrip": false,
240
+ "single_word": false,
241
+ "special": true
242
+ },
243
+ "256026": {
244
+ "content": "<extra_id_273>",
245
+ "lstrip": false,
246
+ "normalized": false,
247
+ "rstrip": false,
248
+ "single_word": false,
249
+ "special": true
250
+ },
251
+ "256027": {
252
+ "content": "<extra_id_272>",
253
+ "lstrip": false,
254
+ "normalized": false,
255
+ "rstrip": false,
256
+ "single_word": false,
257
+ "special": true
258
+ },
259
+ "256028": {
260
+ "content": "<extra_id_271>",
261
+ "lstrip": false,
262
+ "normalized": false,
263
+ "rstrip": false,
264
+ "single_word": false,
265
+ "special": true
266
+ },
267
+ "256029": {
268
+ "content": "<extra_id_270>",
269
+ "lstrip": false,
270
+ "normalized": false,
271
+ "rstrip": false,
272
+ "single_word": false,
273
+ "special": true
274
+ },
275
+ "256030": {
276
+ "content": "<extra_id_269>",
277
+ "lstrip": false,
278
+ "normalized": false,
279
+ "rstrip": false,
280
+ "single_word": false,
281
+ "special": true
282
+ },
283
+ "256031": {
284
+ "content": "<extra_id_268>",
285
+ "lstrip": false,
286
+ "normalized": false,
287
+ "rstrip": false,
288
+ "single_word": false,
289
+ "special": true
290
+ },
291
+ "256032": {
292
+ "content": "<extra_id_267>",
293
+ "lstrip": false,
294
+ "normalized": false,
295
+ "rstrip": false,
296
+ "single_word": false,
297
+ "special": true
298
+ },
299
+ "256033": {
300
+ "content": "<extra_id_266>",
301
+ "lstrip": false,
302
+ "normalized": false,
303
+ "rstrip": false,
304
+ "single_word": false,
305
+ "special": true
306
+ },
307
+ "256034": {
308
+ "content": "<extra_id_265>",
309
+ "lstrip": false,
310
+ "normalized": false,
311
+ "rstrip": false,
312
+ "single_word": false,
313
+ "special": true
314
+ },
315
+ "256035": {
316
+ "content": "<extra_id_264>",
317
+ "lstrip": false,
318
+ "normalized": false,
319
+ "rstrip": false,
320
+ "single_word": false,
321
+ "special": true
322
+ },
323
+ "256036": {
324
+ "content": "<extra_id_263>",
325
+ "lstrip": false,
326
+ "normalized": false,
327
+ "rstrip": false,
328
+ "single_word": false,
329
+ "special": true
330
+ },
331
+ "256037": {
332
+ "content": "<extra_id_262>",
333
+ "lstrip": false,
334
+ "normalized": false,
335
+ "rstrip": false,
336
+ "single_word": false,
337
+ "special": true
338
+ },
339
+ "256038": {
340
+ "content": "<extra_id_261>",
341
+ "lstrip": false,
342
+ "normalized": false,
343
+ "rstrip": false,
344
+ "single_word": false,
345
+ "special": true
346
+ },
347
+ "256039": {
348
+ "content": "<extra_id_260>",
349
+ "lstrip": false,
350
+ "normalized": false,
351
+ "rstrip": false,
352
+ "single_word": false,
353
+ "special": true
354
+ },
355
+ "256040": {
356
+ "content": "<extra_id_259>",
357
+ "lstrip": false,
358
+ "normalized": false,
359
+ "rstrip": false,
360
+ "single_word": false,
361
+ "special": true
362
+ },
363
+ "256041": {
364
+ "content": "<extra_id_258>",
365
+ "lstrip": false,
366
+ "normalized": false,
367
+ "rstrip": false,
368
+ "single_word": false,
369
+ "special": true
370
+ },
371
+ "256042": {
372
+ "content": "<extra_id_257>",
373
+ "lstrip": false,
374
+ "normalized": false,
375
+ "rstrip": false,
376
+ "single_word": false,
377
+ "special": true
378
+ },
379
+ "256043": {
380
+ "content": "<extra_id_256>",
381
+ "lstrip": false,
382
+ "normalized": false,
383
+ "rstrip": false,
384
+ "single_word": false,
385
+ "special": true
386
+ },
387
+ "256044": {
388
+ "content": "<extra_id_255>",
389
+ "lstrip": false,
390
+ "normalized": false,
391
+ "rstrip": false,
392
+ "single_word": false,
393
+ "special": true
394
+ },
395
+ "256045": {
396
+ "content": "<extra_id_254>",
397
+ "lstrip": false,
398
+ "normalized": false,
399
+ "rstrip": false,
400
+ "single_word": false,
401
+ "special": true
402
+ },
403
+ "256046": {
404
+ "content": "<extra_id_253>",
405
+ "lstrip": false,
406
+ "normalized": false,
407
+ "rstrip": false,
408
+ "single_word": false,
409
+ "special": true
410
+ },
411
+ "256047": {
412
+ "content": "<extra_id_252>",
413
+ "lstrip": false,
414
+ "normalized": false,
415
+ "rstrip": false,
416
+ "single_word": false,
417
+ "special": true
418
+ },
419
+ "256048": {
420
+ "content": "<extra_id_251>",
421
+ "lstrip": false,
422
+ "normalized": false,
423
+ "rstrip": false,
424
+ "single_word": false,
425
+ "special": true
426
+ },
427
+ "256049": {
428
+ "content": "<extra_id_250>",
429
+ "lstrip": false,
430
+ "normalized": false,
431
+ "rstrip": false,
432
+ "single_word": false,
433
+ "special": true
434
+ },
435
+ "256050": {
436
+ "content": "<extra_id_249>",
437
+ "lstrip": false,
438
+ "normalized": false,
439
+ "rstrip": false,
440
+ "single_word": false,
441
+ "special": true
442
+ },
443
+ "256051": {
444
+ "content": "<extra_id_248>",
445
+ "lstrip": false,
446
+ "normalized": false,
447
+ "rstrip": false,
448
+ "single_word": false,
449
+ "special": true
450
+ },
451
+ "256052": {
452
+ "content": "<extra_id_247>",
453
+ "lstrip": false,
454
+ "normalized": false,
455
+ "rstrip": false,
456
+ "single_word": false,
457
+ "special": true
458
+ },
459
+ "256053": {
460
+ "content": "<extra_id_246>",
461
+ "lstrip": false,
462
+ "normalized": false,
463
+ "rstrip": false,
464
+ "single_word": false,
465
+ "special": true
466
+ },
467
+ "256054": {
468
+ "content": "<extra_id_245>",
469
+ "lstrip": false,
470
+ "normalized": false,
471
+ "rstrip": false,
472
+ "single_word": false,
473
+ "special": true
474
+ },
475
+ "256055": {
476
+ "content": "<extra_id_244>",
477
+ "lstrip": false,
478
+ "normalized": false,
479
+ "rstrip": false,
480
+ "single_word": false,
481
+ "special": true
482
+ },
483
+ "256056": {
484
+ "content": "<extra_id_243>",
485
+ "lstrip": false,
486
+ "normalized": false,
487
+ "rstrip": false,
488
+ "single_word": false,
489
+ "special": true
490
+ },
491
+ "256057": {
492
+ "content": "<extra_id_242>",
493
+ "lstrip": false,
494
+ "normalized": false,
495
+ "rstrip": false,
496
+ "single_word": false,
497
+ "special": true
498
+ },
499
+ "256058": {
500
+ "content": "<extra_id_241>",
501
+ "lstrip": false,
502
+ "normalized": false,
503
+ "rstrip": false,
504
+ "single_word": false,
505
+ "special": true
506
+ },
507
+ "256059": {
508
+ "content": "<extra_id_240>",
509
+ "lstrip": false,
510
+ "normalized": false,
511
+ "rstrip": false,
512
+ "single_word": false,
513
+ "special": true
514
+ },
515
+ "256060": {
516
+ "content": "<extra_id_239>",
517
+ "lstrip": false,
518
+ "normalized": false,
519
+ "rstrip": false,
520
+ "single_word": false,
521
+ "special": true
522
+ },
523
+ "256061": {
524
+ "content": "<extra_id_238>",
525
+ "lstrip": false,
526
+ "normalized": false,
527
+ "rstrip": false,
528
+ "single_word": false,
529
+ "special": true
530
+ },
531
+ "256062": {
532
+ "content": "<extra_id_237>",
533
+ "lstrip": false,
534
+ "normalized": false,
535
+ "rstrip": false,
536
+ "single_word": false,
537
+ "special": true
538
+ },
539
+ "256063": {
540
+ "content": "<extra_id_236>",
541
+ "lstrip": false,
542
+ "normalized": false,
543
+ "rstrip": false,
544
+ "single_word": false,
545
+ "special": true
546
+ },
547
+ "256064": {
548
+ "content": "<extra_id_235>",
549
+ "lstrip": false,
550
+ "normalized": false,
551
+ "rstrip": false,
552
+ "single_word": false,
553
+ "special": true
554
+ },
555
+ "256065": {
556
+ "content": "<extra_id_234>",
557
+ "lstrip": false,
558
+ "normalized": false,
559
+ "rstrip": false,
560
+ "single_word": false,
561
+ "special": true
562
+ },
563
+ "256066": {
564
+ "content": "<extra_id_233>",
565
+ "lstrip": false,
566
+ "normalized": false,
567
+ "rstrip": false,
568
+ "single_word": false,
569
+ "special": true
570
+ },
571
+ "256067": {
572
+ "content": "<extra_id_232>",
573
+ "lstrip": false,
574
+ "normalized": false,
575
+ "rstrip": false,
576
+ "single_word": false,
577
+ "special": true
578
+ },
579
+ "256068": {
580
+ "content": "<extra_id_231>",
581
+ "lstrip": false,
582
+ "normalized": false,
583
+ "rstrip": false,
584
+ "single_word": false,
585
+ "special": true
586
+ },
587
+ "256069": {
588
+ "content": "<extra_id_230>",
589
+ "lstrip": false,
590
+ "normalized": false,
591
+ "rstrip": false,
592
+ "single_word": false,
593
+ "special": true
594
+ },
595
+ "256070": {
596
+ "content": "<extra_id_229>",
597
+ "lstrip": false,
598
+ "normalized": false,
599
+ "rstrip": false,
600
+ "single_word": false,
601
+ "special": true
602
+ },
603
+ "256071": {
604
+ "content": "<extra_id_228>",
605
+ "lstrip": false,
606
+ "normalized": false,
607
+ "rstrip": false,
608
+ "single_word": false,
609
+ "special": true
610
+ },
611
+ "256072": {
612
+ "content": "<extra_id_227>",
613
+ "lstrip": false,
614
+ "normalized": false,
615
+ "rstrip": false,
616
+ "single_word": false,
617
+ "special": true
618
+ },
619
+ "256073": {
620
+ "content": "<extra_id_226>",
621
+ "lstrip": false,
622
+ "normalized": false,
623
+ "rstrip": false,
624
+ "single_word": false,
625
+ "special": true
626
+ },
627
+ "256074": {
628
+ "content": "<extra_id_225>",
629
+ "lstrip": false,
630
+ "normalized": false,
631
+ "rstrip": false,
632
+ "single_word": false,
633
+ "special": true
634
+ },
635
+ "256075": {
636
+ "content": "<extra_id_224>",
637
+ "lstrip": false,
638
+ "normalized": false,
639
+ "rstrip": false,
640
+ "single_word": false,
641
+ "special": true
642
+ },
643
+ "256076": {
644
+ "content": "<extra_id_223>",
645
+ "lstrip": false,
646
+ "normalized": false,
647
+ "rstrip": false,
648
+ "single_word": false,
649
+ "special": true
650
+ },
651
+ "256077": {
652
+ "content": "<extra_id_222>",
653
+ "lstrip": false,
654
+ "normalized": false,
655
+ "rstrip": false,
656
+ "single_word": false,
657
+ "special": true
658
+ },
659
+ "256078": {
660
+ "content": "<extra_id_221>",
661
+ "lstrip": false,
662
+ "normalized": false,
663
+ "rstrip": false,
664
+ "single_word": false,
665
+ "special": true
666
+ },
667
+ "256079": {
668
+ "content": "<extra_id_220>",
669
+ "lstrip": false,
670
+ "normalized": false,
671
+ "rstrip": false,
672
+ "single_word": false,
673
+ "special": true
674
+ },
675
+ "256080": {
676
+ "content": "<extra_id_219>",
677
+ "lstrip": false,
678
+ "normalized": false,
679
+ "rstrip": false,
680
+ "single_word": false,
681
+ "special": true
682
+ },
683
+ "256081": {
684
+ "content": "<extra_id_218>",
685
+ "lstrip": false,
686
+ "normalized": false,
687
+ "rstrip": false,
688
+ "single_word": false,
689
+ "special": true
690
+ },
691
+ "256082": {
692
+ "content": "<extra_id_217>",
693
+ "lstrip": false,
694
+ "normalized": false,
695
+ "rstrip": false,
696
+ "single_word": false,
697
+ "special": true
698
+ },
699
+ "256083": {
700
+ "content": "<extra_id_216>",
701
+ "lstrip": false,
702
+ "normalized": false,
703
+ "rstrip": false,
704
+ "single_word": false,
705
+ "special": true
706
+ },
707
+ "256084": {
708
+ "content": "<extra_id_215>",
709
+ "lstrip": false,
710
+ "normalized": false,
711
+ "rstrip": false,
712
+ "single_word": false,
713
+ "special": true
714
+ },
715
+ "256085": {
716
+ "content": "<extra_id_214>",
717
+ "lstrip": false,
718
+ "normalized": false,
719
+ "rstrip": false,
720
+ "single_word": false,
721
+ "special": true
722
+ },
723
+ "256086": {
724
+ "content": "<extra_id_213>",
725
+ "lstrip": false,
726
+ "normalized": false,
727
+ "rstrip": false,
728
+ "single_word": false,
729
+ "special": true
730
+ },
731
+ "256087": {
732
+ "content": "<extra_id_212>",
733
+ "lstrip": false,
734
+ "normalized": false,
735
+ "rstrip": false,
736
+ "single_word": false,
737
+ "special": true
738
+ },
739
+ "256088": {
740
+ "content": "<extra_id_211>",
741
+ "lstrip": false,
742
+ "normalized": false,
743
+ "rstrip": false,
744
+ "single_word": false,
745
+ "special": true
746
+ },
747
+ "256089": {
748
+ "content": "<extra_id_210>",
749
+ "lstrip": false,
750
+ "normalized": false,
751
+ "rstrip": false,
752
+ "single_word": false,
753
+ "special": true
754
+ },
755
+ "256090": {
756
+ "content": "<extra_id_209>",
757
+ "lstrip": false,
758
+ "normalized": false,
759
+ "rstrip": false,
760
+ "single_word": false,
761
+ "special": true
762
+ },
763
+ "256091": {
764
+ "content": "<extra_id_208>",
765
+ "lstrip": false,
766
+ "normalized": false,
767
+ "rstrip": false,
768
+ "single_word": false,
769
+ "special": true
770
+ },
771
+ "256092": {
772
+ "content": "<extra_id_207>",
773
+ "lstrip": false,
774
+ "normalized": false,
775
+ "rstrip": false,
776
+ "single_word": false,
777
+ "special": true
778
+ },
779
+ "256093": {
780
+ "content": "<extra_id_206>",
781
+ "lstrip": false,
782
+ "normalized": false,
783
+ "rstrip": false,
784
+ "single_word": false,
785
+ "special": true
786
+ },
787
+ "256094": {
788
+ "content": "<extra_id_205>",
789
+ "lstrip": false,
790
+ "normalized": false,
791
+ "rstrip": false,
792
+ "single_word": false,
793
+ "special": true
794
+ },
795
+ "256095": {
796
+ "content": "<extra_id_204>",
797
+ "lstrip": false,
798
+ "normalized": false,
799
+ "rstrip": false,
800
+ "single_word": false,
801
+ "special": true
802
+ },
803
+ "256096": {
804
+ "content": "<extra_id_203>",
805
+ "lstrip": false,
806
+ "normalized": false,
807
+ "rstrip": false,
808
+ "single_word": false,
809
+ "special": true
810
+ },
811
+ "256097": {
812
+ "content": "<extra_id_202>",
813
+ "lstrip": false,
814
+ "normalized": false,
815
+ "rstrip": false,
816
+ "single_word": false,
817
+ "special": true
818
+ },
819
+ "256098": {
820
+ "content": "<extra_id_201>",
821
+ "lstrip": false,
822
+ "normalized": false,
823
+ "rstrip": false,
824
+ "single_word": false,
825
+ "special": true
826
+ },
827
+ "256099": {
828
+ "content": "<extra_id_200>",
829
+ "lstrip": false,
830
+ "normalized": false,
831
+ "rstrip": false,
832
+ "single_word": false,
833
+ "special": true
834
+ },
835
+ "256100": {
836
+ "content": "<extra_id_199>",
837
+ "lstrip": false,
838
+ "normalized": false,
839
+ "rstrip": false,
840
+ "single_word": false,
841
+ "special": true
842
+ },
843
+ "256101": {
844
+ "content": "<extra_id_198>",
845
+ "lstrip": false,
846
+ "normalized": false,
847
+ "rstrip": false,
848
+ "single_word": false,
849
+ "special": true
850
+ },
851
+ "256102": {
852
+ "content": "<extra_id_197>",
853
+ "lstrip": false,
854
+ "normalized": false,
855
+ "rstrip": false,
856
+ "single_word": false,
857
+ "special": true
858
+ },
859
+ "256103": {
860
+ "content": "<extra_id_196>",
861
+ "lstrip": false,
862
+ "normalized": false,
863
+ "rstrip": false,
864
+ "single_word": false,
865
+ "special": true
866
+ },
867
+ "256104": {
868
+ "content": "<extra_id_195>",
869
+ "lstrip": false,
870
+ "normalized": false,
871
+ "rstrip": false,
872
+ "single_word": false,
873
+ "special": true
874
+ },
875
+ "256105": {
876
+ "content": "<extra_id_194>",
877
+ "lstrip": false,
878
+ "normalized": false,
879
+ "rstrip": false,
880
+ "single_word": false,
881
+ "special": true
882
+ },
883
+ "256106": {
884
+ "content": "<extra_id_193>",
885
+ "lstrip": false,
886
+ "normalized": false,
887
+ "rstrip": false,
888
+ "single_word": false,
889
+ "special": true
890
+ },
891
+ "256107": {
892
+ "content": "<extra_id_192>",
893
+ "lstrip": false,
894
+ "normalized": false,
895
+ "rstrip": false,
896
+ "single_word": false,
897
+ "special": true
898
+ },
899
+ "256108": {
900
+ "content": "<extra_id_191>",
901
+ "lstrip": false,
902
+ "normalized": false,
903
+ "rstrip": false,
904
+ "single_word": false,
905
+ "special": true
906
+ },
907
+ "256109": {
908
+ "content": "<extra_id_190>",
909
+ "lstrip": false,
910
+ "normalized": false,
911
+ "rstrip": false,
912
+ "single_word": false,
913
+ "special": true
914
+ },
915
+ "256110": {
916
+ "content": "<extra_id_189>",
917
+ "lstrip": false,
918
+ "normalized": false,
919
+ "rstrip": false,
920
+ "single_word": false,
921
+ "special": true
922
+ },
923
+ "256111": {
924
+ "content": "<extra_id_188>",
925
+ "lstrip": false,
926
+ "normalized": false,
927
+ "rstrip": false,
928
+ "single_word": false,
929
+ "special": true
930
+ },
931
+ "256112": {
932
+ "content": "<extra_id_187>",
933
+ "lstrip": false,
934
+ "normalized": false,
935
+ "rstrip": false,
936
+ "single_word": false,
937
+ "special": true
938
+ },
939
+ "256113": {
940
+ "content": "<extra_id_186>",
941
+ "lstrip": false,
942
+ "normalized": false,
943
+ "rstrip": false,
944
+ "single_word": false,
945
+ "special": true
946
+ },
947
+ "256114": {
948
+ "content": "<extra_id_185>",
949
+ "lstrip": false,
950
+ "normalized": false,
951
+ "rstrip": false,
952
+ "single_word": false,
953
+ "special": true
954
+ },
955
+ "256115": {
956
+ "content": "<extra_id_184>",
957
+ "lstrip": false,
958
+ "normalized": false,
959
+ "rstrip": false,
960
+ "single_word": false,
961
+ "special": true
962
+ },
963
+ "256116": {
964
+ "content": "<extra_id_183>",
965
+ "lstrip": false,
966
+ "normalized": false,
967
+ "rstrip": false,
968
+ "single_word": false,
969
+ "special": true
970
+ },
971
+ "256117": {
972
+ "content": "<extra_id_182>",
973
+ "lstrip": false,
974
+ "normalized": false,
975
+ "rstrip": false,
976
+ "single_word": false,
977
+ "special": true
978
+ },
979
+ "256118": {
980
+ "content": "<extra_id_181>",
981
+ "lstrip": false,
982
+ "normalized": false,
983
+ "rstrip": false,
984
+ "single_word": false,
985
+ "special": true
986
+ },
987
+ "256119": {
988
+ "content": "<extra_id_180>",
989
+ "lstrip": false,
990
+ "normalized": false,
991
+ "rstrip": false,
992
+ "single_word": false,
993
+ "special": true
994
+ },
995
+ "256120": {
996
+ "content": "<extra_id_179>",
997
+ "lstrip": false,
998
+ "normalized": false,
999
+ "rstrip": false,
1000
+ "single_word": false,
1001
+ "special": true
1002
+ },
1003
+ "256121": {
1004
+ "content": "<extra_id_178>",
1005
+ "lstrip": false,
1006
+ "normalized": false,
1007
+ "rstrip": false,
1008
+ "single_word": false,
1009
+ "special": true
1010
+ },
1011
+ "256122": {
1012
+ "content": "<extra_id_177>",
1013
+ "lstrip": false,
1014
+ "normalized": false,
1015
+ "rstrip": false,
1016
+ "single_word": false,
1017
+ "special": true
1018
+ },
1019
+ "256123": {
1020
+ "content": "<extra_id_176>",
1021
+ "lstrip": false,
1022
+ "normalized": false,
1023
+ "rstrip": false,
1024
+ "single_word": false,
1025
+ "special": true
1026
+ },
1027
+ "256124": {
1028
+ "content": "<extra_id_175>",
1029
+ "lstrip": false,
1030
+ "normalized": false,
1031
+ "rstrip": false,
1032
+ "single_word": false,
1033
+ "special": true
1034
+ },
1035
+ "256125": {
1036
+ "content": "<extra_id_174>",
1037
+ "lstrip": false,
1038
+ "normalized": false,
1039
+ "rstrip": false,
1040
+ "single_word": false,
1041
+ "special": true
1042
+ },
1043
+ "256126": {
1044
+ "content": "<extra_id_173>",
1045
+ "lstrip": false,
1046
+ "normalized": false,
1047
+ "rstrip": false,
1048
+ "single_word": false,
1049
+ "special": true
1050
+ },
1051
+ "256127": {
1052
+ "content": "<extra_id_172>",
1053
+ "lstrip": false,
1054
+ "normalized": false,
1055
+ "rstrip": false,
1056
+ "single_word": false,
1057
+ "special": true
1058
+ },
1059
+ "256128": {
1060
+ "content": "<extra_id_171>",
1061
+ "lstrip": false,
1062
+ "normalized": false,
1063
+ "rstrip": false,
1064
+ "single_word": false,
1065
+ "special": true
1066
+ },
1067
+ "256129": {
1068
+ "content": "<extra_id_170>",
1069
+ "lstrip": false,
1070
+ "normalized": false,
1071
+ "rstrip": false,
1072
+ "single_word": false,
1073
+ "special": true
1074
+ },
1075
+ "256130": {
1076
+ "content": "<extra_id_169>",
1077
+ "lstrip": false,
1078
+ "normalized": false,
1079
+ "rstrip": false,
1080
+ "single_word": false,
1081
+ "special": true
1082
+ },
1083
+ "256131": {
1084
+ "content": "<extra_id_168>",
1085
+ "lstrip": false,
1086
+ "normalized": false,
1087
+ "rstrip": false,
1088
+ "single_word": false,
1089
+ "special": true
1090
+ },
1091
+ "256132": {
1092
+ "content": "<extra_id_167>",
1093
+ "lstrip": false,
1094
+ "normalized": false,
1095
+ "rstrip": false,
1096
+ "single_word": false,
1097
+ "special": true
1098
+ },
1099
+ "256133": {
1100
+ "content": "<extra_id_166>",
1101
+ "lstrip": false,
1102
+ "normalized": false,
1103
+ "rstrip": false,
1104
+ "single_word": false,
1105
+ "special": true
1106
+ },
1107
+ "256134": {
1108
+ "content": "<extra_id_165>",
1109
+ "lstrip": false,
1110
+ "normalized": false,
1111
+ "rstrip": false,
1112
+ "single_word": false,
1113
+ "special": true
1114
+ },
1115
+ "256135": {
1116
+ "content": "<extra_id_164>",
1117
+ "lstrip": false,
1118
+ "normalized": false,
1119
+ "rstrip": false,
1120
+ "single_word": false,
1121
+ "special": true
1122
+ },
1123
+ "256136": {
1124
+ "content": "<extra_id_163>",
1125
+ "lstrip": false,
1126
+ "normalized": false,
1127
+ "rstrip": false,
1128
+ "single_word": false,
1129
+ "special": true
1130
+ },
1131
+ "256137": {
1132
+ "content": "<extra_id_162>",
1133
+ "lstrip": false,
1134
+ "normalized": false,
1135
+ "rstrip": false,
1136
+ "single_word": false,
1137
+ "special": true
1138
+ },
1139
+ "256138": {
1140
+ "content": "<extra_id_161>",
1141
+ "lstrip": false,
1142
+ "normalized": false,
1143
+ "rstrip": false,
1144
+ "single_word": false,
1145
+ "special": true
1146
+ },
1147
+ "256139": {
1148
+ "content": "<extra_id_160>",
1149
+ "lstrip": false,
1150
+ "normalized": false,
1151
+ "rstrip": false,
1152
+ "single_word": false,
1153
+ "special": true
1154
+ },
1155
+ "256140": {
1156
+ "content": "<extra_id_159>",
1157
+ "lstrip": false,
1158
+ "normalized": false,
1159
+ "rstrip": false,
1160
+ "single_word": false,
1161
+ "special": true
1162
+ },
1163
+ "256141": {
1164
+ "content": "<extra_id_158>",
1165
+ "lstrip": false,
1166
+ "normalized": false,
1167
+ "rstrip": false,
1168
+ "single_word": false,
1169
+ "special": true
1170
+ },
1171
+ "256142": {
1172
+ "content": "<extra_id_157>",
1173
+ "lstrip": false,
1174
+ "normalized": false,
1175
+ "rstrip": false,
1176
+ "single_word": false,
1177
+ "special": true
1178
+ },
1179
+ "256143": {
1180
+ "content": "<extra_id_156>",
1181
+ "lstrip": false,
1182
+ "normalized": false,
1183
+ "rstrip": false,
1184
+ "single_word": false,
1185
+ "special": true
1186
+ },
1187
+ "256144": {
1188
+ "content": "<extra_id_155>",
1189
+ "lstrip": false,
1190
+ "normalized": false,
1191
+ "rstrip": false,
1192
+ "single_word": false,
1193
+ "special": true
1194
+ },
1195
+ "256145": {
1196
+ "content": "<extra_id_154>",
1197
+ "lstrip": false,
1198
+ "normalized": false,
1199
+ "rstrip": false,
1200
+ "single_word": false,
1201
+ "special": true
1202
+ },
1203
+ "256146": {
1204
+ "content": "<extra_id_153>",
1205
+ "lstrip": false,
1206
+ "normalized": false,
1207
+ "rstrip": false,
1208
+ "single_word": false,
1209
+ "special": true
1210
+ },
1211
+ "256147": {
1212
+ "content": "<extra_id_152>",
1213
+ "lstrip": false,
1214
+ "normalized": false,
1215
+ "rstrip": false,
1216
+ "single_word": false,
1217
+ "special": true
1218
+ },
1219
+ "256148": {
1220
+ "content": "<extra_id_151>",
1221
+ "lstrip": false,
1222
+ "normalized": false,
1223
+ "rstrip": false,
1224
+ "single_word": false,
1225
+ "special": true
1226
+ },
1227
+ "256149": {
1228
+ "content": "<extra_id_150>",
1229
+ "lstrip": false,
1230
+ "normalized": false,
1231
+ "rstrip": false,
1232
+ "single_word": false,
1233
+ "special": true
1234
+ },
1235
+ "256150": {
1236
+ "content": "<extra_id_149>",
1237
+ "lstrip": false,
1238
+ "normalized": false,
1239
+ "rstrip": false,
1240
+ "single_word": false,
1241
+ "special": true
1242
+ },
1243
+ "256151": {
1244
+ "content": "<extra_id_148>",
1245
+ "lstrip": false,
1246
+ "normalized": false,
1247
+ "rstrip": false,
1248
+ "single_word": false,
1249
+ "special": true
1250
+ },
1251
+ "256152": {
1252
+ "content": "<extra_id_147>",
1253
+ "lstrip": false,
1254
+ "normalized": false,
1255
+ "rstrip": false,
1256
+ "single_word": false,
1257
+ "special": true
1258
+ },
1259
+ "256153": {
1260
+ "content": "<extra_id_146>",
1261
+ "lstrip": false,
1262
+ "normalized": false,
1263
+ "rstrip": false,
1264
+ "single_word": false,
1265
+ "special": true
1266
+ },
1267
+ "256154": {
1268
+ "content": "<extra_id_145>",
1269
+ "lstrip": false,
1270
+ "normalized": false,
1271
+ "rstrip": false,
1272
+ "single_word": false,
1273
+ "special": true
1274
+ },
1275
+ "256155": {
1276
+ "content": "<extra_id_144>",
1277
+ "lstrip": false,
1278
+ "normalized": false,
1279
+ "rstrip": false,
1280
+ "single_word": false,
1281
+ "special": true
1282
+ },
1283
+ "256156": {
1284
+ "content": "<extra_id_143>",
1285
+ "lstrip": false,
1286
+ "normalized": false,
1287
+ "rstrip": false,
1288
+ "single_word": false,
1289
+ "special": true
1290
+ },
1291
+ "256157": {
1292
+ "content": "<extra_id_142>",
1293
+ "lstrip": false,
1294
+ "normalized": false,
1295
+ "rstrip": false,
1296
+ "single_word": false,
1297
+ "special": true
1298
+ },
1299
+ "256158": {
1300
+ "content": "<extra_id_141>",
1301
+ "lstrip": false,
1302
+ "normalized": false,
1303
+ "rstrip": false,
1304
+ "single_word": false,
1305
+ "special": true
1306
+ },
1307
+ "256159": {
1308
+ "content": "<extra_id_140>",
1309
+ "lstrip": false,
1310
+ "normalized": false,
1311
+ "rstrip": false,
1312
+ "single_word": false,
1313
+ "special": true
1314
+ },
1315
+ "256160": {
1316
+ "content": "<extra_id_139>",
1317
+ "lstrip": false,
1318
+ "normalized": false,
1319
+ "rstrip": false,
1320
+ "single_word": false,
1321
+ "special": true
1322
+ },
1323
+ "256161": {
1324
+ "content": "<extra_id_138>",
1325
+ "lstrip": false,
1326
+ "normalized": false,
1327
+ "rstrip": false,
1328
+ "single_word": false,
1329
+ "special": true
1330
+ },
1331
+ "256162": {
1332
+ "content": "<extra_id_137>",
1333
+ "lstrip": false,
1334
+ "normalized": false,
1335
+ "rstrip": false,
1336
+ "single_word": false,
1337
+ "special": true
1338
+ },
1339
+ "256163": {
1340
+ "content": "<extra_id_136>",
1341
+ "lstrip": false,
1342
+ "normalized": false,
1343
+ "rstrip": false,
1344
+ "single_word": false,
1345
+ "special": true
1346
+ },
1347
+ "256164": {
1348
+ "content": "<extra_id_135>",
1349
+ "lstrip": false,
1350
+ "normalized": false,
1351
+ "rstrip": false,
1352
+ "single_word": false,
1353
+ "special": true
1354
+ },
1355
+ "256165": {
1356
+ "content": "<extra_id_134>",
1357
+ "lstrip": false,
1358
+ "normalized": false,
1359
+ "rstrip": false,
1360
+ "single_word": false,
1361
+ "special": true
1362
+ },
1363
+ "256166": {
1364
+ "content": "<extra_id_133>",
1365
+ "lstrip": false,
1366
+ "normalized": false,
1367
+ "rstrip": false,
1368
+ "single_word": false,
1369
+ "special": true
1370
+ },
1371
+ "256167": {
1372
+ "content": "<extra_id_132>",
1373
+ "lstrip": false,
1374
+ "normalized": false,
1375
+ "rstrip": false,
1376
+ "single_word": false,
1377
+ "special": true
1378
+ },
1379
+ "256168": {
1380
+ "content": "<extra_id_131>",
1381
+ "lstrip": false,
1382
+ "normalized": false,
1383
+ "rstrip": false,
1384
+ "single_word": false,
1385
+ "special": true
1386
+ },
1387
+ "256169": {
1388
+ "content": "<extra_id_130>",
1389
+ "lstrip": false,
1390
+ "normalized": false,
1391
+ "rstrip": false,
1392
+ "single_word": false,
1393
+ "special": true
1394
+ },
1395
+ "256170": {
1396
+ "content": "<extra_id_129>",
1397
+ "lstrip": false,
1398
+ "normalized": false,
1399
+ "rstrip": false,
1400
+ "single_word": false,
1401
+ "special": true
1402
+ },
1403
+ "256171": {
1404
+ "content": "<extra_id_128>",
1405
+ "lstrip": false,
1406
+ "normalized": false,
1407
+ "rstrip": false,
1408
+ "single_word": false,
1409
+ "special": true
1410
+ },
1411
+ "256172": {
1412
+ "content": "<extra_id_127>",
1413
+ "lstrip": false,
1414
+ "normalized": false,
1415
+ "rstrip": false,
1416
+ "single_word": false,
1417
+ "special": true
1418
+ },
1419
+ "256173": {
1420
+ "content": "<extra_id_126>",
1421
+ "lstrip": false,
1422
+ "normalized": false,
1423
+ "rstrip": false,
1424
+ "single_word": false,
1425
+ "special": true
1426
+ },
1427
+ "256174": {
1428
+ "content": "<extra_id_125>",
1429
+ "lstrip": false,
1430
+ "normalized": false,
1431
+ "rstrip": false,
1432
+ "single_word": false,
1433
+ "special": true
1434
+ },
1435
+ "256175": {
1436
+ "content": "<extra_id_124>",
1437
+ "lstrip": false,
1438
+ "normalized": false,
1439
+ "rstrip": false,
1440
+ "single_word": false,
1441
+ "special": true
1442
+ },
1443
+ "256176": {
1444
+ "content": "<extra_id_123>",
1445
+ "lstrip": false,
1446
+ "normalized": false,
1447
+ "rstrip": false,
1448
+ "single_word": false,
1449
+ "special": true
1450
+ },
1451
+ "256177": {
1452
+ "content": "<extra_id_122>",
1453
+ "lstrip": false,
1454
+ "normalized": false,
1455
+ "rstrip": false,
1456
+ "single_word": false,
1457
+ "special": true
1458
+ },
1459
+ "256178": {
1460
+ "content": "<extra_id_121>",
1461
+ "lstrip": false,
1462
+ "normalized": false,
1463
+ "rstrip": false,
1464
+ "single_word": false,
1465
+ "special": true
1466
+ },
1467
+ "256179": {
1468
+ "content": "<extra_id_120>",
1469
+ "lstrip": false,
1470
+ "normalized": false,
1471
+ "rstrip": false,
1472
+ "single_word": false,
1473
+ "special": true
1474
+ },
1475
+ "256180": {
1476
+ "content": "<extra_id_119>",
1477
+ "lstrip": false,
1478
+ "normalized": false,
1479
+ "rstrip": false,
1480
+ "single_word": false,
1481
+ "special": true
1482
+ },
1483
+ "256181": {
1484
+ "content": "<extra_id_118>",
1485
+ "lstrip": false,
1486
+ "normalized": false,
1487
+ "rstrip": false,
1488
+ "single_word": false,
1489
+ "special": true
1490
+ },
1491
+ "256182": {
1492
+ "content": "<extra_id_117>",
1493
+ "lstrip": false,
1494
+ "normalized": false,
1495
+ "rstrip": false,
1496
+ "single_word": false,
1497
+ "special": true
1498
+ },
1499
+ "256183": {
1500
+ "content": "<extra_id_116>",
1501
+ "lstrip": false,
1502
+ "normalized": false,
1503
+ "rstrip": false,
1504
+ "single_word": false,
1505
+ "special": true
1506
+ },
1507
+ "256184": {
1508
+ "content": "<extra_id_115>",
1509
+ "lstrip": false,
1510
+ "normalized": false,
1511
+ "rstrip": false,
1512
+ "single_word": false,
1513
+ "special": true
1514
+ },
1515
+ "256185": {
1516
+ "content": "<extra_id_114>",
1517
+ "lstrip": false,
1518
+ "normalized": false,
1519
+ "rstrip": false,
1520
+ "single_word": false,
1521
+ "special": true
1522
+ },
1523
+ "256186": {
1524
+ "content": "<extra_id_113>",
1525
+ "lstrip": false,
1526
+ "normalized": false,
1527
+ "rstrip": false,
1528
+ "single_word": false,
1529
+ "special": true
1530
+ },
1531
+ "256187": {
1532
+ "content": "<extra_id_112>",
1533
+ "lstrip": false,
1534
+ "normalized": false,
1535
+ "rstrip": false,
1536
+ "single_word": false,
1537
+ "special": true
1538
+ },
1539
+ "256188": {
1540
+ "content": "<extra_id_111>",
1541
+ "lstrip": false,
1542
+ "normalized": false,
1543
+ "rstrip": false,
1544
+ "single_word": false,
1545
+ "special": true
1546
+ },
1547
+ "256189": {
1548
+ "content": "<extra_id_110>",
1549
+ "lstrip": false,
1550
+ "normalized": false,
1551
+ "rstrip": false,
1552
+ "single_word": false,
1553
+ "special": true
1554
+ },
1555
+ "256190": {
1556
+ "content": "<extra_id_109>",
1557
+ "lstrip": false,
1558
+ "normalized": false,
1559
+ "rstrip": false,
1560
+ "single_word": false,
1561
+ "special": true
1562
+ },
1563
+ "256191": {
1564
+ "content": "<extra_id_108>",
1565
+ "lstrip": false,
1566
+ "normalized": false,
1567
+ "rstrip": false,
1568
+ "single_word": false,
1569
+ "special": true
1570
+ },
1571
+ "256192": {
1572
+ "content": "<extra_id_107>",
1573
+ "lstrip": false,
1574
+ "normalized": false,
1575
+ "rstrip": false,
1576
+ "single_word": false,
1577
+ "special": true
1578
+ },
1579
+ "256193": {
1580
+ "content": "<extra_id_106>",
1581
+ "lstrip": false,
1582
+ "normalized": false,
1583
+ "rstrip": false,
1584
+ "single_word": false,
1585
+ "special": true
1586
+ },
1587
+ "256194": {
1588
+ "content": "<extra_id_105>",
1589
+ "lstrip": false,
1590
+ "normalized": false,
1591
+ "rstrip": false,
1592
+ "single_word": false,
1593
+ "special": true
1594
+ },
1595
+ "256195": {
1596
+ "content": "<extra_id_104>",
1597
+ "lstrip": false,
1598
+ "normalized": false,
1599
+ "rstrip": false,
1600
+ "single_word": false,
1601
+ "special": true
1602
+ },
1603
+ "256196": {
1604
+ "content": "<extra_id_103>",
1605
+ "lstrip": false,
1606
+ "normalized": false,
1607
+ "rstrip": false,
1608
+ "single_word": false,
1609
+ "special": true
1610
+ },
1611
+ "256197": {
1612
+ "content": "<extra_id_102>",
1613
+ "lstrip": false,
1614
+ "normalized": false,
1615
+ "rstrip": false,
1616
+ "single_word": false,
1617
+ "special": true
1618
+ },
1619
+ "256198": {
1620
+ "content": "<extra_id_101>",
1621
+ "lstrip": false,
1622
+ "normalized": false,
1623
+ "rstrip": false,
1624
+ "single_word": false,
1625
+ "special": true
1626
+ },
1627
+ "256199": {
1628
+ "content": "<extra_id_100>",
1629
+ "lstrip": false,
1630
+ "normalized": false,
1631
+ "rstrip": false,
1632
+ "single_word": false,
1633
+ "special": true
1634
+ },
1635
+ "256200": {
1636
+ "content": "<extra_id_99>",
1637
+ "lstrip": false,
1638
+ "normalized": false,
1639
+ "rstrip": false,
1640
+ "single_word": false,
1641
+ "special": true
1642
+ },
1643
+ "256201": {
1644
+ "content": "<extra_id_98>",
1645
+ "lstrip": false,
1646
+ "normalized": false,
1647
+ "rstrip": false,
1648
+ "single_word": false,
1649
+ "special": true
1650
+ },
1651
+ "256202": {
1652
+ "content": "<extra_id_97>",
1653
+ "lstrip": false,
1654
+ "normalized": false,
1655
+ "rstrip": false,
1656
+ "single_word": false,
1657
+ "special": true
1658
+ },
1659
+ "256203": {
1660
+ "content": "<extra_id_96>",
1661
+ "lstrip": false,
1662
+ "normalized": false,
1663
+ "rstrip": false,
1664
+ "single_word": false,
1665
+ "special": true
1666
+ },
1667
+ "256204": {
1668
+ "content": "<extra_id_95>",
1669
+ "lstrip": false,
1670
+ "normalized": false,
1671
+ "rstrip": false,
1672
+ "single_word": false,
1673
+ "special": true
1674
+ },
1675
+ "256205": {
1676
+ "content": "<extra_id_94>",
1677
+ "lstrip": false,
1678
+ "normalized": false,
1679
+ "rstrip": false,
1680
+ "single_word": false,
1681
+ "special": true
1682
+ },
1683
+ "256206": {
1684
+ "content": "<extra_id_93>",
1685
+ "lstrip": false,
1686
+ "normalized": false,
1687
+ "rstrip": false,
1688
+ "single_word": false,
1689
+ "special": true
1690
+ },
1691
+ "256207": {
1692
+ "content": "<extra_id_92>",
1693
+ "lstrip": false,
1694
+ "normalized": false,
1695
+ "rstrip": false,
1696
+ "single_word": false,
1697
+ "special": true
1698
+ },
1699
+ "256208": {
1700
+ "content": "<extra_id_91>",
1701
+ "lstrip": false,
1702
+ "normalized": false,
1703
+ "rstrip": false,
1704
+ "single_word": false,
1705
+ "special": true
1706
+ },
1707
+ "256209": {
1708
+ "content": "<extra_id_90>",
1709
+ "lstrip": false,
1710
+ "normalized": false,
1711
+ "rstrip": false,
1712
+ "single_word": false,
1713
+ "special": true
1714
+ },
1715
+ "256210": {
1716
+ "content": "<extra_id_89>",
1717
+ "lstrip": false,
1718
+ "normalized": false,
1719
+ "rstrip": false,
1720
+ "single_word": false,
1721
+ "special": true
1722
+ },
1723
+ "256211": {
1724
+ "content": "<extra_id_88>",
1725
+ "lstrip": false,
1726
+ "normalized": false,
1727
+ "rstrip": false,
1728
+ "single_word": false,
1729
+ "special": true
1730
+ },
1731
+ "256212": {
1732
+ "content": "<extra_id_87>",
1733
+ "lstrip": false,
1734
+ "normalized": false,
1735
+ "rstrip": false,
1736
+ "single_word": false,
1737
+ "special": true
1738
+ },
1739
+ "256213": {
1740
+ "content": "<extra_id_86>",
1741
+ "lstrip": false,
1742
+ "normalized": false,
1743
+ "rstrip": false,
1744
+ "single_word": false,
1745
+ "special": true
1746
+ },
1747
+ "256214": {
1748
+ "content": "<extra_id_85>",
1749
+ "lstrip": false,
1750
+ "normalized": false,
1751
+ "rstrip": false,
1752
+ "single_word": false,
1753
+ "special": true
1754
+ },
1755
+ "256215": {
1756
+ "content": "<extra_id_84>",
1757
+ "lstrip": false,
1758
+ "normalized": false,
1759
+ "rstrip": false,
1760
+ "single_word": false,
1761
+ "special": true
1762
+ },
1763
+ "256216": {
1764
+ "content": "<extra_id_83>",
1765
+ "lstrip": false,
1766
+ "normalized": false,
1767
+ "rstrip": false,
1768
+ "single_word": false,
1769
+ "special": true
1770
+ },
1771
+ "256217": {
1772
+ "content": "<extra_id_82>",
1773
+ "lstrip": false,
1774
+ "normalized": false,
1775
+ "rstrip": false,
1776
+ "single_word": false,
1777
+ "special": true
1778
+ },
1779
+ "256218": {
1780
+ "content": "<extra_id_81>",
1781
+ "lstrip": false,
1782
+ "normalized": false,
1783
+ "rstrip": false,
1784
+ "single_word": false,
1785
+ "special": true
1786
+ },
1787
+ "256219": {
1788
+ "content": "<extra_id_80>",
1789
+ "lstrip": false,
1790
+ "normalized": false,
1791
+ "rstrip": false,
1792
+ "single_word": false,
1793
+ "special": true
1794
+ },
1795
+ "256220": {
1796
+ "content": "<extra_id_79>",
1797
+ "lstrip": false,
1798
+ "normalized": false,
1799
+ "rstrip": false,
1800
+ "single_word": false,
1801
+ "special": true
1802
+ },
1803
+ "256221": {
1804
+ "content": "<extra_id_78>",
1805
+ "lstrip": false,
1806
+ "normalized": false,
1807
+ "rstrip": false,
1808
+ "single_word": false,
1809
+ "special": true
1810
+ },
1811
+ "256222": {
1812
+ "content": "<extra_id_77>",
1813
+ "lstrip": false,
1814
+ "normalized": false,
1815
+ "rstrip": false,
1816
+ "single_word": false,
1817
+ "special": true
1818
+ },
1819
+ "256223": {
1820
+ "content": "<extra_id_76>",
1821
+ "lstrip": false,
1822
+ "normalized": false,
1823
+ "rstrip": false,
1824
+ "single_word": false,
1825
+ "special": true
1826
+ },
1827
+ "256224": {
1828
+ "content": "<extra_id_75>",
1829
+ "lstrip": false,
1830
+ "normalized": false,
1831
+ "rstrip": false,
1832
+ "single_word": false,
1833
+ "special": true
1834
+ },
1835
+ "256225": {
1836
+ "content": "<extra_id_74>",
1837
+ "lstrip": false,
1838
+ "normalized": false,
1839
+ "rstrip": false,
1840
+ "single_word": false,
1841
+ "special": true
1842
+ },
1843
+ "256226": {
1844
+ "content": "<extra_id_73>",
1845
+ "lstrip": false,
1846
+ "normalized": false,
1847
+ "rstrip": false,
1848
+ "single_word": false,
1849
+ "special": true
1850
+ },
1851
+ "256227": {
1852
+ "content": "<extra_id_72>",
1853
+ "lstrip": false,
1854
+ "normalized": false,
1855
+ "rstrip": false,
1856
+ "single_word": false,
1857
+ "special": true
1858
+ },
1859
+ "256228": {
1860
+ "content": "<extra_id_71>",
1861
+ "lstrip": false,
1862
+ "normalized": false,
1863
+ "rstrip": false,
1864
+ "single_word": false,
1865
+ "special": true
1866
+ },
1867
+ "256229": {
1868
+ "content": "<extra_id_70>",
1869
+ "lstrip": false,
1870
+ "normalized": false,
1871
+ "rstrip": false,
1872
+ "single_word": false,
1873
+ "special": true
1874
+ },
1875
+ "256230": {
1876
+ "content": "<extra_id_69>",
1877
+ "lstrip": false,
1878
+ "normalized": false,
1879
+ "rstrip": false,
1880
+ "single_word": false,
1881
+ "special": true
1882
+ },
1883
+ "256231": {
1884
+ "content": "<extra_id_68>",
1885
+ "lstrip": false,
1886
+ "normalized": false,
1887
+ "rstrip": false,
1888
+ "single_word": false,
1889
+ "special": true
1890
+ },
1891
+ "256232": {
1892
+ "content": "<extra_id_67>",
1893
+ "lstrip": false,
1894
+ "normalized": false,
1895
+ "rstrip": false,
1896
+ "single_word": false,
1897
+ "special": true
1898
+ },
1899
+ "256233": {
1900
+ "content": "<extra_id_66>",
1901
+ "lstrip": false,
1902
+ "normalized": false,
1903
+ "rstrip": false,
1904
+ "single_word": false,
1905
+ "special": true
1906
+ },
1907
+ "256234": {
1908
+ "content": "<extra_id_65>",
1909
+ "lstrip": false,
1910
+ "normalized": false,
1911
+ "rstrip": false,
1912
+ "single_word": false,
1913
+ "special": true
1914
+ },
1915
+ "256235": {
1916
+ "content": "<extra_id_64>",
1917
+ "lstrip": false,
1918
+ "normalized": false,
1919
+ "rstrip": false,
1920
+ "single_word": false,
1921
+ "special": true
1922
+ },
1923
+ "256236": {
1924
+ "content": "<extra_id_63>",
1925
+ "lstrip": false,
1926
+ "normalized": false,
1927
+ "rstrip": false,
1928
+ "single_word": false,
1929
+ "special": true
1930
+ },
1931
+ "256237": {
1932
+ "content": "<extra_id_62>",
1933
+ "lstrip": false,
1934
+ "normalized": false,
1935
+ "rstrip": false,
1936
+ "single_word": false,
1937
+ "special": true
1938
+ },
1939
+ "256238": {
1940
+ "content": "<extra_id_61>",
1941
+ "lstrip": false,
1942
+ "normalized": false,
1943
+ "rstrip": false,
1944
+ "single_word": false,
1945
+ "special": true
1946
+ },
1947
+ "256239": {
1948
+ "content": "<extra_id_60>",
1949
+ "lstrip": false,
1950
+ "normalized": false,
1951
+ "rstrip": false,
1952
+ "single_word": false,
1953
+ "special": true
1954
+ },
1955
+ "256240": {
1956
+ "content": "<extra_id_59>",
1957
+ "lstrip": false,
1958
+ "normalized": false,
1959
+ "rstrip": false,
1960
+ "single_word": false,
1961
+ "special": true
1962
+ },
1963
+ "256241": {
1964
+ "content": "<extra_id_58>",
1965
+ "lstrip": false,
1966
+ "normalized": false,
1967
+ "rstrip": false,
1968
+ "single_word": false,
1969
+ "special": true
1970
+ },
1971
+ "256242": {
1972
+ "content": "<extra_id_57>",
1973
+ "lstrip": false,
1974
+ "normalized": false,
1975
+ "rstrip": false,
1976
+ "single_word": false,
1977
+ "special": true
1978
+ },
1979
+ "256243": {
1980
+ "content": "<extra_id_56>",
1981
+ "lstrip": false,
1982
+ "normalized": false,
1983
+ "rstrip": false,
1984
+ "single_word": false,
1985
+ "special": true
1986
+ },
1987
+ "256244": {
1988
+ "content": "<extra_id_55>",
1989
+ "lstrip": false,
1990
+ "normalized": false,
1991
+ "rstrip": false,
1992
+ "single_word": false,
1993
+ "special": true
1994
+ },
1995
+ "256245": {
1996
+ "content": "<extra_id_54>",
1997
+ "lstrip": false,
1998
+ "normalized": false,
1999
+ "rstrip": false,
2000
+ "single_word": false,
2001
+ "special": true
2002
+ },
2003
+ "256246": {
2004
+ "content": "<extra_id_53>",
2005
+ "lstrip": false,
2006
+ "normalized": false,
2007
+ "rstrip": false,
2008
+ "single_word": false,
2009
+ "special": true
2010
+ },
2011
+ "256247": {
2012
+ "content": "<extra_id_52>",
2013
+ "lstrip": false,
2014
+ "normalized": false,
2015
+ "rstrip": false,
2016
+ "single_word": false,
2017
+ "special": true
2018
+ },
2019
+ "256248": {
2020
+ "content": "<extra_id_51>",
2021
+ "lstrip": false,
2022
+ "normalized": false,
2023
+ "rstrip": false,
2024
+ "single_word": false,
2025
+ "special": true
2026
+ },
2027
+ "256249": {
2028
+ "content": "<extra_id_50>",
2029
+ "lstrip": false,
2030
+ "normalized": false,
2031
+ "rstrip": false,
2032
+ "single_word": false,
2033
+ "special": true
2034
+ },
2035
+ "256250": {
2036
+ "content": "<extra_id_49>",
2037
+ "lstrip": false,
2038
+ "normalized": false,
2039
+ "rstrip": false,
2040
+ "single_word": false,
2041
+ "special": true
2042
+ },
2043
+ "256251": {
2044
+ "content": "<extra_id_48>",
2045
+ "lstrip": false,
2046
+ "normalized": false,
2047
+ "rstrip": false,
2048
+ "single_word": false,
2049
+ "special": true
2050
+ },
2051
+ "256252": {
2052
+ "content": "<extra_id_47>",
2053
+ "lstrip": false,
2054
+ "normalized": false,
2055
+ "rstrip": false,
2056
+ "single_word": false,
2057
+ "special": true
2058
+ },
2059
+ "256253": {
2060
+ "content": "<extra_id_46>",
2061
+ "lstrip": false,
2062
+ "normalized": false,
2063
+ "rstrip": false,
2064
+ "single_word": false,
2065
+ "special": true
2066
+ },
2067
+ "256254": {
2068
+ "content": "<extra_id_45>",
2069
+ "lstrip": false,
2070
+ "normalized": false,
2071
+ "rstrip": false,
2072
+ "single_word": false,
2073
+ "special": true
2074
+ },
2075
+ "256255": {
2076
+ "content": "<extra_id_44>",
2077
+ "lstrip": false,
2078
+ "normalized": false,
2079
+ "rstrip": false,
2080
+ "single_word": false,
2081
+ "special": true
2082
+ },
2083
+ "256256": {
2084
+ "content": "<extra_id_43>",
2085
+ "lstrip": false,
2086
+ "normalized": false,
2087
+ "rstrip": false,
2088
+ "single_word": false,
2089
+ "special": true
2090
+ },
2091
+ "256257": {
2092
+ "content": "<extra_id_42>",
2093
+ "lstrip": false,
2094
+ "normalized": false,
2095
+ "rstrip": false,
2096
+ "single_word": false,
2097
+ "special": true
2098
+ },
2099
+ "256258": {
2100
+ "content": "<extra_id_41>",
2101
+ "lstrip": false,
2102
+ "normalized": false,
2103
+ "rstrip": false,
2104
+ "single_word": false,
2105
+ "special": true
2106
+ },
2107
+ "256259": {
2108
+ "content": "<extra_id_40>",
2109
+ "lstrip": false,
2110
+ "normalized": false,
2111
+ "rstrip": false,
2112
+ "single_word": false,
2113
+ "special": true
2114
+ },
2115
+ "256260": {
2116
+ "content": "<extra_id_39>",
2117
+ "lstrip": false,
2118
+ "normalized": false,
2119
+ "rstrip": false,
2120
+ "single_word": false,
2121
+ "special": true
2122
+ },
2123
+ "256261": {
2124
+ "content": "<extra_id_38>",
2125
+ "lstrip": false,
2126
+ "normalized": false,
2127
+ "rstrip": false,
2128
+ "single_word": false,
2129
+ "special": true
2130
+ },
2131
+ "256262": {
2132
+ "content": "<extra_id_37>",
2133
+ "lstrip": false,
2134
+ "normalized": false,
2135
+ "rstrip": false,
2136
+ "single_word": false,
2137
+ "special": true
2138
+ },
2139
+ "256263": {
2140
+ "content": "<extra_id_36>",
2141
+ "lstrip": false,
2142
+ "normalized": false,
2143
+ "rstrip": false,
2144
+ "single_word": false,
2145
+ "special": true
2146
+ },
2147
+ "256264": {
2148
+ "content": "<extra_id_35>",
2149
+ "lstrip": false,
2150
+ "normalized": false,
2151
+ "rstrip": false,
2152
+ "single_word": false,
2153
+ "special": true
2154
+ },
2155
+ "256265": {
2156
+ "content": "<extra_id_34>",
2157
+ "lstrip": false,
2158
+ "normalized": false,
2159
+ "rstrip": false,
2160
+ "single_word": false,
2161
+ "special": true
2162
+ },
2163
+ "256266": {
2164
+ "content": "<extra_id_33>",
2165
+ "lstrip": false,
2166
+ "normalized": false,
2167
+ "rstrip": false,
2168
+ "single_word": false,
2169
+ "special": true
2170
+ },
2171
+ "256267": {
2172
+ "content": "<extra_id_32>",
2173
+ "lstrip": false,
2174
+ "normalized": false,
2175
+ "rstrip": false,
2176
+ "single_word": false,
2177
+ "special": true
2178
+ },
2179
+ "256268": {
2180
+ "content": "<extra_id_31>",
2181
+ "lstrip": false,
2182
+ "normalized": false,
2183
+ "rstrip": false,
2184
+ "single_word": false,
2185
+ "special": true
2186
+ },
2187
+ "256269": {
2188
+ "content": "<extra_id_30>",
2189
+ "lstrip": false,
2190
+ "normalized": false,
2191
+ "rstrip": false,
2192
+ "single_word": false,
2193
+ "special": true
2194
+ },
2195
+ "256270": {
2196
+ "content": "<extra_id_29>",
2197
+ "lstrip": false,
2198
+ "normalized": false,
2199
+ "rstrip": false,
2200
+ "single_word": false,
2201
+ "special": true
2202
+ },
2203
+ "256271": {
2204
+ "content": "<extra_id_28>",
2205
+ "lstrip": false,
2206
+ "normalized": false,
2207
+ "rstrip": false,
2208
+ "single_word": false,
2209
+ "special": true
2210
+ },
2211
+ "256272": {
2212
+ "content": "<extra_id_27>",
2213
+ "lstrip": false,
2214
+ "normalized": false,
2215
+ "rstrip": false,
2216
+ "single_word": false,
2217
+ "special": true
2218
+ },
2219
+ "256273": {
2220
+ "content": "<extra_id_26>",
2221
+ "lstrip": false,
2222
+ "normalized": false,
2223
+ "rstrip": false,
2224
+ "single_word": false,
2225
+ "special": true
2226
+ },
2227
+ "256274": {
2228
+ "content": "<extra_id_25>",
2229
+ "lstrip": false,
2230
+ "normalized": false,
2231
+ "rstrip": false,
2232
+ "single_word": false,
2233
+ "special": true
2234
+ },
2235
+ "256275": {
2236
+ "content": "<extra_id_24>",
2237
+ "lstrip": false,
2238
+ "normalized": false,
2239
+ "rstrip": false,
2240
+ "single_word": false,
2241
+ "special": true
2242
+ },
2243
+ "256276": {
2244
+ "content": "<extra_id_23>",
2245
+ "lstrip": false,
2246
+ "normalized": false,
2247
+ "rstrip": false,
2248
+ "single_word": false,
2249
+ "special": true
2250
+ },
2251
+ "256277": {
2252
+ "content": "<extra_id_22>",
2253
+ "lstrip": false,
2254
+ "normalized": false,
2255
+ "rstrip": false,
2256
+ "single_word": false,
2257
+ "special": true
2258
+ },
2259
+ "256278": {
2260
+ "content": "<extra_id_21>",
2261
+ "lstrip": false,
2262
+ "normalized": false,
2263
+ "rstrip": false,
2264
+ "single_word": false,
2265
+ "special": true
2266
+ },
2267
+ "256279": {
2268
+ "content": "<extra_id_20>",
2269
+ "lstrip": false,
2270
+ "normalized": false,
2271
+ "rstrip": false,
2272
+ "single_word": false,
2273
+ "special": true
2274
+ },
2275
+ "256280": {
2276
+ "content": "<extra_id_19>",
2277
+ "lstrip": false,
2278
+ "normalized": false,
2279
+ "rstrip": false,
2280
+ "single_word": false,
2281
+ "special": true
2282
+ },
2283
+ "256281": {
2284
+ "content": "<extra_id_18>",
2285
+ "lstrip": false,
2286
+ "normalized": false,
2287
+ "rstrip": false,
2288
+ "single_word": false,
2289
+ "special": true
2290
+ },
2291
+ "256282": {
2292
+ "content": "<extra_id_17>",
2293
+ "lstrip": false,
2294
+ "normalized": false,
2295
+ "rstrip": false,
2296
+ "single_word": false,
2297
+ "special": true
2298
+ },
2299
+ "256283": {
2300
+ "content": "<extra_id_16>",
2301
+ "lstrip": false,
2302
+ "normalized": false,
2303
+ "rstrip": false,
2304
+ "single_word": false,
2305
+ "special": true
2306
+ },
2307
+ "256284": {
2308
+ "content": "<extra_id_15>",
2309
+ "lstrip": false,
2310
+ "normalized": false,
2311
+ "rstrip": false,
2312
+ "single_word": false,
2313
+ "special": true
2314
+ },
2315
+ "256285": {
2316
+ "content": "<extra_id_14>",
2317
+ "lstrip": false,
2318
+ "normalized": false,
2319
+ "rstrip": false,
2320
+ "single_word": false,
2321
+ "special": true
2322
+ },
2323
+ "256286": {
2324
+ "content": "<extra_id_13>",
2325
+ "lstrip": false,
2326
+ "normalized": false,
2327
+ "rstrip": false,
2328
+ "single_word": false,
2329
+ "special": true
2330
+ },
2331
+ "256287": {
2332
+ "content": "<extra_id_12>",
2333
+ "lstrip": false,
2334
+ "normalized": false,
2335
+ "rstrip": false,
2336
+ "single_word": false,
2337
+ "special": true
2338
+ },
2339
+ "256288": {
2340
+ "content": "<extra_id_11>",
2341
+ "lstrip": false,
2342
+ "normalized": false,
2343
+ "rstrip": false,
2344
+ "single_word": false,
2345
+ "special": true
2346
+ },
2347
+ "256289": {
2348
+ "content": "<extra_id_10>",
2349
+ "lstrip": false,
2350
+ "normalized": false,
2351
+ "rstrip": false,
2352
+ "single_word": false,
2353
+ "special": true
2354
+ },
2355
+ "256290": {
2356
+ "content": "<extra_id_9>",
2357
+ "lstrip": false,
2358
+ "normalized": false,
2359
+ "rstrip": false,
2360
+ "single_word": false,
2361
+ "special": true
2362
+ },
2363
+ "256291": {
2364
+ "content": "<extra_id_8>",
2365
+ "lstrip": false,
2366
+ "normalized": false,
2367
+ "rstrip": false,
2368
+ "single_word": false,
2369
+ "special": true
2370
+ },
2371
+ "256292": {
2372
+ "content": "<extra_id_7>",
2373
+ "lstrip": false,
2374
+ "normalized": false,
2375
+ "rstrip": false,
2376
+ "single_word": false,
2377
+ "special": true
2378
+ },
2379
+ "256293": {
2380
+ "content": "<extra_id_6>",
2381
+ "lstrip": false,
2382
+ "normalized": false,
2383
+ "rstrip": false,
2384
+ "single_word": false,
2385
+ "special": true
2386
+ },
2387
+ "256294": {
2388
+ "content": "<extra_id_5>",
2389
+ "lstrip": false,
2390
+ "normalized": false,
2391
+ "rstrip": false,
2392
+ "single_word": false,
2393
+ "special": true
2394
+ },
2395
+ "256295": {
2396
+ "content": "<extra_id_4>",
2397
+ "lstrip": false,
2398
+ "normalized": false,
2399
+ "rstrip": false,
2400
+ "single_word": false,
2401
+ "special": true
2402
+ },
2403
+ "256296": {
2404
+ "content": "<extra_id_3>",
2405
+ "lstrip": false,
2406
+ "normalized": false,
2407
+ "rstrip": false,
2408
+ "single_word": false,
2409
+ "special": true
2410
+ },
2411
+ "256297": {
2412
+ "content": "<extra_id_2>",
2413
+ "lstrip": false,
2414
+ "normalized": false,
2415
+ "rstrip": false,
2416
+ "single_word": false,
2417
+ "special": true
2418
+ },
2419
+ "256298": {
2420
+ "content": "<extra_id_1>",
2421
+ "lstrip": false,
2422
+ "normalized": false,
2423
+ "rstrip": false,
2424
+ "single_word": false,
2425
+ "special": true
2426
+ },
2427
+ "256299": {
2428
+ "content": "<extra_id_0>",
2429
+ "lstrip": false,
2430
+ "normalized": false,
2431
+ "rstrip": false,
2432
+ "single_word": false,
2433
+ "special": true
2434
+ }
2435
+ },
2436
+ "additional_special_tokens": [
2437
+ "<extra_id_0>",
2438
+ "<extra_id_1>",
2439
+ "<extra_id_2>",
2440
+ "<extra_id_3>",
2441
+ "<extra_id_4>",
2442
+ "<extra_id_5>",
2443
+ "<extra_id_6>",
2444
+ "<extra_id_7>",
2445
+ "<extra_id_8>",
2446
+ "<extra_id_9>",
2447
+ "<extra_id_10>",
2448
+ "<extra_id_11>",
2449
+ "<extra_id_12>",
2450
+ "<extra_id_13>",
2451
+ "<extra_id_14>",
2452
+ "<extra_id_15>",
2453
+ "<extra_id_16>",
2454
+ "<extra_id_17>",
2455
+ "<extra_id_18>",
2456
+ "<extra_id_19>",
2457
+ "<extra_id_20>",
2458
+ "<extra_id_21>",
2459
+ "<extra_id_22>",
2460
+ "<extra_id_23>",
2461
+ "<extra_id_24>",
2462
+ "<extra_id_25>",
2463
+ "<extra_id_26>",
2464
+ "<extra_id_27>",
2465
+ "<extra_id_28>",
2466
+ "<extra_id_29>",
2467
+ "<extra_id_30>",
2468
+ "<extra_id_31>",
2469
+ "<extra_id_32>",
2470
+ "<extra_id_33>",
2471
+ "<extra_id_34>",
2472
+ "<extra_id_35>",
2473
+ "<extra_id_36>",
2474
+ "<extra_id_37>",
2475
+ "<extra_id_38>",
2476
+ "<extra_id_39>",
2477
+ "<extra_id_40>",
2478
+ "<extra_id_41>",
2479
+ "<extra_id_42>",
2480
+ "<extra_id_43>",
2481
+ "<extra_id_44>",
2482
+ "<extra_id_45>",
2483
+ "<extra_id_46>",
2484
+ "<extra_id_47>",
2485
+ "<extra_id_48>",
2486
+ "<extra_id_49>",
2487
+ "<extra_id_50>",
2488
+ "<extra_id_51>",
2489
+ "<extra_id_52>",
2490
+ "<extra_id_53>",
2491
+ "<extra_id_54>",
2492
+ "<extra_id_55>",
2493
+ "<extra_id_56>",
2494
+ "<extra_id_57>",
2495
+ "<extra_id_58>",
2496
+ "<extra_id_59>",
2497
+ "<extra_id_60>",
2498
+ "<extra_id_61>",
2499
+ "<extra_id_62>",
2500
+ "<extra_id_63>",
2501
+ "<extra_id_64>",
2502
+ "<extra_id_65>",
2503
+ "<extra_id_66>",
2504
+ "<extra_id_67>",
2505
+ "<extra_id_68>",
2506
+ "<extra_id_69>",
2507
+ "<extra_id_70>",
2508
+ "<extra_id_71>",
2509
+ "<extra_id_72>",
2510
+ "<extra_id_73>",
2511
+ "<extra_id_74>",
2512
+ "<extra_id_75>",
2513
+ "<extra_id_76>",
2514
+ "<extra_id_77>",
2515
+ "<extra_id_78>",
2516
+ "<extra_id_79>",
2517
+ "<extra_id_80>",
2518
+ "<extra_id_81>",
2519
+ "<extra_id_82>",
2520
+ "<extra_id_83>",
2521
+ "<extra_id_84>",
2522
+ "<extra_id_85>",
2523
+ "<extra_id_86>",
2524
+ "<extra_id_87>",
2525
+ "<extra_id_88>",
2526
+ "<extra_id_89>",
2527
+ "<extra_id_90>",
2528
+ "<extra_id_91>",
2529
+ "<extra_id_92>",
2530
+ "<extra_id_93>",
2531
+ "<extra_id_94>",
2532
+ "<extra_id_95>",
2533
+ "<extra_id_96>",
2534
+ "<extra_id_97>",
2535
+ "<extra_id_98>",
2536
+ "<extra_id_99>",
2537
+ "<extra_id_100>",
2538
+ "<extra_id_101>",
2539
+ "<extra_id_102>",
2540
+ "<extra_id_103>",
2541
+ "<extra_id_104>",
2542
+ "<extra_id_105>",
2543
+ "<extra_id_106>",
2544
+ "<extra_id_107>",
2545
+ "<extra_id_108>",
2546
+ "<extra_id_109>",
2547
+ "<extra_id_110>",
2548
+ "<extra_id_111>",
2549
+ "<extra_id_112>",
2550
+ "<extra_id_113>",
2551
+ "<extra_id_114>",
2552
+ "<extra_id_115>",
2553
+ "<extra_id_116>",
2554
+ "<extra_id_117>",
2555
+ "<extra_id_118>",
2556
+ "<extra_id_119>",
2557
+ "<extra_id_120>",
2558
+ "<extra_id_121>",
2559
+ "<extra_id_122>",
2560
+ "<extra_id_123>",
2561
+ "<extra_id_124>",
2562
+ "<extra_id_125>",
2563
+ "<extra_id_126>",
2564
+ "<extra_id_127>",
2565
+ "<extra_id_128>",
2566
+ "<extra_id_129>",
2567
+ "<extra_id_130>",
2568
+ "<extra_id_131>",
2569
+ "<extra_id_132>",
2570
+ "<extra_id_133>",
2571
+ "<extra_id_134>",
2572
+ "<extra_id_135>",
2573
+ "<extra_id_136>",
2574
+ "<extra_id_137>",
2575
+ "<extra_id_138>",
2576
+ "<extra_id_139>",
2577
+ "<extra_id_140>",
2578
+ "<extra_id_141>",
2579
+ "<extra_id_142>",
2580
+ "<extra_id_143>",
2581
+ "<extra_id_144>",
2582
+ "<extra_id_145>",
2583
+ "<extra_id_146>",
2584
+ "<extra_id_147>",
2585
+ "<extra_id_148>",
2586
+ "<extra_id_149>",
2587
+ "<extra_id_150>",
2588
+ "<extra_id_151>",
2589
+ "<extra_id_152>",
2590
+ "<extra_id_153>",
2591
+ "<extra_id_154>",
2592
+ "<extra_id_155>",
2593
+ "<extra_id_156>",
2594
+ "<extra_id_157>",
2595
+ "<extra_id_158>",
2596
+ "<extra_id_159>",
2597
+ "<extra_id_160>",
2598
+ "<extra_id_161>",
2599
+ "<extra_id_162>",
2600
+ "<extra_id_163>",
2601
+ "<extra_id_164>",
2602
+ "<extra_id_165>",
2603
+ "<extra_id_166>",
2604
+ "<extra_id_167>",
2605
+ "<extra_id_168>",
2606
+ "<extra_id_169>",
2607
+ "<extra_id_170>",
2608
+ "<extra_id_171>",
2609
+ "<extra_id_172>",
2610
+ "<extra_id_173>",
2611
+ "<extra_id_174>",
2612
+ "<extra_id_175>",
2613
+ "<extra_id_176>",
2614
+ "<extra_id_177>",
2615
+ "<extra_id_178>",
2616
+ "<extra_id_179>",
2617
+ "<extra_id_180>",
2618
+ "<extra_id_181>",
2619
+ "<extra_id_182>",
2620
+ "<extra_id_183>",
2621
+ "<extra_id_184>",
2622
+ "<extra_id_185>",
2623
+ "<extra_id_186>",
2624
+ "<extra_id_187>",
2625
+ "<extra_id_188>",
2626
+ "<extra_id_189>",
2627
+ "<extra_id_190>",
2628
+ "<extra_id_191>",
2629
+ "<extra_id_192>",
2630
+ "<extra_id_193>",
2631
+ "<extra_id_194>",
2632
+ "<extra_id_195>",
2633
+ "<extra_id_196>",
2634
+ "<extra_id_197>",
2635
+ "<extra_id_198>",
2636
+ "<extra_id_199>",
2637
+ "<extra_id_200>",
2638
+ "<extra_id_201>",
2639
+ "<extra_id_202>",
2640
+ "<extra_id_203>",
2641
+ "<extra_id_204>",
2642
+ "<extra_id_205>",
2643
+ "<extra_id_206>",
2644
+ "<extra_id_207>",
2645
+ "<extra_id_208>",
2646
+ "<extra_id_209>",
2647
+ "<extra_id_210>",
2648
+ "<extra_id_211>",
2649
+ "<extra_id_212>",
2650
+ "<extra_id_213>",
2651
+ "<extra_id_214>",
2652
+ "<extra_id_215>",
2653
+ "<extra_id_216>",
2654
+ "<extra_id_217>",
2655
+ "<extra_id_218>",
2656
+ "<extra_id_219>",
2657
+ "<extra_id_220>",
2658
+ "<extra_id_221>",
2659
+ "<extra_id_222>",
2660
+ "<extra_id_223>",
2661
+ "<extra_id_224>",
2662
+ "<extra_id_225>",
2663
+ "<extra_id_226>",
2664
+ "<extra_id_227>",
2665
+ "<extra_id_228>",
2666
+ "<extra_id_229>",
2667
+ "<extra_id_230>",
2668
+ "<extra_id_231>",
2669
+ "<extra_id_232>",
2670
+ "<extra_id_233>",
2671
+ "<extra_id_234>",
2672
+ "<extra_id_235>",
2673
+ "<extra_id_236>",
2674
+ "<extra_id_237>",
2675
+ "<extra_id_238>",
2676
+ "<extra_id_239>",
2677
+ "<extra_id_240>",
2678
+ "<extra_id_241>",
2679
+ "<extra_id_242>",
2680
+ "<extra_id_243>",
2681
+ "<extra_id_244>",
2682
+ "<extra_id_245>",
2683
+ "<extra_id_246>",
2684
+ "<extra_id_247>",
2685
+ "<extra_id_248>",
2686
+ "<extra_id_249>",
2687
+ "<extra_id_250>",
2688
+ "<extra_id_251>",
2689
+ "<extra_id_252>",
2690
+ "<extra_id_253>",
2691
+ "<extra_id_254>",
2692
+ "<extra_id_255>",
2693
+ "<extra_id_256>",
2694
+ "<extra_id_257>",
2695
+ "<extra_id_258>",
2696
+ "<extra_id_259>",
2697
+ "<extra_id_260>",
2698
+ "<extra_id_261>",
2699
+ "<extra_id_262>",
2700
+ "<extra_id_263>",
2701
+ "<extra_id_264>",
2702
+ "<extra_id_265>",
2703
+ "<extra_id_266>",
2704
+ "<extra_id_267>",
2705
+ "<extra_id_268>",
2706
+ "<extra_id_269>",
2707
+ "<extra_id_270>",
2708
+ "<extra_id_271>",
2709
+ "<extra_id_272>",
2710
+ "<extra_id_273>",
2711
+ "<extra_id_274>",
2712
+ "<extra_id_275>",
2713
+ "<extra_id_276>",
2714
+ "<extra_id_277>",
2715
+ "<extra_id_278>",
2716
+ "<extra_id_279>",
2717
+ "<extra_id_280>",
2718
+ "<extra_id_281>",
2719
+ "<extra_id_282>",
2720
+ "<extra_id_283>",
2721
+ "<extra_id_284>",
2722
+ "<extra_id_285>",
2723
+ "<extra_id_286>",
2724
+ "<extra_id_287>",
2725
+ "<extra_id_288>",
2726
+ "<extra_id_289>",
2727
+ "<extra_id_290>",
2728
+ "<extra_id_291>",
2729
+ "<extra_id_292>",
2730
+ "<extra_id_293>",
2731
+ "<extra_id_294>",
2732
+ "<extra_id_295>",
2733
+ "<extra_id_296>",
2734
+ "<extra_id_297>",
2735
+ "<extra_id_298>",
2736
+ "<extra_id_299>"
2737
+ ],
2738
+ "bos_token": "<s>",
2739
+ "clean_up_tokenization_spaces": true,
2740
+ "eos_token": "</s>",
2741
+ "extra_ids": 300,
2742
+ "model_max_length": 1000000000000000019884624838656,
2743
+ "pad_token": "<pad>",
2744
+ "sp_model_kwargs": {},
2745
+ "spaces_between_special_tokens": false,
2746
+ "tokenizer_class": "T5Tokenizer",
2747
+ "unk_token": "<unk>"
2748
+ }
infer_nimcritic.py ADDED
@@ -0,0 +1,1582 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """NimCritic 单条视频推理。
3
+
4
+ 默认 ``rollout_stride=1``。论文短任务表使用 ``--rollout-stride 2``。
5
+
6
+ 本文件、``nimcritic_model.py``、权重与 ``base/`` 位于同一目录。读帧、resize
7
+ 和滑窗在本文件里。DiT、VAE 与文本编码器在 ``nimcritic_model.py``。
8
+
9
+ 输入为视频文件时按容器帧率采样至 ``--sample-hz``(默认 2Hz),并保留末帧。
10
+ 输入已是帧序列时使用 ``--frames``,不再按 2Hz 重采样。
11
+
12
+ 示例::
13
+
14
+ python infer_nimcritic.py \\
15
+ --video clip.mp4 \\
16
+ --task "pick up the cup" \\
17
+ --output result.json
18
+
19
+ 参数说明见 ``--help``。只检查不加载权重::
20
+
21
+ python infer_nimcritic.py --self-check
22
+ """
23
+
24
+ from __future__ import annotations
25
+
26
+ import argparse
27
+ import json
28
+ import logging
29
+ import math
30
+ import os
31
+ import sys
32
+ import time
33
+ from dataclasses import dataclass, field
34
+ from pathlib import Path
35
+ from typing import Any
36
+
37
+ import numpy as np
38
+ import torch
39
+
40
+ logger = logging.getLogger("infer_nimcritic")
41
+
42
+ _ROOT = Path(__file__).resolve().parent
43
+
44
+ DEFAULT_CKPT = _ROOT / "nimcritic_step_128000.pt"
45
+ DEFAULT_BASE = _ROOT / "base"
46
+
47
+ # Wan2.2 VAE temporal downsample. cond_pixel = (video_condition_frames - 1) * tf + 1.
48
+ TEMPORAL_DOWNSAMPLE = 4
49
+ VIDEO_CONDITION_FRAMES = 2
50
+ VALUE_CONDITION_FRAMES = 1
51
+ TOKENIZER_MAX_LEN = 128
52
+ MODEL_ID = "Wan-AI/Wan2.2-TI2V-5B"
53
+ TOKENIZER_MODEL_ID = "Wan-AI/Wan2.1-T2V-1.3B"
54
+
55
+ TRAINING_TASK_PREFIX = (
56
+ "A video recorded from a robot's point of view executing the following instruction: "
57
+ )
58
+
59
+ TAIL_MODES = ("reanchor", "clamp")
60
+ AGGREGATE_MODES = ("first", "mean", "distance", "custom")
61
+ INFER_MODES = ("value", "joint")
62
+ PROGRESS_REPRS = ("absolute", "relative")
63
+ RESIZE_MODES = ("center_crop", "stretch", "letterbox")
64
+ _IMAGE_SUFFIXES = {".jpg", ".jpeg", ".png", ".webp", ".bmp"}
65
+ _LONG_EPISODE_WARN = 512
66
+
67
+ # step 128000 的结构。改这些就不能加载这份权重。
68
+ DEFAULT_VIDEO_DIT_CONFIG: dict[str, Any] = {
69
+ "has_image_input": False,
70
+ "patch_size": [1, 2, 2],
71
+ "in_dim": 48,
72
+ "hidden_dim": 3072,
73
+ "ffn_dim": 14336,
74
+ "freq_dim": 256,
75
+ "text_dim": 4096,
76
+ "out_dim": 48,
77
+ "num_heads": 24,
78
+ "attn_head_dim": 128,
79
+ "num_layers": 30,
80
+ "eps": 1.0e-06,
81
+ "seperated_timestep": True,
82
+ "require_clip_embedding": False,
83
+ "require_vae_embedding": False,
84
+ "fuse_vae_embedding_in_latents": True,
85
+ "use_gradient_checkpointing": False,
86
+ "video_attention_mask_mode": "first_frame_causal",
87
+ "action_conditioned": False,
88
+ }
89
+
90
+ DEFAULT_VALUE_DIT_CONFIG: dict[str, Any] = {
91
+ "value_dim": 2,
92
+ "hidden_dim": 1024,
93
+ "ffn_dim": 4096,
94
+ "num_heads": 24,
95
+ "attn_head_dim": 128,
96
+ "num_layers": 30,
97
+ "text_dim": 4096,
98
+ "freq_dim": 256,
99
+ "eps": 1.0e-06,
100
+ "use_gradient_checkpointing": False,
101
+ }
102
+
103
+ _BASE_FILES = (
104
+ "DiffSynth-Studio/Wan-Series-Converted-Safetensors/Wan2.2_VAE.safetensors",
105
+ "DiffSynth-Studio/Wan-Series-Converted-Safetensors/models_t5_umt5-xxl-enc-bf16.safetensors",
106
+ "Wan-AI/Wan2.1-T2V-1.3B/google/umt5-xxl/tokenizer_config.json",
107
+ )
108
+
109
+
110
+ @dataclass
111
+ class InferConfig:
112
+ """发布 yaml 的推理默认值。加载后仍可改滑窗和采样字段再调用 ``infer``。
113
+
114
+ ``video_infer_shift`` / ``value_infer_shift`` / ``torch_dtype`` / 路径在
115
+ ``load_model`` 时生效。``sigma_shift`` 非空时,当次调用同时盖过两侧 shift。
116
+ """
117
+
118
+ ckpt: Path = DEFAULT_CKPT
119
+ base_model_path: Path = DEFAULT_BASE
120
+ device: str = "cuda"
121
+ torch_dtype: str = "bfloat16"
122
+ height: int = 256
123
+ width: int = 448
124
+ resize_mode: str = "stretch"
125
+ # 只作用于 --video:按容器 fps 抽到该频率。--frames 已是帧序列,不再重抽。
126
+ sample_hz: float = 2.0
127
+ frame_stride: int | None = None
128
+ infer_mode: str = "value"
129
+ reverse: bool = False
130
+ reverse_infer_mode: str = "value"
131
+ value_seq_len: int = 5
132
+ rollout_stride: int | None = 1
133
+ rollout_aggregate: str = "distance"
134
+ rollout_aggregate_distance_power: float = 1.0
135
+ rollout_aggregate_weights: list[float] | None = None
136
+ rollout_dump_votes: bool = True
137
+ tail_mode: str = "clamp"
138
+ reverse_tail_mode: str = "reanchor"
139
+ num_inference_steps: int = 20
140
+ sigma_shift: float | None = None
141
+ seed: int = 42
142
+ rand_device: str = "cpu"
143
+ tiled: bool = False
144
+ value_cond_init: list[float] = field(default_factory=lambda: [0.0, 0.0])
145
+ reverse_value_cond_init: list[float] = field(default_factory=lambda: [1.0, 1.0])
146
+ value_progress_repr: str = "relative"
147
+ video_infer_shift: float = 5.0
148
+ value_infer_shift: float = 5.0
149
+
150
+ def public_dict(self) -> dict[str, Any]:
151
+ raw = {
152
+ "ckpt": str(self.ckpt),
153
+ "base_model_path": str(self.base_model_path),
154
+ "device": self.device,
155
+ "torch_dtype": self.torch_dtype,
156
+ "height": self.height,
157
+ "width": self.width,
158
+ "resize_mode": self.resize_mode,
159
+ "sample_hz": self.sample_hz,
160
+ "frame_stride": self.frame_stride,
161
+ "infer_mode": self.infer_mode,
162
+ "reverse": self.reverse,
163
+ "reverse_infer_mode": self.reverse_infer_mode,
164
+ "value_seq_len": self.value_seq_len,
165
+ "rollout_stride": self.rollout_stride,
166
+ "rollout_aggregate": self.rollout_aggregate,
167
+ "rollout_aggregate_distance_power": self.rollout_aggregate_distance_power,
168
+ "rollout_aggregate_weights": self.rollout_aggregate_weights,
169
+ "rollout_dump_votes": self.rollout_dump_votes,
170
+ "tail_mode": self.tail_mode,
171
+ "reverse_tail_mode": self.reverse_tail_mode,
172
+ "num_inference_steps": self.num_inference_steps,
173
+ "sigma_shift": self.sigma_shift,
174
+ "seed": self.seed,
175
+ "rand_device": self.rand_device,
176
+ "tiled": self.tiled,
177
+ "value_cond_init": list(self.value_cond_init),
178
+ "reverse_value_cond_init": list(self.reverse_value_cond_init),
179
+ "value_progress_repr": self.value_progress_repr,
180
+ "video_infer_shift": self.video_infer_shift,
181
+ "value_infer_shift": self.value_infer_shift,
182
+ "video_condition_frames": VIDEO_CONDITION_FRAMES,
183
+ "value_condition_frames": VALUE_CONDITION_FRAMES,
184
+ }
185
+ return raw
186
+
187
+
188
+ def rm_kwargs(cfg: InferConfig) -> dict[str, Any]:
189
+ """与 ``NimCriticRM`` 对齐的 kwargs,供和包内 adapter 对结果。"""
190
+ return {
191
+ "base_model_path": str(cfg.base_model_path),
192
+ "torch_dtype": cfg.torch_dtype,
193
+ "height": cfg.height,
194
+ "width": cfg.width,
195
+ "resize_mode": cfg.resize_mode,
196
+ "frame_stride": cfg.frame_stride,
197
+ "infer_mode": cfg.infer_mode,
198
+ "reverse_infer_mode": cfg.reverse_infer_mode,
199
+ "reverse_eval": cfg.reverse,
200
+ "value_seq_len": cfg.value_seq_len,
201
+ "rollout_stride": cfg.rollout_stride,
202
+ "rollout_aggregate": cfg.rollout_aggregate,
203
+ "rollout_aggregate_distance_power": cfg.rollout_aggregate_distance_power,
204
+ "rollout_aggregate_weights": cfg.rollout_aggregate_weights,
205
+ "rollout_dump_votes": cfg.rollout_dump_votes,
206
+ "tail_mode": cfg.tail_mode,
207
+ "reverse_tail_mode": cfg.reverse_tail_mode,
208
+ "num_inference_steps": cfg.num_inference_steps,
209
+ "sigma_shift": cfg.sigma_shift,
210
+ "seed": cfg.seed,
211
+ "rand_device": cfg.rand_device,
212
+ "tiled": cfg.tiled,
213
+ "video_condition_frames": VIDEO_CONDITION_FRAMES,
214
+ "value_condition_frames": VALUE_CONDITION_FRAMES,
215
+ "value_cond_init": list(cfg.value_cond_init),
216
+ "reverse_value_cond_init": list(cfg.reverse_value_cond_init),
217
+ "value_progress_repr": cfg.value_progress_repr,
218
+ "video_infer_shift": cfg.video_infer_shift,
219
+ "value_infer_shift": cfg.value_infer_shift,
220
+ "tokenizer_max_len": TOKENIZER_MAX_LEN,
221
+ "skip_dit_load_from_pretrain": True,
222
+ "mot_checkpoint_mixed_attn": False,
223
+ "redirect_common_files": True,
224
+ }
225
+
226
+
227
+ def wrap_training_task(task: str) -> str:
228
+ text = str(task or "")
229
+ if text.startswith(TRAINING_TASK_PREFIX):
230
+ return text
231
+ return TRAINING_TASK_PREFIX + text
232
+
233
+
234
+ def video_keep_indices(
235
+ n: int, fps: float, sample_hz: float, frame_stride: int | None = None
236
+ ) -> tuple[list[int], int]:
237
+ """按容器帧率抽到 ``sample_hz``,再可选地做序号步长。
238
+
239
+ 步长是 ``round(fps / sample_hz)``,至少为 1。源帧率不高于目标时保留全部帧。
240
+ 两步都保留各自序列的最后一帧。返回 ``(源帧下标, 频率步长)``。
241
+ """
242
+ if n < 0:
243
+ raise ValueError(f"n must be >= 0, got {n}")
244
+ if not math.isfinite(float(sample_hz)) or float(sample_hz) <= 0.0:
245
+ raise ValueError(f"sample_hz must be > 0, got {sample_hz}")
246
+ if not math.isfinite(float(fps)) or float(fps) <= 0.0:
247
+ raise ValueError(
248
+ f"video fps is {fps}, cannot sample at {sample_hz} Hz. "
249
+ "Use a file that records a frame rate, or pass --frames."
250
+ )
251
+ hz_stride = max(1, int(round(float(fps) / float(sample_hz))))
252
+ indices = subsample_frame_indices(n, hz_stride)
253
+ if frame_stride is not None and int(frame_stride) != 1:
254
+ inner = subsample_frame_indices(len(indices), frame_stride)
255
+ indices = [indices[i] for i in inner]
256
+ return indices, hz_stride
257
+
258
+
259
+ def subsample_frame_indices(n: int, stride: int | None) -> list[int]:
260
+ """均匀抽帧,始终保留最后一帧。``None`` 或 ``1`` 表示全帧。"""
261
+ if n < 0:
262
+ raise ValueError(f"n must be >= 0, got {n}")
263
+ if stride is None or int(stride) == 1:
264
+ return list(range(n))
265
+ stride_i = int(stride)
266
+ if stride_i < 1:
267
+ raise ValueError(f"frame_stride must be >= 1, got {stride}")
268
+ if n == 0:
269
+ return []
270
+ indices = list(range(0, n, stride_i))
271
+ last = n - 1
272
+ if last not in indices:
273
+ indices.append(last)
274
+ return indices
275
+
276
+
277
+ def geometry(cfg: InferConfig, tf: int = TEMPORAL_DOWNSAMPLE) -> dict[str, Any]:
278
+ """校验推理参数并返回窗口几何。非法组合在这里抛,不加载权重。"""
279
+ if cfg.infer_mode not in INFER_MODES:
280
+ raise ValueError(f"infer_mode must be one of {INFER_MODES}, got {cfg.infer_mode!r}")
281
+ if cfg.reverse_infer_mode not in INFER_MODES:
282
+ raise ValueError(
283
+ f"reverse_infer_mode must be one of {INFER_MODES}, got {cfg.reverse_infer_mode!r}"
284
+ )
285
+ if cfg.resize_mode not in RESIZE_MODES:
286
+ raise ValueError(f"resize_mode must be one of {RESIZE_MODES}, got {cfg.resize_mode!r}")
287
+ if cfg.tail_mode not in TAIL_MODES:
288
+ raise ValueError(f"tail_mode must be one of {TAIL_MODES}, got {cfg.tail_mode!r}")
289
+ if cfg.reverse_tail_mode not in TAIL_MODES:
290
+ raise ValueError(
291
+ f"reverse_tail_mode must be one of {TAIL_MODES}, got {cfg.reverse_tail_mode!r}"
292
+ )
293
+ if cfg.value_progress_repr not in PROGRESS_REPRS:
294
+ raise ValueError(
295
+ f"value_progress_repr must be one of {PROGRESS_REPRS}, got {cfg.value_progress_repr!r}"
296
+ )
297
+ if cfg.torch_dtype not in ("bfloat16", "float16", "float32"):
298
+ raise ValueError(f"torch_dtype must be bfloat16, float16, or float32, got {cfg.torch_dtype!r}")
299
+ if not str(cfg.device):
300
+ raise ValueError("device must be a non-empty string")
301
+ if not str(cfg.rand_device):
302
+ raise ValueError("rand_device must be a non-empty string")
303
+ height, width = int(cfg.height), int(cfg.width)
304
+ if height % 16 != 0 or width % 16 != 0 or height <= 0 or width <= 0:
305
+ raise ValueError(f"height/width must be positive multiples of 16, got {height}x{width}")
306
+ if int(cfg.num_inference_steps) < 1:
307
+ raise ValueError(f"num_inference_steps must be >= 1, got {cfg.num_inference_steps}")
308
+ if not math.isfinite(float(cfg.sample_hz)) or float(cfg.sample_hz) <= 0.0:
309
+ raise ValueError(f"sample_hz must be > 0, got {cfg.sample_hz}")
310
+ if cfg.frame_stride is not None and int(cfg.frame_stride) < 1:
311
+ raise ValueError(f"frame_stride must be >= 1, got {cfg.frame_stride}")
312
+ if int(tf) < 1:
313
+ raise ValueError(f"temporal downsample must be >= 1, got {tf}")
314
+
315
+ value_dim = int(DEFAULT_VALUE_DIT_CONFIG["value_dim"])
316
+ for key, raw in (
317
+ ("value_cond_init", cfg.value_cond_init),
318
+ ("reverse_value_cond_init", cfg.reverse_value_cond_init),
319
+ ):
320
+ vals = [float(v) for v in raw]
321
+ if len(vals) != value_dim:
322
+ raise ValueError(f"{key} length {len(vals)} != value_dim {value_dim}")
323
+
324
+ vcf = VIDEO_CONDITION_FRAMES
325
+ vcf_v = VALUE_CONDITION_FRAMES
326
+ cond_pixel = (vcf - 1) * int(tf) + 1
327
+ value_seq_len = int(cfg.value_seq_len)
328
+ if value_seq_len < vcf_v:
329
+ raise ValueError(f"value_seq_len={value_seq_len} must be >= value_condition_frames={vcf_v}")
330
+ for key, mode in (("tail_mode", cfg.tail_mode), ("reverse_tail_mode", cfg.reverse_tail_mode)):
331
+ if mode == "reanchor" and value_seq_len < cond_pixel:
332
+ raise ValueError(
333
+ f"value_seq_len={value_seq_len} must be >= cond_pixel={cond_pixel} for {key}={mode}"
334
+ )
335
+ max_stride = value_seq_len - vcf_v
336
+ if max_stride < 1:
337
+ raise ValueError(f"value_seq_len - value_condition_frames must be >= 1, got {max_stride}")
338
+ stride = max_stride if cfg.rollout_stride is None else int(cfg.rollout_stride)
339
+ if not 1 <= stride <= max_stride:
340
+ raise ValueError(f"rollout_stride must be in [1, {max_stride}], got {stride}")
341
+
342
+ mode = str(cfg.rollout_aggregate)
343
+ if mode not in AGGREGATE_MODES:
344
+ raise ValueError(f"rollout_aggregate must be one of {AGGREGATE_MODES}, got {mode!r}")
345
+ power = float(cfg.rollout_aggregate_distance_power)
346
+ if mode == "distance" and not power > 0.0:
347
+ raise ValueError(f"rollout_aggregate_distance_power must be > 0, got {power}")
348
+ weights: list[float] | None = None
349
+ if mode == "custom":
350
+ raw_weights = cfg.rollout_aggregate_weights
351
+ if raw_weights is None:
352
+ raise ValueError(
353
+ "rollout_aggregate=custom requires rollout_aggregate_weights "
354
+ f"(length {max_stride} = value_seq_len - value_condition_frames)"
355
+ )
356
+ weights = [float(w) for w in raw_weights]
357
+ if len(weights) != max_stride:
358
+ raise ValueError(
359
+ f"rollout_aggregate_weights length {len(weights)} != "
360
+ f"value_seq_len - value_condition_frames = {max_stride}"
361
+ )
362
+ if any(not np.isfinite(w) or w < 0.0 for w in weights):
363
+ raise ValueError(f"rollout_aggregate_weights must be finite and >= 0, got {weights}")
364
+ if all(w == 0.0 for w in weights):
365
+ raise ValueError("rollout_aggregate_weights must not be all zero")
366
+
367
+ for label, selected in (
368
+ ("infer_mode", cfg.infer_mode),
369
+ ("reverse_infer_mode", cfg.reverse_infer_mode),
370
+ ):
371
+ if selected == "joint" and stride > int(tf):
372
+ raise ValueError(
373
+ f"{label}=joint tiles {tf} predict frames per window; rollout_stride={stride} exceeds that"
374
+ )
375
+
376
+ return {
377
+ "vcf": vcf,
378
+ "vcf_v": vcf_v,
379
+ "tf": int(tf),
380
+ "cond_pixel": cond_pixel,
381
+ "value_seq_len": value_seq_len,
382
+ "stride": stride,
383
+ "video_window": cond_pixel + int(tf),
384
+ "aggregate": {
385
+ "mode": mode,
386
+ "power": power,
387
+ "weights": weights,
388
+ "dump_votes": bool(cfg.rollout_dump_votes),
389
+ },
390
+ }
391
+
392
+
393
+ def minimum_frames(cfg: InferConfig, tf: int = TEMPORAL_DOWNSAMPLE) -> int:
394
+ return int(geometry(cfg, tf)["cond_pixel"])
395
+
396
+
397
+ def _agg_weights(agg: dict[str, Any], offsets: torch.Tensor) -> torch.Tensor:
398
+ mode = agg["mode"]
399
+ if mode == "mean":
400
+ return torch.ones(int(offsets.numel()), dtype=torch.float64)
401
+ if mode == "distance":
402
+ return (offsets.to(torch.float64) + 1.0).pow(-float(agg["power"]))
403
+ weights = agg["weights"]
404
+ return torch.tensor([weights[int(o)] for o in offsets.tolist()], dtype=torch.float64)
405
+
406
+
407
+ def _accumulate_window(
408
+ state: dict[str, Any],
409
+ wv: torch.Tensor,
410
+ raw_wv: torch.Tensor,
411
+ *,
412
+ start: int,
413
+ horizon: int,
414
+ vcf_v: int,
415
+ agg: dict[str, Any],
416
+ ) -> None:
417
+ """整段预测都投票。后续窗的自回归前缀读运行加权平均(绝对进度)。"""
418
+ lo = start + vcf_v
419
+ hi = min(start + horizon, state["num_frames"])
420
+ if lo >= hi:
421
+ return
422
+ n = hi - lo
423
+ w = _agg_weights(agg, torch.arange(n))
424
+ seg_v = wv[vcf_v : vcf_v + n].to(torch.float64)
425
+ seg_r = raw_wv[vcf_v : vcf_v + n].to(torch.float64)
426
+ state["value_sum"][lo:hi] += w[:, None] * seg_v
427
+ state["raw_sum"][lo:hi] += w[:, None] * seg_r
428
+ state["weight_sum"][lo:hi] += w
429
+ first = state["votes"][lo:hi] == 0
430
+ if bool(first.any()):
431
+ idx = torch.arange(lo, hi)[first]
432
+ state["first_value"][idx] = wv[vcf_v : vcf_v + n][first]
433
+ state["first_raw"][idx] = raw_wv[vcf_v : vcf_v + n][first]
434
+ state["votes"][lo:hi] += 1
435
+ if agg["dump_votes"]:
436
+ for t in range(n):
437
+ state["votes_dump"].append(
438
+ {
439
+ "pos": lo + t,
440
+ "window_start": start,
441
+ "step_offset": t,
442
+ "weight": float(w[t]),
443
+ "raw": seg_r[t].tolist(),
444
+ "value": seg_v[t].tolist(),
445
+ }
446
+ )
447
+ w_seg = state["weight_sum"][lo:hi]
448
+ running = torch.where(
449
+ w_seg[:, None] > 0,
450
+ state["value_sum"][lo:hi] / w_seg.clamp(min=1e-12)[:, None],
451
+ state["first_value"][lo:hi].to(torch.float64),
452
+ )
453
+ state["values"][lo:hi] = running.to(torch.float32)
454
+
455
+
456
+ def _finalize_votes(state: dict[str, Any], agg: dict[str, Any]) -> tuple[torch.Tensor, torch.Tensor]:
457
+ weight = state["weight_sum"]
458
+ votes = state["votes"]
459
+ bad = [j for j in range(1, state["num_frames"]) if float(weight[j]) <= 0.0]
460
+ if bad:
461
+ raise RuntimeError(
462
+ f"rollout_aggregate={agg['mode']}: {len(bad)} positions received no "
463
+ f"positive-weight prediction (first: {bad[:5]}); check "
464
+ "rollout_aggregate_weights / rollout_stride"
465
+ )
466
+ values = state["values"].clone()
467
+ raw = state["raw_values"].clone()
468
+ single = votes == 1
469
+ multi = votes > 1
470
+ if bool(single.any()):
471
+ values[single] = state["first_value"][single]
472
+ raw[single] = state["first_raw"][single]
473
+ if bool(multi.any()):
474
+ values[multi] = (state["value_sum"][multi] / weight[multi, None]).to(torch.float32)
475
+ raw[multi] = (state["raw_sum"][multi] / weight[multi, None]).to(torch.float32)
476
+ return values, raw
477
+
478
+
479
+ def _cond_frames(video: torch.Tensor, start: int, cond_pixel: int) -> torch.Tensor:
480
+ """``[start, start + cond_pixel)``。越界位置复用最后一帧(clamp 尾窗)。"""
481
+ n = int(video.shape[0])
482
+ if start + cond_pixel <= n:
483
+ return video[start : start + cond_pixel]
484
+ idx = torch.arange(start, start + cond_pixel).clamp(max=n - 1)
485
+ return video[idx]
486
+
487
+
488
+ def resize_frame(img: Any, height: int, width: int, mode: str) -> Any:
489
+ """把一帧变成恰好 ``height`` × ``width``。PIL 的 size 是 (宽, 高)。"""
490
+ from PIL import Image
491
+
492
+ if mode not in RESIZE_MODES:
493
+ raise ValueError(f"resize_mode must be one of {RESIZE_MODES}, got {mode!r}")
494
+ if mode == "stretch":
495
+ return img.resize((width, height), resample=Image.BILINEAR)
496
+ src_w, src_h = img.size
497
+ if mode == "center_crop":
498
+ scale = max(width / src_w, height / src_h)
499
+ resized = img.resize((round(src_w * scale), round(src_h * scale)), resample=Image.BILINEAR)
500
+ rw, rh = resized.size
501
+ left = max((rw - width) // 2, 0)
502
+ top = max((rh - height) // 2, 0)
503
+ return resized.crop((left, top, left + width, top + height))
504
+ scale = min(width / src_w, height / src_h)
505
+ new_w, new_h = max(1, round(src_w * scale)), max(1, round(src_h * scale))
506
+ resized = img.resize((new_w, new_h), resample=Image.BILINEAR)
507
+ canvas = Image.new(img.mode, (width, height), 0)
508
+ canvas.paste(resized, ((width - new_w) // 2, (height - new_h) // 2))
509
+ return canvas
510
+
511
+
512
+ def frames_to_tensor(frames: list[Any], height: int, width: int, mode: str) -> torch.Tensor:
513
+ """PIL 帧 → ``[T, 3, H, W]`` float32,范围 [-1, 1]。"""
514
+ if not frames:
515
+ raise ValueError("decoded zero frames")
516
+ arr = np.empty((len(frames), height, width, 3), dtype=np.float32)
517
+ for i, frame in enumerate(frames):
518
+ arr[i] = np.asarray(resize_frame(frame, height, width, mode), dtype=np.float32)
519
+ video = torch.from_numpy(arr).permute(0, 3, 1, 2).contiguous()
520
+ return video * (2.0 / 255.0) - 1.0
521
+
522
+
523
+ def _open_rgb(path: Path) -> Any:
524
+ from PIL import Image
525
+
526
+ with Image.open(path) as img:
527
+ return img.convert("RGB")
528
+
529
+
530
+ def resolve_frame_paths(frames: list[str | Path] | str | Path) -> list[Path]:
531
+ """目录按文件名排序展开;文件列表原样使用。"""
532
+ if isinstance(frames, (str, Path)):
533
+ items: list[Path] = [Path(frames)]
534
+ else:
535
+ items = [Path(p) for p in frames]
536
+ if len(items) == 1 and items[0].is_dir():
537
+ paths = sorted(
538
+ p for p in items[0].iterdir() if p.is_file() and p.suffix.lower() in _IMAGE_SUFFIXES
539
+ )
540
+ if not paths:
541
+ raise FileNotFoundError(f"no images in {items[0]}")
542
+ return paths
543
+ missing = [p for p in items if not p.is_file()]
544
+ if missing:
545
+ raise FileNotFoundError(f"frame path is not a file: {missing[0]}")
546
+ return items
547
+
548
+
549
+ def _open_capture(path: str | Path) -> tuple[Any, Path]:
550
+ try:
551
+ import cv2
552
+ except ImportError as exc:
553
+ raise ImportError(
554
+ "opencv-python is required for video loading; "
555
+ "install with: cd release/nimcritic && uv sync"
556
+ ) from exc
557
+ file_path = Path(path).expanduser()
558
+ if not file_path.is_file():
559
+ raise ValueError(f"cannot open video file: {file_path}")
560
+ video = cv2.VideoCapture(str(file_path))
561
+ if not video.isOpened():
562
+ video.release()
563
+ raise ValueError(f"cannot open video file: {file_path}")
564
+ return video, file_path
565
+
566
+
567
+ def probe_video(path: str | Path) -> tuple[int, float]:
568
+ """返回 ``(容器帧数, fps)``。帧数读不到时为 0,留给解码再数。"""
569
+ import cv2
570
+
571
+ video, _ = _open_capture(path)
572
+ try:
573
+ n = int(video.get(cv2.CAP_PROP_FRAME_COUNT))
574
+ fps = float(video.get(cv2.CAP_PROP_FPS))
575
+ finally:
576
+ video.release()
577
+ return (n if n > 0 else 0), fps
578
+
579
+
580
+ def decode_video(path: str | Path, indices: list[int] | None = None) -> tuple[list[Any], float, int]:
581
+ """用 OpenCV 解出 RGB PIL 帧。``indices`` 给出时只保留这些源帧下标。"""
582
+ try:
583
+ from PIL import Image
584
+ except ImportError as exc:
585
+ raise ImportError(
586
+ "Pillow is required for video loading; install with: cd release/nimcritic && uv sync"
587
+ ) from exc
588
+ import cv2
589
+
590
+ video, file_path = _open_capture(path)
591
+ fps = float(video.get(cv2.CAP_PROP_FPS))
592
+ want = None if indices is None else set(indices)
593
+ image_list: list[Any] = []
594
+ seen = 0
595
+ try:
596
+ while True:
597
+ ok, frame = video.read()
598
+ if not ok:
599
+ break
600
+ if want is None or seen in want:
601
+ rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
602
+ image_list.append(Image.fromarray(rgb))
603
+ seen += 1
604
+ finally:
605
+ video.release()
606
+ if seen == 0:
607
+ raise ValueError(f"decoded zero frames from {file_path}")
608
+ if want is not None and len(image_list) != len(indices or []):
609
+ raise ValueError(
610
+ f"{file_path} reported frames that were not decoded: "
611
+ f"asked {len(indices or [])}, got {len(image_list)} of {seen}"
612
+ )
613
+ logger.info("decoded %s/%s frames from %s (fps=%s)", len(image_list), seen, file_path, fps)
614
+ return image_list, fps, seen
615
+
616
+
617
+ def load_pil_frames(
618
+ *,
619
+ video: str | Path | None = None,
620
+ frames: list[str | Path] | str | Path | None = None,
621
+ sample_hz: float = 2.0,
622
+ frame_stride: int | None = None,
623
+ ) -> tuple[list[Any], dict[str, Any]]:
624
+ """``frames`` 优先于 ``video``。返回抽帧后的 PIL 列表和采样记录。
625
+
626
+ 视频按 ``sample_hz`` 从容器帧率抽帧。帧目录或帧列表已经是序列,
627
+ ``sample_hz`` 不再生效,只看 ``frame_stride``。
628
+ """
629
+ if frames is not None:
630
+ paths = resolve_frame_paths(frames)
631
+ indices = subsample_frame_indices(len(paths), frame_stride)
632
+ if len(indices) > _LONG_EPISODE_WARN and frame_stride is None:
633
+ logger.warning("%s frames with no frame_stride", len(paths))
634
+ sampling = {
635
+ "source": "frames",
636
+ "native_fps": None,
637
+ "sample_hz": None,
638
+ "sample_hz_applied": False,
639
+ "hz_stride": None,
640
+ "frame_stride": None if frame_stride is None else int(frame_stride),
641
+ "source_frames": len(paths),
642
+ "kept_indices": indices,
643
+ }
644
+ return [_open_rgb(paths[i]) for i in indices], sampling
645
+ if video is None:
646
+ raise ValueError("infer requires video or frames")
647
+ n_probe, fps = probe_video(video)
648
+ if n_probe > 0:
649
+ indices, hz_stride = video_keep_indices(n_probe, fps, sample_hz, frame_stride)
650
+ picked, fps, seen = decode_video(video, indices)
651
+ if seen != n_probe:
652
+ raise ValueError(f"video frame count changed while reading: probe {n_probe}, decoded {seen}")
653
+ else:
654
+ decoded, fps, seen = decode_video(video)
655
+ indices, hz_stride = video_keep_indices(seen, fps, sample_hz, frame_stride)
656
+ picked = [decoded[i] for i in indices]
657
+ if len(picked) > _LONG_EPISODE_WARN:
658
+ logger.warning("keeping %s frames after sampling %s Hz from %s fps", len(picked), sample_hz, fps)
659
+ logger.info(
660
+ "video sample_hz=%s native_fps=%s hz_stride=%s kept=%s/%s",
661
+ sample_hz,
662
+ fps,
663
+ hz_stride,
664
+ len(indices),
665
+ seen,
666
+ )
667
+ sampling = {
668
+ "source": "video",
669
+ "native_fps": fps,
670
+ "sample_hz": float(sample_hz),
671
+ "sample_hz_applied": True,
672
+ "hz_stride": hz_stride,
673
+ "frame_stride": None if frame_stride is None else int(frame_stride),
674
+ "source_frames": n_probe or seen,
675
+ "kept_indices": indices,
676
+ }
677
+ return picked, sampling
678
+
679
+
680
+ def _check_weight_paths(cfg: InferConfig) -> tuple[Path, Path]:
681
+ ckpt = Path(cfg.ckpt).expanduser()
682
+ base = Path(cfg.base_model_path).expanduser()
683
+ if not ckpt.is_file():
684
+ raise FileNotFoundError(f"checkpoint is not a file: {ckpt}")
685
+ if not base.is_dir():
686
+ raise FileNotFoundError(f"base model directory is not a directory: {base}")
687
+ missing = [rel for rel in _BASE_FILES if not (base / rel).is_file()]
688
+ if missing:
689
+ raise FileNotFoundError(
690
+ f"base model directory {base} is missing {missing[0]}. "
691
+ "Point --base at the base/ directory (VAE, UMT5, tokenizer)."
692
+ )
693
+ return ckpt, base
694
+
695
+
696
+ def load_model(cfg: InferConfig) -> Any:
697
+ """加载 VAE、UMT5 和 step 权重。调用前先 ``geometry(cfg)``。"""
698
+ geometry(cfg, TEMPORAL_DOWNSAMPLE)
699
+ ckpt, base = _check_weight_paths(cfg)
700
+ try:
701
+ from nimcritic_model import NimCritic
702
+ except ImportError as exc:
703
+ raise ImportError(
704
+ "NimCritic runtime requires torch, transformers>=4.57,<4.58, "
705
+ "einops, safetensors, opencv-python-headless, and Pillow."
706
+ ) from exc
707
+
708
+ os.environ["DIFFSYNTH_MODEL_BASE_PATH"] = str(base)
709
+ if not hasattr(torch, cfg.torch_dtype):
710
+ raise ValueError(f"torch has no dtype {cfg.torch_dtype!r}")
711
+ torch_dtype = getattr(torch, cfg.torch_dtype)
712
+ logger.info(
713
+ "loading ckpt=%s base=%s device=%s dtype=%s",
714
+ ckpt,
715
+ base,
716
+ cfg.device,
717
+ cfg.torch_dtype,
718
+ )
719
+ model = NimCritic.from_wan22_pretrained(
720
+ device=cfg.device,
721
+ torch_dtype=torch_dtype,
722
+ model_id=MODEL_ID,
723
+ tokenizer_model_id=TOKENIZER_MODEL_ID,
724
+ tokenizer_max_len=TOKENIZER_MAX_LEN,
725
+ load_text_encoder=True,
726
+ redirect_common_files=True,
727
+ video_dit_config=dict(DEFAULT_VIDEO_DIT_CONFIG),
728
+ value_dit_config=dict(DEFAULT_VALUE_DIT_CONFIG),
729
+ value_dit_pretrained_path=None,
730
+ skip_dit_load_from_pretrain=True,
731
+ mot_checkpoint_mixed_attn=False,
732
+ video_infer_shift=float(cfg.video_infer_shift),
733
+ video_num_train_timesteps=1000,
734
+ value_infer_shift=float(cfg.value_infer_shift),
735
+ value_num_train_timesteps=1000,
736
+ video_condition_frames=VIDEO_CONDITION_FRAMES,
737
+ value_condition_frames=VALUE_CONDITION_FRAMES,
738
+ )
739
+ payload = model.load_checkpoint(str(ckpt))
740
+ model.eval()
741
+ tf = int(model.vae.temporal_downsample_factor)
742
+ if tf != TEMPORAL_DOWNSAMPLE:
743
+ raise RuntimeError(
744
+ f"VAE temporal_downsample_factor={tf}, expected {TEMPORAL_DOWNSAMPLE}"
745
+ )
746
+ step = payload.get("step") if isinstance(payload, dict) else None
747
+ logger.info("loaded step=%s", step)
748
+ return model
749
+
750
+
751
+ def _infer_window(
752
+ model: Any,
753
+ *,
754
+ mode: str,
755
+ task: str,
756
+ images: torch.Tensor,
757
+ gt_value: torch.Tensor,
758
+ horizon: int,
759
+ video_window: int,
760
+ cfg: InferConfig,
761
+ ) -> dict[str, Any]:
762
+ kwargs = {
763
+ "num_inference_steps": int(cfg.num_inference_steps),
764
+ "sigma_shift": None if cfg.sigma_shift is None else float(cfg.sigma_shift),
765
+ "seed": int(cfg.seed),
766
+ "rand_device": str(cfg.rand_device),
767
+ "tiled": bool(cfg.tiled),
768
+ "value_progress_repr": cfg.value_progress_repr,
769
+ "video_condition_frames": VIDEO_CONDITION_FRAMES,
770
+ "value_condition_frames": VALUE_CONDITION_FRAMES,
771
+ }
772
+ if mode == "value":
773
+ return model.infer_value(
774
+ prompt=task,
775
+ input_image=images,
776
+ value_horizon=horizon,
777
+ gt_value=gt_value,
778
+ **kwargs,
779
+ )
780
+ return model.infer_joint(
781
+ prompt=task,
782
+ input_image=images,
783
+ num_video_frames=video_window,
784
+ value_horizon=horizon,
785
+ value=gt_value,
786
+ test_value_with_infer_value=False,
787
+ **kwargs,
788
+ )
789
+
790
+
791
+ def rollout(
792
+ model: Any,
793
+ video: torch.Tensor,
794
+ task: str,
795
+ mode: str,
796
+ *,
797
+ value_init: list[float],
798
+ tail_mode: str,
799
+ cfg: InferConfig,
800
+ ) -> tuple[np.ndarray, np.ndarray, np.ndarray | None, dict[str, Any], list[dict[str, Any]] | None, float]:
801
+ """一条 episode 的滑窗。返回绝对进度 value、反算前 raw、joint 帧、切分信息、投票、秒数。"""
802
+ if mode not in INFER_MODES:
803
+ raise ValueError(f"unknown infer_mode {mode!r}")
804
+ if tail_mode not in TAIL_MODES:
805
+ raise ValueError(f"unknown tail_mode {tail_mode!r}")
806
+ tf = int(model.vae.temporal_downsample_factor)
807
+ geom = geometry(cfg, tf)
808
+ from nimcritic_model import decode_window_progress
809
+ agg = geom["aggregate"]
810
+ aggregating = agg["mode"] != "first"
811
+ cond_pixel = geom["cond_pixel"]
812
+ vcf_v = geom["vcf_v"]
813
+ stride = geom["stride"]
814
+ value_dim = int(model.value_expert.value_dim)
815
+ if len(value_init) != value_dim:
816
+ raise ValueError(f"value_init length {len(value_init)} != value_dim {value_dim}")
817
+ num_frames = int(video.shape[0])
818
+ if num_frames < cond_pixel:
819
+ raise ValueError(f"episode has {num_frames} frames < {cond_pixel} condition frames")
820
+
821
+ init = torch.tensor(value_init, dtype=torch.float32)
822
+ values = torch.zeros((num_frames, value_dim), dtype=torch.float32)
823
+ values[0] = init
824
+ raw_values = torch.zeros((num_frames, value_dim), dtype=torch.float32)
825
+ raw_values[0] = init
826
+ state: dict[str, Any] = {
827
+ "video": video,
828
+ "num_frames": num_frames,
829
+ "values": values,
830
+ "raw_values": raw_values,
831
+ "filled": 1,
832
+ "n_windows": 0,
833
+ "pred_frames": {},
834
+ "done": num_frames <= 1,
835
+ }
836
+ if aggregating:
837
+ state.update(
838
+ value_sum=torch.zeros((num_frames, value_dim), dtype=torch.float64),
839
+ raw_sum=torch.zeros((num_frames, value_dim), dtype=torch.float64),
840
+ weight_sum=torch.zeros(num_frames, dtype=torch.float64),
841
+ votes=torch.zeros(num_frames, dtype=torch.long),
842
+ first_value=torch.zeros((num_frames, value_dim), dtype=torch.float32),
843
+ first_raw=torch.zeros((num_frames, value_dim), dtype=torch.float32),
844
+ votes_dump=[],
845
+ )
846
+
847
+ runtime = 0.0
848
+ while not state["done"]:
849
+ if state["filled"] >= num_frames:
850
+ state["done"] = True
851
+ break
852
+ start = state["filled"] - vcf_v
853
+ if tail_mode == "reanchor" and start + cond_pixel > num_frames:
854
+ start = num_frames - cond_pixel
855
+ horizon = min(geom["value_seq_len"], num_frames - start)
856
+ images = _cond_frames(video, start, cond_pixel)
857
+ gt_value = torch.zeros((1, horizon, value_dim), dtype=torch.float32)
858
+ gt_value[0, :vcf_v] = state["values"][start : start + vcf_v]
859
+ logger.info(
860
+ "window start=%s horizon=%s filled=%s/%s mode=%s",
861
+ start,
862
+ horizon,
863
+ state["filled"],
864
+ num_frames,
865
+ mode,
866
+ )
867
+ started = time.perf_counter()
868
+ out = _infer_window(
869
+ model,
870
+ mode=mode,
871
+ task=task,
872
+ images=images,
873
+ gt_value=gt_value,
874
+ horizon=horizon,
875
+ video_window=geom["video_window"],
876
+ cfg=cfg,
877
+ )
878
+ runtime += time.perf_counter() - started
879
+ window_value = torch.as_tensor(out["value"], dtype=torch.float32)
880
+ if window_value.ndim != 2 or window_value.shape[0] != horizon:
881
+ raise ValueError(
882
+ f"window: expected value [h={horizon}, value_dim], got shape {tuple(window_value.shape)}"
883
+ )
884
+ window_value = window_value.unsqueeze(0)
885
+ raw_window_value = window_value
886
+ window_value = decode_window_progress(window_value, gt_value, vcf_v, cfg.value_progress_repr)
887
+ wv = window_value[0]
888
+ raw_wv = raw_window_value[0]
889
+ keep = min(stride, start + horizon - state["filled"])
890
+ if aggregating:
891
+ _accumulate_window(
892
+ state, wv, raw_wv, start=start, horizon=horizon, vcf_v=vcf_v, agg=agg
893
+ )
894
+ else:
895
+ fill_slice = slice(state["filled"], state["filled"] + keep)
896
+ src_slice = slice(state["filled"] - start, state["filled"] - start + keep)
897
+ state["values"][fill_slice] = wv[src_slice]
898
+ state["raw_values"][fill_slice] = raw_wv[src_slice]
899
+ state["filled"] += keep
900
+ state["n_windows"] += 1
901
+ if state["filled"] >= num_frames:
902
+ state["done"] = True
903
+ if mode == "joint":
904
+ frames = out.get("video")
905
+ if len(frames) != geom["video_window"]:
906
+ raise ValueError(
907
+ f"window s={start}: infer_joint must decode {geom['video_window']} "
908
+ f"frames, got {len(frames)}"
909
+ )
910
+ for fi in range(cond_pixel, min(cond_pixel + stride, len(frames))):
911
+ abs_idx = start + fi
912
+ if abs_idx < num_frames:
913
+ state["pred_frames"][abs_idx] = np.asarray(frames[fi].convert("RGB"), dtype=np.uint8)
914
+
915
+ split: dict[str, Any] = {
916
+ "cond_pixel": cond_pixel,
917
+ "pred_start": cond_pixel,
918
+ "pred_end": num_frames,
919
+ "n_windows": state["n_windows"],
920
+ "stride": stride,
921
+ "value_seq_len": geom["value_seq_len"],
922
+ "aggregate": agg["mode"],
923
+ }
924
+ if agg["mode"] == "distance":
925
+ split["distance_power"] = agg["power"]
926
+ elif agg["mode"] == "custom":
927
+ split["weights"] = agg["weights"]
928
+ if aggregating:
929
+ values_t, raw_t = _finalize_votes(state, agg)
930
+ value = values_t.numpy().astype(np.float64)
931
+ raw = raw_t.numpy().astype(np.float64)
932
+ else:
933
+ value = state["values"].numpy().astype(np.float64)
934
+ raw = state["raw_values"].numpy().astype(np.float64)
935
+ votes = state["votes_dump"] if aggregating and agg["dump_votes"] else None
936
+ pred: np.ndarray | None
937
+ if mode == "value" or num_frames == cond_pixel:
938
+ pred = None
939
+ else:
940
+ missing = [j for j in range(cond_pixel, num_frames) if j not in state["pred_frames"]]
941
+ if missing:
942
+ raise RuntimeError(
943
+ f"joint rollout left {len(missing)} unpredicted frames "
944
+ f"(first: {missing[:5]}); predictions must tile [{cond_pixel}, {num_frames})"
945
+ )
946
+ pred = np.stack([state["pred_frames"][j] for j in range(cond_pixel, num_frames)])
947
+ return value, raw, pred, split, votes, runtime
948
+
949
+
950
+ def _save_pred_frames(frames: np.ndarray, directory: Path, cond_pixel: int) -> None:
951
+ from PIL import Image
952
+
953
+ directory.mkdir(parents=True, exist_ok=True)
954
+ for offset, frame in enumerate(frames):
955
+ Image.fromarray(frame).save(directory / f"frame_{cond_pixel + offset:06d}.png")
956
+
957
+
958
+ def _pack_pass(
959
+ value: np.ndarray,
960
+ raw: np.ndarray,
961
+ split: dict[str, Any],
962
+ votes: list[dict[str, Any]] | None,
963
+ pred: np.ndarray | None,
964
+ pred_dir: Path | None,
965
+ runtime: float,
966
+ ) -> dict[str, Any]:
967
+ if pred is not None and pred_dir is not None:
968
+ _save_pred_frames(pred, pred_dir, int(split["cond_pixel"]))
969
+ packed: dict[str, Any] = {
970
+ "progress": value[:, 0].tolist(),
971
+ "success": value[:, 1].tolist(),
972
+ "value": value.tolist(),
973
+ "raw_value": raw.tolist(),
974
+ "rollout": split,
975
+ "votes": votes,
976
+ "runtime_seconds": runtime,
977
+ }
978
+ if pred is not None and pred_dir is not None:
979
+ packed["pred_frames_dir"] = str(pred_dir)
980
+ return packed
981
+
982
+
983
+ def infer(
984
+ model: Any,
985
+ *,
986
+ video: str | Path | None = None,
987
+ frames: list[str | Path] | str | Path | None = None,
988
+ task: str,
989
+ cfg: InferConfig,
990
+ pred_frames_dir: str | Path | None = None,
991
+ reverse_pred_frames_dir: str | Path | None = None,
992
+ ) -> dict[str, Any]:
993
+ """对一条视频或一组帧做滑窗推理。
994
+
995
+ 反向曲线的时间顺序是翻转后的:下标 0 对应原视频最后一帧,与评测包里
996
+ 落盘的 ``reverse_values`` 相同(评测在算分前才翻回正序)。
997
+ """
998
+ tf = int(model.vae.temporal_downsample_factor)
999
+ geometry(cfg, tf)
1000
+ picked, sampling = load_pil_frames(
1001
+ video=video,
1002
+ frames=frames,
1003
+ sample_hz=float(cfg.sample_hz),
1004
+ frame_stride=cfg.frame_stride,
1005
+ )
1006
+ tensor = frames_to_tensor(picked, int(cfg.height), int(cfg.width), cfg.resize_mode)
1007
+ prompt = wrap_training_task(task)
1008
+ forward_init = [float(v) for v in cfg.value_cond_init]
1009
+ fwd_value, fwd_raw, fwd_pred, fwd_split, fwd_votes, fwd_runtime = rollout(
1010
+ model,
1011
+ tensor,
1012
+ prompt,
1013
+ cfg.infer_mode,
1014
+ value_init=forward_init,
1015
+ tail_mode=cfg.tail_mode,
1016
+ cfg=cfg,
1017
+ )
1018
+ result = _pack_pass(
1019
+ fwd_value,
1020
+ fwd_raw,
1021
+ fwd_split,
1022
+ fwd_votes,
1023
+ fwd_pred,
1024
+ Path(pred_frames_dir) if pred_frames_dir is not None else None,
1025
+ fwd_runtime,
1026
+ )
1027
+ result["task"] = str(task or "")
1028
+ result["prompt"] = prompt
1029
+ result["num_frames"] = int(tensor.shape[0])
1030
+ result["sampling"] = sampling
1031
+ result["config"] = cfg.public_dict()
1032
+ if cfg.reverse:
1033
+ reverse_init = [float(v) for v in cfg.reverse_value_cond_init]
1034
+ rev_value, rev_raw, rev_pred, rev_split, rev_votes, rev_runtime = rollout(
1035
+ model,
1036
+ torch.flip(tensor, dims=[0]),
1037
+ prompt,
1038
+ cfg.reverse_infer_mode,
1039
+ value_init=reverse_init,
1040
+ tail_mode=cfg.reverse_tail_mode,
1041
+ cfg=cfg,
1042
+ )
1043
+ reverse = _pack_pass(
1044
+ rev_value,
1045
+ rev_raw,
1046
+ rev_split,
1047
+ rev_votes,
1048
+ rev_pred,
1049
+ Path(reverse_pred_frames_dir) if reverse_pred_frames_dir is not None else None,
1050
+ rev_runtime,
1051
+ )
1052
+ reverse["time_order"] = "flipped"
1053
+ result["reverse"] = reverse
1054
+ else:
1055
+ result["reverse"] = None
1056
+ return result
1057
+
1058
+
1059
+ def dump_result(result: dict[str, Any], output: str | Path | None) -> None:
1060
+ text = json.dumps(result, ensure_ascii=False, indent=2)
1061
+ if output is None:
1062
+ sys.stdout.write(text)
1063
+ sys.stdout.write("\n")
1064
+ return
1065
+ path = Path(output)
1066
+ path.parent.mkdir(parents=True, exist_ok=True)
1067
+ path.write_text(text + "\n", encoding="utf-8")
1068
+ logger.info("wrote %s", path)
1069
+
1070
+
1071
+ def self_check() -> None:
1072
+ """抽帧、resize 尺寸、非法参数。不加载权重。"""
1073
+ from PIL import Image
1074
+
1075
+ assert subsample_frame_indices(10, None) == list(range(10))
1076
+ assert subsample_frame_indices(10, 1) == list(range(10))
1077
+ assert subsample_frame_indices(10, 3) == [0, 3, 6, 9]
1078
+ assert subsample_frame_indices(10, 4) == [0, 4, 8, 9]
1079
+ assert subsample_frame_indices(0, 3) == []
1080
+ try:
1081
+ subsample_frame_indices(4, 0)
1082
+ except ValueError:
1083
+ pass
1084
+ else:
1085
+ raise AssertionError("frame_stride 0 should fail")
1086
+
1087
+ src = Image.new("RGB", (100, 40), (255, 0, 0))
1088
+ for mode in RESIZE_MODES:
1089
+ out = resize_frame(src, 256, 448, mode)
1090
+ if out.size != (448, 256):
1091
+ raise AssertionError(f"{mode} size {out.size}, expected (448, 256)")
1092
+ stretch = np.asarray(resize_frame(src, 32, 48, "stretch"))
1093
+ if stretch.shape != (32, 48, 3):
1094
+ raise AssertionError(f"stretch array shape {stretch.shape}")
1095
+ letter = np.asarray(resize_frame(src, 32, 48, "letterbox"))
1096
+ if int(letter[0, 0, 0]) != 0:
1097
+ raise AssertionError("letterbox corner should be padded black")
1098
+
1099
+ ok = geometry(InferConfig())
1100
+ if ok["stride"] != 1 or ok["cond_pixel"] != 5 or ok["aggregate"]["mode"] != "distance":
1101
+ raise AssertionError(f"yaml defaults drifted: {ok}")
1102
+ if InferConfig().sample_hz != 2.0:
1103
+ raise AssertionError("sample_hz default must be 2")
1104
+ if video_keep_indices(60, 30.0, 2.0) != ([0, 15, 30, 45, 59], 15):
1105
+ raise AssertionError(f"30fps→2Hz indices drifted: {video_keep_indices(60, 30.0, 2.0)}")
1106
+ if video_keep_indices(31, 30.0, 2.0)[0] != [0, 15, 30]:
1107
+ raise AssertionError("30fps→2Hz should keep the last on-grid frame")
1108
+ if video_keep_indices(10, 2.0, 2.0)[0] != list(range(10)):
1109
+ raise AssertionError("2fps video at 2Hz should keep every frame")
1110
+ if video_keep_indices(60, 30.0, 2.0, 2)[0] != [0, 30, 59]:
1111
+ raise AssertionError("frame_stride should thin the 2Hz grid")
1112
+ try:
1113
+ video_keep_indices(10, 0.0, 2.0)
1114
+ except ValueError:
1115
+ pass
1116
+ else:
1117
+ raise AssertionError("missing fps should fail")
1118
+
1119
+ bad_cases = [
1120
+ InferConfig(rollout_stride=0),
1121
+ InferConfig(rollout_stride=99),
1122
+ InferConfig(rollout_aggregate="custom"),
1123
+ InferConfig(rollout_aggregate="custom", rollout_aggregate_weights=[1.0, 1.0]),
1124
+ InferConfig(rollout_aggregate="custom", rollout_aggregate_weights=[0.0, 0.0, 0.0, 0.0]),
1125
+ InferConfig(height=255, width=448),
1126
+ InferConfig(tail_mode="pad"),
1127
+ InferConfig(rollout_aggregate="nope"),
1128
+ InferConfig(value_seq_len=3, tail_mode="reanchor"),
1129
+ InferConfig(infer_mode="joint", value_seq_len=9, rollout_stride=5, tail_mode="clamp"),
1130
+ InferConfig(rollout_aggregate="distance", rollout_aggregate_distance_power=0.0),
1131
+ InferConfig(frame_stride=0),
1132
+ InferConfig(sample_hz=0),
1133
+ InferConfig(value_progress_repr="delta"),
1134
+ ]
1135
+ for cfg in bad_cases:
1136
+ try:
1137
+ geometry(cfg)
1138
+ except ValueError:
1139
+ continue
1140
+ raise AssertionError(f"expected ValueError for {cfg}")
1141
+
1142
+ wrapped = wrap_training_task("pick up the cup")
1143
+ if not wrapped.startswith(TRAINING_TASK_PREFIX) or wrap_training_task(wrapped) != wrapped:
1144
+ raise AssertionError("task prefix wrap failed")
1145
+ logger.info("self-check ok")
1146
+
1147
+
1148
+ def _csv_floats(text: str) -> list[float]:
1149
+ parts = [p.strip() for p in text.split(",") if p.strip()]
1150
+ if not parts:
1151
+ raise argparse.ArgumentTypeError("expected comma-separated floats")
1152
+ try:
1153
+ return [float(p) for p in parts]
1154
+ except ValueError as exc:
1155
+ raise argparse.ArgumentTypeError(str(exc)) from exc
1156
+
1157
+
1158
+ def _opt(meaning: str, choices: str, default: str) -> str:
1159
+ return f"{meaning}\n可选:{choices}\n默认:{default}"
1160
+
1161
+
1162
+ def _build_parser() -> argparse.ArgumentParser:
1163
+ p = argparse.ArgumentParser(
1164
+ description=(
1165
+ "NimCritic 单条视频推理。\n"
1166
+ "默认口径与 configs/model/nimcritic.yaml 相同(rollout_stride=1)。\n"
1167
+ "直接给 --video 时按容器帧率抽到 --sample-hz(默认 2Hz)。\n"
1168
+ "已抽好的 --frames 不再按 sample-hz 重抽。\n"
1169
+ "下列结构与这份 step 128000 绑定,不能从命令行改:"
1170
+ "video_condition_frames=2,value_condition_frames=1,"
1171
+ "tokenizer_max_len=128,skip_dit_load_from_pretrain=true。"
1172
+ ),
1173
+ formatter_class=argparse.RawTextHelpFormatter,
1174
+ )
1175
+ p.add_argument(
1176
+ "--self-check",
1177
+ action="store_true",
1178
+ help=_opt(
1179
+ "不加载权重,只检查抽帧公式、三种 resize 的输出尺寸,以及非法参数会不会报错。",
1180
+ "加上即运行;不加则走推理。",
1181
+ "关闭",
1182
+ ),
1183
+ )
1184
+ p.add_argument(
1185
+ "--video",
1186
+ type=Path,
1187
+ default=None,
1188
+ help=_opt(
1189
+ "一条视频文件。按容器 fps 抽到 --sample-hz,并始终保留最后一帧。和 --frames 同时给时不用视频。",
1190
+ "可读的视频路径。容器里必须有 fps,否则报错。",
1191
+ "无",
1192
+ ),
1193
+ )
1194
+ p.add_argument(
1195
+ "--frames",
1196
+ type=Path,
1197
+ nargs="+",
1198
+ default=None,
1199
+ help=_opt(
1200
+ "已经抽好的帧。给一个目录时按文件名排序;给多个路径时按你写的顺序。sample-hz 对帧序列不生效。",
1201
+ "目录,或 jpg/jpeg/png/webp/bmp 文件。",
1202
+ "无",
1203
+ ),
1204
+ )
1205
+ p.add_argument(
1206
+ "--task",
1207
+ default=None,
1208
+ help=_opt(
1209
+ "任务指令。送进模型前包一层训练前缀;字符串已经带这个前缀时不包第二次。",
1210
+ "任意文本。推理时必填。",
1211
+ "无",
1212
+ ),
1213
+ )
1214
+ p.add_argument(
1215
+ "--output",
1216
+ type=Path,
1217
+ default=None,
1218
+ help=_opt("把 progress、success、采样记录和本次配置写成 JSON。", "文件路径。", "打到 stdout"),
1219
+ )
1220
+ p.add_argument(
1221
+ "--pred-frames-dir",
1222
+ type=Path,
1223
+ default=None,
1224
+ help=_opt(
1225
+ "infer-mode=joint 时,预测帧写成 PNG 的目录。反向 joint 会再写一个同名加 _reverse 的目录。",
1226
+ "目录路径。value 模式忽略。",
1227
+ "给了 --output 时用 <输出名>_pred_frames,否则不落盘",
1228
+ ),
1229
+ )
1230
+ p.add_argument(
1231
+ "--ckpt",
1232
+ type=Path,
1233
+ default=argparse.SUPPRESS,
1234
+ help=_opt(
1235
+ "NimCritic 的 .pt 权重。加载时生效。",
1236
+ "文件路径。",
1237
+ "nimcritic_step_128000.pt(与本脚本同目录)",
1238
+ ),
1239
+ )
1240
+ p.add_argument(
1241
+ "--base",
1242
+ dest="base_model_path",
1243
+ type=Path,
1244
+ default=argparse.SUPPRESS,
1245
+ help=_opt(
1246
+ "Wan2.2 VAE、UMT5-XXL 和分词器所在目录(weights/base 这一层)。加载时生效。",
1247
+ "目录路径。",
1248
+ "base(与本脚本同目录)",
1249
+ ),
1250
+ )
1251
+ p.add_argument(
1252
+ "--device",
1253
+ default=argparse.SUPPRESS,
1254
+ help=_opt("模型所在设备。加载时生效。", "cuda、cuda:0、cpu 等 PyTorch 设备名。", "cuda"),
1255
+ )
1256
+ p.add_argument(
1257
+ "--torch-dtype",
1258
+ dest="torch_dtype",
1259
+ choices=("bfloat16", "float16", "float32"),
1260
+ default=argparse.SUPPRESS,
1261
+ help=_opt("权重 dtype。加载时生效。", "bfloat16、float16、float32。", "bfloat16"),
1262
+ )
1263
+ p.add_argument(
1264
+ "--height",
1265
+ type=int,
1266
+ default=argparse.SUPPRESS,
1267
+ help=_opt("送进模型前的帧高。", "16 的正倍数。", "256"),
1268
+ )
1269
+ p.add_argument(
1270
+ "--width",
1271
+ type=int,
1272
+ default=argparse.SUPPRESS,
1273
+ help=_opt("送进模型前的帧宽。", "16 的正倍数。", "448"),
1274
+ )
1275
+ p.add_argument(
1276
+ "--resize-mode",
1277
+ dest="resize_mode",
1278
+ choices=RESIZE_MODES,
1279
+ default=argparse.SUPPRESS,
1280
+ help=_opt(
1281
+ "把原帧变成 height×width 的方式。center_crop 先等比放大再中心裁掉多余部分;stretch 直接拉满,不保留宽高比;letterbox 先等比缩小再上下或左右补黑边。",
1282
+ "center_crop、stretch、letterbox。",
1283
+ "stretch",
1284
+ ),
1285
+ )
1286
+ p.add_argument(
1287
+ "--sample-hz",
1288
+ dest="sample_hz",
1289
+ type=float,
1290
+ default=argparse.SUPPRESS,
1291
+ help=_opt(
1292
+ "只对 --video 生效的目标采样频率。步长 = round(容器fps / sample-hz),至少为 1,并保留最后一帧。源 fps 不高于目标时保留全部解码帧。--frames 已经是帧序列,这个参数不再生效。",
1293
+ "大于 0 的赫兹数。训练和发布评测都是 2Hz。",
1294
+ "2",
1295
+ ),
1296
+ )
1297
+ p.add_argument(
1298
+ "--frame-stride",
1299
+ dest="frame_stride",
1300
+ type=int,
1301
+ default=argparse.SUPPRESS,
1302
+ help=_opt(
1303
+ "在已经决定的帧序列上再按序号抽帧,保留 0、stride、2*stride…以及末帧。--video 时作用在 sample-hz 抽完之后;--frames 时直接作用在给定帧上。",
1304
+ "整数 >= 1。1 与省略相同,表示这一步不再抽。",
1305
+ "不抽",
1306
+ ),
1307
+ )
1308
+ p.add_argument(
1309
+ "--infer-mode",
1310
+ dest="infer_mode",
1311
+ choices=INFER_MODES,
1312
+ default=argparse.SUPPRESS,
1313
+ help=_opt(
1314
+ "value 只去噪 progress/success,video expert 作条件。joint 每个窗同时去噪一段预测帧,并可以写成 PNG。",
1315
+ "value、joint。",
1316
+ "value",
1317
+ ),
1318
+ )
1319
+ p.add_argument(
1320
+ "--reverse",
1321
+ action="store_true",
1322
+ default=argparse.SUPPRESS,
1323
+ help=_opt(
1324
+ "把时间翻转后再跑一遍滑窗,起点用 --reverse-value-cond-init。结果里 reverse 的下标 0 是原视频最后一帧。",
1325
+ "加上即开启。",
1326
+ "关闭",
1327
+ ),
1328
+ )
1329
+ p.add_argument(
1330
+ "--reverse-infer-mode",
1331
+ dest="reverse_infer_mode",
1332
+ choices=INFER_MODES,
1333
+ default=argparse.SUPPRESS,
1334
+ help=_opt("反向那一遍用 value 还是 joint。含义同 --infer-mode。", "value、joint。", "value"),
1335
+ )
1336
+ p.add_argument(
1337
+ "--value-seq-len",
1338
+ dest="value_seq_len",
1339
+ type=int,
1340
+ default=argparse.SUPPRESS,
1341
+ help=_opt(
1342
+ "每个滑窗的 value 步数,其中第 1 步钉在上一窗的预测上。尾窗为 reanchor 时必须 >= 5(条件像素帧数)。",
1343
+ "整数 >= 1,且不小于条件步数。",
1344
+ "5",
1345
+ ),
1346
+ )
1347
+ p.add_argument(
1348
+ "--rollout-stride",
1349
+ dest="rollout_stride",
1350
+ type=int,
1351
+ default=argparse.SUPPRESS,
1352
+ help=_opt(
1353
+ "每个窗写回的新位置数。调小会让同一位置被后面的窗重推。joint 时不能超过 4。论文短任务表用的是 2,发布 yaml 是 1。",
1354
+ "1 到 value-seq-len-1(默认上限 4)。",
1355
+ "1",
1356
+ ),
1357
+ )
1358
+ p.add_argument(
1359
+ "--rollout-aggregate",
1360
+ dest="rollout_aggregate",
1361
+ choices=AGGREGATE_MODES,
1362
+ default=argparse.SUPPRESS,
1363
+ help=_opt(
1364
+ "同一位置被多个窗预测时怎么合并,合并发生在还原成绝对进度之后。first 只保留每窗 stride 个新位置;mean 对全部预测简单平均;distance 按窗内预测步序号 o(从 0 起)加权 1/(o+1)^power;custom 按 --rollout-aggregate-weights 加权。后一窗的条件帧读的是运行中的平均。",
1365
+ "first、mean、distance、custom。",
1366
+ "distance",
1367
+ ),
1368
+ )
1369
+ p.add_argument(
1370
+ "--rollout-aggregate-distance-power",
1371
+ dest="rollout_aggregate_distance_power",
1372
+ type=float,
1373
+ default=argparse.SUPPRESS,
1374
+ help=_opt("distance 聚合的指数 power。", "大于 0 的实数。", "1"),
1375
+ )
1376
+ p.add_argument(
1377
+ "--rollout-aggregate-weights",
1378
+ dest="rollout_aggregate_weights",
1379
+ type=_csv_floats,
1380
+ default=argparse.SUPPRESS,
1381
+ help=_opt(
1382
+ "custom 聚合的逐预测步权重,逗号分隔。下标 0 是窗内第一个新预测步。",
1383
+ "长度必须等于 value-seq-len-1(默认 4);每个数有限且 >= 0,不能全是 0。",
1384
+ "无;只有 aggregate=custom 时必填",
1385
+ ),
1386
+ )
1387
+ p.add_argument(
1388
+ "--rollout-dump-votes",
1389
+ dest="rollout_dump_votes",
1390
+ action=argparse.BooleanOptionalAction,
1391
+ default=argparse.SUPPRESS,
1392
+ help=_opt(
1393
+ "在 JSON 里写下每次投票的位置、窗起点、步序号、权重和数值。first 聚合没有重叠票,不写。用 --no-rollout-dump-votes 关闭。",
1394
+ "开启或关闭。",
1395
+ "开启",
1396
+ ),
1397
+ )
1398
+ p.add_argument(
1399
+ "--tail-mode",
1400
+ dest="tail_mode",
1401
+ choices=TAIL_MODES,
1402
+ default=argparse.SUPPRESS,
1403
+ help=_opt(
1404
+ "结尾放不下 5 个条件帧时的正向尾窗。reanchor 把窗口挪到结尾前 5 帧,条件帧全是真实帧;clamp 不挪,越界的条件帧重复最后一帧,只保留还在片内的预测。",
1405
+ "reanchor、clamp。",
1406
+ "clamp",
1407
+ ),
1408
+ )
1409
+ p.add_argument(
1410
+ "--reverse-tail-mode",
1411
+ dest="reverse_tail_mode",
1412
+ choices=TAIL_MODES,
1413
+ default=argparse.SUPPRESS,
1414
+ help=_opt("反向那一遍的尾窗策略。含义同 --tail-mode。", "reanchor、clamp。", "reanchor"),
1415
+ )
1416
+ p.add_argument(
1417
+ "--num-inference-steps",
1418
+ dest="num_inference_steps",
1419
+ type=int,
1420
+ default=argparse.SUPPRESS,
1421
+ help=_opt("每个窗的去噪步数。joint 时 video 和 value 用同一步数。", "整数 >= 1。", "20"),
1422
+ )
1423
+ p.add_argument(
1424
+ "--sigma-shift",
1425
+ dest="sigma_shift",
1426
+ type=float,
1427
+ default=argparse.SUPPRESS,
1428
+ help=_opt(
1429
+ "这一次调用同时覆盖 video 和 value 两个 scheduler 的 shift。省略时各用各的 --video-infer-shift / --value-infer-shift。",
1430
+ "实数。省略表示不覆盖。",
1431
+ "不覆盖",
1432
+ ),
1433
+ )
1434
+ p.add_argument(
1435
+ "--seed",
1436
+ type=int,
1437
+ default=argparse.SUPPRESS,
1438
+ help=_opt("每个窗去噪噪声的种子。每个窗都重新用这个种子,不递增。", "整数。", "42"),
1439
+ )
1440
+ p.add_argument(
1441
+ "--rand-device",
1442
+ dest="rand_device",
1443
+ default=argparse.SUPPRESS,
1444
+ help=_opt("生成噪声的设备。放在 cpu 上时换 GPU 也保持同一条噪声。", "cpu 或 cuda。", "cpu"),
1445
+ )
1446
+ p.add_argument(
1447
+ "--tiled",
1448
+ action="store_true",
1449
+ default=argparse.SUPPRESS,
1450
+ help=_opt("VAE 编解码按块进行,省显存,结果与整帧编解码略有差别。", "加上即开启。", "关闭"),
1451
+ )
1452
+ p.add_argument(
1453
+ "--value-cond-init",
1454
+ dest="value_cond_init",
1455
+ type=_csv_floats,
1456
+ default=argparse.SUPPRESS,
1457
+ help=_opt(
1458
+ "正向第一帧钉住的 [progress, success]。后面的窗改为钉上一窗的预测。",
1459
+ "两个逗号分隔的数,分别在 progress 和 success 的 0–1 刻度上。",
1460
+ "0,0",
1461
+ ),
1462
+ )
1463
+ p.add_argument(
1464
+ "--reverse-value-cond-init",
1465
+ dest="reverse_value_cond_init",
1466
+ type=_csv_floats,
1467
+ default=argparse.SUPPRESS,
1468
+ help=_opt(
1469
+ "反向第一帧钉住的 [progress, success]。翻转后的序列从原视频结尾开始,所以默认是完成态。",
1470
+ "两个逗号分隔的数。",
1471
+ "1,1",
1472
+ ),
1473
+ )
1474
+ p.add_argument(
1475
+ "--value-progress-repr",
1476
+ dest="value_progress_repr",
1477
+ choices=PROGRESS_REPRS,
1478
+ default=argparse.SUPPRESS,
1479
+ help=_opt(
1480
+ "progress 通道的含义,必须和权重的训练口径一致。relative:预测值是相对该窗第一个条件帧的增量,范围 [-1, 1],写回前还原成绝对 0–1。absolute:模型直接输出绝对进度。success 两种口径都是绝对 0–1。这份 step 128000 是 relative。",
1481
+ "absolute、relative。",
1482
+ "relative",
1483
+ ),
1484
+ )
1485
+ p.add_argument(
1486
+ "--video-infer-shift",
1487
+ dest="video_infer_shift",
1488
+ type=float,
1489
+ default=argparse.SUPPRESS,
1490
+ help=_opt(
1491
+ "video scheduler 的 shift。只在 joint 且没有 --sigma-shift 时影响去噪。加载时生效,改它需要重新 load_model。",
1492
+ "实数。",
1493
+ "5",
1494
+ ),
1495
+ )
1496
+ p.add_argument(
1497
+ "--value-infer-shift",
1498
+ dest="value_infer_shift",
1499
+ type=float,
1500
+ default=argparse.SUPPRESS,
1501
+ help=_opt(
1502
+ "value scheduler 的 shift。没有 --sigma-shift 时使用。加载时生效,改它需要重新 load_model。",
1503
+ "实数。",
1504
+ "5",
1505
+ ),
1506
+ )
1507
+ return p
1508
+
1509
+
1510
+ def config_from_args(args: argparse.Namespace) -> InferConfig:
1511
+ cfg = InferConfig()
1512
+ for key, value in vars(args).items():
1513
+ if hasattr(cfg, key):
1514
+ setattr(cfg, key, value)
1515
+ return cfg
1516
+
1517
+
1518
+ def main(argv: list[str] | None = None) -> None:
1519
+ logging.basicConfig(
1520
+ level=logging.INFO,
1521
+ format="%(asctime)s %(levelname)s %(name)s: %(message)s",
1522
+ )
1523
+ args = _build_parser().parse_args(argv)
1524
+ if args.self_check:
1525
+ self_check()
1526
+ return
1527
+ if not args.task:
1528
+ raise SystemExit("inference requires --task")
1529
+ if args.video is None and args.frames is None:
1530
+ raise SystemExit("inference requires --video or --frames")
1531
+ cfg = config_from_args(args)
1532
+ geom = geometry(cfg, TEMPORAL_DOWNSAMPLE)
1533
+ if args.frames is not None:
1534
+ n_kept = len(subsample_frame_indices(len(resolve_frame_paths(args.frames)), cfg.frame_stride))
1535
+ else:
1536
+ n_src, fps = probe_video(args.video)
1537
+ if n_src <= 0:
1538
+ n_kept = None
1539
+ if not math.isfinite(fps) or fps <= 0.0:
1540
+ raise ValueError(
1541
+ f"video fps is {fps}, cannot sample at {cfg.sample_hz} Hz. "
1542
+ "Use a file that records a frame rate, or pass --frames."
1543
+ )
1544
+ else:
1545
+ n_kept = len(video_keep_indices(n_src, fps, cfg.sample_hz, cfg.frame_stride)[0])
1546
+ if n_kept is not None and n_kept < geom["cond_pixel"]:
1547
+ raise ValueError(
1548
+ f"episode has {n_kept} frames after subsample < {geom['cond_pixel']} condition frames"
1549
+ )
1550
+ pred_dir = args.pred_frames_dir
1551
+ reverse_pred_dir = None
1552
+ if cfg.infer_mode == "joint" and pred_dir is None and args.output is not None:
1553
+ pred_dir = args.output.with_suffix("")
1554
+ pred_dir = pred_dir.parent / f"{pred_dir.name}_pred_frames"
1555
+ if cfg.reverse and cfg.reverse_infer_mode == "joint":
1556
+ if pred_dir is None:
1557
+ reverse_pred_dir = Path("nimcritic_reverse_pred_frames")
1558
+ else:
1559
+ reverse_pred_dir = pred_dir.parent / f"{pred_dir.name}_reverse"
1560
+ model = load_model(cfg)
1561
+ result = infer(
1562
+ model,
1563
+ video=args.video,
1564
+ frames=args.frames,
1565
+ task=args.task,
1566
+ cfg=cfg,
1567
+ pred_frames_dir=pred_dir if cfg.infer_mode == "joint" else None,
1568
+ reverse_pred_frames_dir=reverse_pred_dir,
1569
+ )
1570
+ dump_result(result, args.output)
1571
+ logger.info(
1572
+ "frames=%s progress[0]=%.4f progress[-1]=%.4f windows=%s seconds=%.1f",
1573
+ result["num_frames"],
1574
+ result["progress"][0],
1575
+ result["progress"][-1],
1576
+ result["rollout"]["n_windows"],
1577
+ result["runtime_seconds"],
1578
+ )
1579
+
1580
+
1581
+ if __name__ == "__main__":
1582
+ main()
nimcritic_model.py ADDED
The diff for this file is too large to render. See raw diff
 
nimcritic_step_128000.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:2e677884dad0dd087c0f7238676f5989e28a127a4211950da8326fb90ee89020
3
+ size 12042556293
pyproject.toml ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Inference environment for this directory. Not a library.
2
+ # From this directory: uv sync && uv run python infer_nimcritic.py --help
3
+ [project]
4
+ name = "nimcritic-infer"
5
+ version = "0.1.0"
6
+ description = "Single-video inference for the NimCritic reward model"
7
+ readme = "README.md"
8
+ requires-python = ">=3.12"
9
+ dependencies = [
10
+ "einops",
11
+ "numpy",
12
+ "opencv-python-headless",
13
+ "Pillow",
14
+ "safetensors",
15
+ "torch",
16
+ "tqdm",
17
+ "transformers>=4.57,<4.58",
18
+ ]
19
+
20
+ [tool.uv]
21
+ package = false