Upload folder using huggingface_hub
Browse files- .gitattributes +1 -0
- README.md +24 -0
- added_tokens.json +107 -0
- chat_template.jinja +88 -0
- config.json +297 -0
- configuration_minicpmo.py +260 -0
- generation_config.json +12 -0
- model-00001-of-00002.safetensors +3 -0
- model-00002-of-00002.safetensors +3 -0
- model.safetensors.index.json +0 -0
- modeling_minicpmo.py +0 -0
- modeling_navit_siglip.py +981 -0
- preprocessor_config.json +35 -0
- processing_minicpmo.py +1665 -0
- processor_config.json +89 -0
- special_tokens_map.json +580 -0
- tokenization_minicpmo_fast.py +120 -0
- tokenizer.json +3 -0
- tokenizer_config.json +6989 -0
- utils.py +2417 -0
- vocab.json +0 -0
.gitattributes
CHANGED
|
@@ -33,3 +33,4 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
|
| 33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
|
|
|
|
|
| 33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
| 36 |
+
tokenizer.json filter=lfs diff=lfs merge=lfs -text
|
README.md
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
license: apache-2.0
|
| 3 |
+
pipeline_tag: any-to-any
|
| 4 |
+
library_name: transformers
|
| 5 |
+
tags:
|
| 6 |
+
- minicpm-o
|
| 7 |
+
- minicpm-v
|
| 8 |
+
- multimodal
|
| 9 |
+
- full-duplex
|
| 10 |
+
- mlx
|
| 11 |
+
---
|
| 12 |
+
|
| 13 |
+
# mlx-community/MiniCPM-o-4_5-4bit
|
| 14 |
+
This model was converted to MLX format from [`openbmb/MiniCPM-o-4_5`]() using mlx-vlm version **0.3.13**.
|
| 15 |
+
Refer to the [original model card](https://huggingface.co/openbmb/MiniCPM-o-4_5) for more details on the model.
|
| 16 |
+
## Use with mlx
|
| 17 |
+
|
| 18 |
+
```bash
|
| 19 |
+
pip install -U mlx-vlm
|
| 20 |
+
```
|
| 21 |
+
|
| 22 |
+
```bash
|
| 23 |
+
python -m mlx_vlm.generate --model mlx-community/MiniCPM-o-4_5-4bit --max-tokens 100 --temperature 0.0 --prompt "Describe this image." --image <path_to_image>
|
| 24 |
+
```
|
added_tokens.json
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"</answer>": 151686,
|
| 3 |
+
"</box>": 151674,
|
| 4 |
+
"</focus>": 151688,
|
| 5 |
+
"</image>": 151670,
|
| 6 |
+
"</image_id>": 151682,
|
| 7 |
+
"</image_save_to>": 151696,
|
| 8 |
+
"</line>": 151690,
|
| 9 |
+
"</perception>": 151692,
|
| 10 |
+
"</point>": 151678,
|
| 11 |
+
"</quad>": 151676,
|
| 12 |
+
"</ref>": 151672,
|
| 13 |
+
"</slice>": 151680,
|
| 14 |
+
"</source_image>": 151694,
|
| 15 |
+
"</think>": 151668,
|
| 16 |
+
"</tool_call>": 151658,
|
| 17 |
+
"</tool_response>": 151666,
|
| 18 |
+
"</unit>": 151684,
|
| 19 |
+
"<answer>": 151685,
|
| 20 |
+
"<box>": 151673,
|
| 21 |
+
"<focus>": 151687,
|
| 22 |
+
"<image>": 151669,
|
| 23 |
+
"<image_id>": 151681,
|
| 24 |
+
"<image_save_to>": 151695,
|
| 25 |
+
"<line>": 151689,
|
| 26 |
+
"<perception>": 151691,
|
| 27 |
+
"<point>": 151677,
|
| 28 |
+
"<quad>": 151675,
|
| 29 |
+
"<ref>": 151671,
|
| 30 |
+
"<slice>": 151679,
|
| 31 |
+
"<source_image>": 151693,
|
| 32 |
+
"<think>": 151667,
|
| 33 |
+
"<tool_call>": 151657,
|
| 34 |
+
"<tool_response>": 151665,
|
| 35 |
+
"<unit>": 151683,
|
| 36 |
+
"<|audio_end|>": 151699,
|
| 37 |
+
"<|audio_start|>": 151697,
|
| 38 |
+
"<|audio|>": 151698,
|
| 39 |
+
"<|box_end|>": 151649,
|
| 40 |
+
"<|box_start|>": 151648,
|
| 41 |
+
"<|emotion_end|>": 151711,
|
| 42 |
+
"<|emotion_start|>": 151710,
|
| 43 |
+
"<|endoftext|>": 151643,
|
| 44 |
+
"<|file_sep|>": 151664,
|
| 45 |
+
"<|fim_middle|>": 151660,
|
| 46 |
+
"<|fim_pad|>": 151662,
|
| 47 |
+
"<|fim_prefix|>": 151659,
|
| 48 |
+
"<|fim_suffix|>": 151661,
|
| 49 |
+
"<|im_end|>": 151645,
|
| 50 |
+
"<|im_start|>": 151644,
|
| 51 |
+
"<|image_pad|>": 151655,
|
| 52 |
+
"<|interrupt|>": 151707,
|
| 53 |
+
"<|listen|>": 151705,
|
| 54 |
+
"<|object_ref_end|>": 151647,
|
| 55 |
+
"<|object_ref_start|>": 151646,
|
| 56 |
+
"<|pitch_end|>": 151715,
|
| 57 |
+
"<|pitch_start|>": 151714,
|
| 58 |
+
"<|quad_end|>": 151651,
|
| 59 |
+
"<|quad_start|>": 151650,
|
| 60 |
+
"<|repo_name|>": 151663,
|
| 61 |
+
"<|speak|>": 151706,
|
| 62 |
+
"<|speed_end|>": 151713,
|
| 63 |
+
"<|speed_start|>": 151712,
|
| 64 |
+
"<|spk_bos|>": 151700,
|
| 65 |
+
"<|spk_eos|>": 151702,
|
| 66 |
+
"<|spk|>": 151701,
|
| 67 |
+
"<|turn_bos|>": 151716,
|
| 68 |
+
"<|timbre_10|>": 151726,
|
| 69 |
+
"<|timbre_11|>": 151727,
|
| 70 |
+
"<|timbre_12|>": 151728,
|
| 71 |
+
"<|timbre_13|>": 151729,
|
| 72 |
+
"<|timbre_14|>": 151730,
|
| 73 |
+
"<|timbre_15|>": 151731,
|
| 74 |
+
"<|timbre_16|>": 151732,
|
| 75 |
+
"<|timbre_17|>": 151733,
|
| 76 |
+
"<|timbre_18|>": 151734,
|
| 77 |
+
"<|timbre_19|>": 151735,
|
| 78 |
+
"<|turn_eos|>": 151717,
|
| 79 |
+
"<|timbre_20|>": 151736,
|
| 80 |
+
"<|timbre_21|>": 151737,
|
| 81 |
+
"<|timbre_22|>": 151738,
|
| 82 |
+
"<|timbre_23|>": 151739,
|
| 83 |
+
"<|timbre_24|>": 151740,
|
| 84 |
+
"<|timbre_25|>": 151741,
|
| 85 |
+
"<|timbre_26|>": 151742,
|
| 86 |
+
"<|timbre_27|>": 151743,
|
| 87 |
+
"<|timbre_28|>": 151744,
|
| 88 |
+
"<|timbre_29|>": 151745,
|
| 89 |
+
"<|chunk_eos|>": 151718,
|
| 90 |
+
"<|timbre_30|>": 151746,
|
| 91 |
+
"<|timbre_31|>": 151747,
|
| 92 |
+
"<|chunk_bos|>": 151719,
|
| 93 |
+
"<|chunk_tts_bos|>": 151720,
|
| 94 |
+
"<|chunk_tts_eos|>": 151721,
|
| 95 |
+
"<|tts_pad|>": 151722,
|
| 96 |
+
"<|timbre_7|>": 151723,
|
| 97 |
+
"<|timbre_8|>": 151724,
|
| 98 |
+
"<|timbre_9|>": 151725,
|
| 99 |
+
"<|tts_bos|>": 151703,
|
| 100 |
+
"<|tts_eos|>": 151704,
|
| 101 |
+
"<|vad_end|>": 151709,
|
| 102 |
+
"<|vad_start|>": 151708,
|
| 103 |
+
"<|video_pad|>": 151656,
|
| 104 |
+
"<|vision_end|>": 151653,
|
| 105 |
+
"<|vision_pad|>": 151654,
|
| 106 |
+
"<|vision_start|>": 151652
|
| 107 |
+
}
|
chat_template.jinja
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{%- if tools %}
|
| 2 |
+
{{- '<|im_start|>system\n' }}
|
| 3 |
+
{%- if messages[0].role == 'system' %}
|
| 4 |
+
{{- messages[0].content + '\n\n' }}
|
| 5 |
+
{%- endif %}
|
| 6 |
+
{{- "# Tools\n\nYou may call one or more functions to assist with the user query.\n\nYou are provided with function signatures within <tools></tools> XML tags:\n<tools>" }}
|
| 7 |
+
{%- for tool in tools %}
|
| 8 |
+
{{- "\n" }}
|
| 9 |
+
{{- tool | tojson }}
|
| 10 |
+
{%- endfor %}
|
| 11 |
+
{{- "\n</tools>\n\nFor each function call, return a json object with function name and arguments within <tool_call></tool_call> XML tags:\n<tool_call>\n{\"name\": <function-name>, \"arguments\": <args-json-object>}\n</tool_call><|im_end|>\n" }}
|
| 12 |
+
{%- else %}
|
| 13 |
+
{%- if messages[0].role == 'system' %}
|
| 14 |
+
{{- '<|im_start|>system\n' + messages[0].content + '<|im_end|>\n' }}
|
| 15 |
+
{%- endif %}
|
| 16 |
+
{%- endif %}
|
| 17 |
+
{%- set ns = namespace(multi_step_tool=true, last_query_index=messages|length - 1) %}
|
| 18 |
+
{%- for message in messages[::-1] %}
|
| 19 |
+
{%- set index = (messages|length - 1) - loop.index0 %}
|
| 20 |
+
{%- if ns.multi_step_tool and message.role == "user" and not(message.content.startswith('<tool_response>') and message.content.endswith('</tool_response>')) %}
|
| 21 |
+
{%- set ns.multi_step_tool = false %}
|
| 22 |
+
{%- set ns.last_query_index = index %}
|
| 23 |
+
{%- endif %}
|
| 24 |
+
{%- endfor %}
|
| 25 |
+
{%- for message in messages %}
|
| 26 |
+
{%- if (message.role == "user") or (message.role == "system" and not loop.first) %}
|
| 27 |
+
{{- '<|im_start|>' + message.role + '\n' + message.content + '<|im_end|>' + '\n' }}
|
| 28 |
+
{%- elif message.role == "assistant" %}
|
| 29 |
+
{%- set content = message.content %}
|
| 30 |
+
{%- set reasoning_content = '' %}
|
| 31 |
+
{%- if message.reasoning_content is defined and message.reasoning_content is not none %}
|
| 32 |
+
{%- set reasoning_content = message.reasoning_content %}
|
| 33 |
+
{%- else %}
|
| 34 |
+
{%- if '</think>' in message.content %}
|
| 35 |
+
{%- set content = message.content.split('</think>')[-1].lstrip('\n') %}
|
| 36 |
+
{%- set reasoning_content = message.content.split('</think>')[0].rstrip('\n').split('<think>')[-1].lstrip('\n') %}
|
| 37 |
+
{%- endif %}
|
| 38 |
+
{%- endif %}
|
| 39 |
+
{%- if loop.index0 > ns.last_query_index %}
|
| 40 |
+
{%- if loop.last or (not loop.last and reasoning_content) %}
|
| 41 |
+
{{- '<|im_start|>' + message.role + '\n<think>\n' + reasoning_content.strip('\n') + '\n</think>\n\n' + content.lstrip('\n') }}
|
| 42 |
+
{%- else %}
|
| 43 |
+
{{- '<|im_start|>' + message.role + '\n' + content }}
|
| 44 |
+
{%- endif %}
|
| 45 |
+
{%- else %}
|
| 46 |
+
{{- '<|im_start|>' + message.role + '\n' + content }}
|
| 47 |
+
{%- endif %}
|
| 48 |
+
{%- if message.tool_calls %}
|
| 49 |
+
{%- for tool_call in message.tool_calls %}
|
| 50 |
+
{%- if (loop.first and content) or (not loop.first) %}
|
| 51 |
+
{{- '\n' }}
|
| 52 |
+
{%- endif %}
|
| 53 |
+
{%- if tool_call.function %}
|
| 54 |
+
{%- set tool_call = tool_call.function %}
|
| 55 |
+
{%- endif %}
|
| 56 |
+
{{- '<tool_call>\n{"name": "' }}
|
| 57 |
+
{{- tool_call.name }}
|
| 58 |
+
{{- '", "arguments": ' }}
|
| 59 |
+
{%- if tool_call.arguments is string %}
|
| 60 |
+
{{- tool_call.arguments }}
|
| 61 |
+
{%- else %}
|
| 62 |
+
{{- tool_call.arguments | tojson }}
|
| 63 |
+
{%- endif %}
|
| 64 |
+
{{- '}\n</tool_call>' }}
|
| 65 |
+
{%- endfor %}
|
| 66 |
+
{%- endif %}
|
| 67 |
+
{{- '<|im_end|>\n' }}
|
| 68 |
+
{%- elif message.role == "tool" %}
|
| 69 |
+
{%- if loop.first or (messages[loop.index0 - 1].role != "tool") %}
|
| 70 |
+
{{- '<|im_start|>user' }}
|
| 71 |
+
{%- endif %}
|
| 72 |
+
{{- '\n<tool_response>\n' }}
|
| 73 |
+
{{- message.content }}
|
| 74 |
+
{{- '\n</tool_response>' }}
|
| 75 |
+
{%- if loop.last or (messages[loop.index0 + 1].role != "tool") %}
|
| 76 |
+
{{- '<|im_end|>\n' }}
|
| 77 |
+
{%- endif %}
|
| 78 |
+
{%- endif %}
|
| 79 |
+
{%- endfor %}
|
| 80 |
+
{%- if add_generation_prompt %}
|
| 81 |
+
{{- '<|im_start|>assistant\n' }}
|
| 82 |
+
{%- if enable_thinking is defined and enable_thinking is false %}
|
| 83 |
+
{{- '<think>\n\n</think>\n\n' }}
|
| 84 |
+
{%- endif %}
|
| 85 |
+
{%- if use_tts_template is defined and use_tts_template is true %}
|
| 86 |
+
{{- '<|tts_bos|>' }}
|
| 87 |
+
{%- endif %}
|
| 88 |
+
{%- endif %}
|
config.json
ADDED
|
@@ -0,0 +1,297 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"architectures": [
|
| 3 |
+
"MiniCPMO"
|
| 4 |
+
],
|
| 5 |
+
"attention_bias": false,
|
| 6 |
+
"attention_dropout": 0.0,
|
| 7 |
+
"audio_chunk_length": 1.0,
|
| 8 |
+
"audio_config": {
|
| 9 |
+
"_attn_implementation_autoset": true,
|
| 10 |
+
"_name_or_path": "openai/whisper-medium",
|
| 11 |
+
"activation_dropout": 0.0,
|
| 12 |
+
"activation_function": "gelu",
|
| 13 |
+
"apply_spec_augment": false,
|
| 14 |
+
"architectures": [
|
| 15 |
+
"MiniCPMWhisperEncoder"
|
| 16 |
+
],
|
| 17 |
+
"attention_dropout": 0.0,
|
| 18 |
+
"begin_suppress_tokens": [
|
| 19 |
+
220,
|
| 20 |
+
50257
|
| 21 |
+
],
|
| 22 |
+
"bos_token_id": 50257,
|
| 23 |
+
"classifier_proj_size": 256,
|
| 24 |
+
"d_model": 1024,
|
| 25 |
+
"decoder_attention_heads": 16,
|
| 26 |
+
"decoder_ffn_dim": 4096,
|
| 27 |
+
"decoder_layerdrop": 0.0,
|
| 28 |
+
"decoder_layers": 24,
|
| 29 |
+
"decoder_start_token_id": 50258,
|
| 30 |
+
"dropout": 0.0,
|
| 31 |
+
"encoder_attention_heads": 16,
|
| 32 |
+
"encoder_ffn_dim": 4096,
|
| 33 |
+
"encoder_layerdrop": 0.0,
|
| 34 |
+
"encoder_layers": 24,
|
| 35 |
+
"eos_token_id": 50257,
|
| 36 |
+
"forced_decoder_ids": [
|
| 37 |
+
[
|
| 38 |
+
1,
|
| 39 |
+
50259
|
| 40 |
+
],
|
| 41 |
+
[
|
| 42 |
+
2,
|
| 43 |
+
50359
|
| 44 |
+
],
|
| 45 |
+
[
|
| 46 |
+
3,
|
| 47 |
+
50363
|
| 48 |
+
]
|
| 49 |
+
],
|
| 50 |
+
"init_std": 0.02,
|
| 51 |
+
"mask_feature_length": 10,
|
| 52 |
+
"mask_feature_min_masks": 0,
|
| 53 |
+
"mask_feature_prob": 0.0,
|
| 54 |
+
"mask_time_length": 10,
|
| 55 |
+
"mask_time_min_masks": 2,
|
| 56 |
+
"mask_time_prob": 0.05,
|
| 57 |
+
"max_length": 448,
|
| 58 |
+
"max_source_positions": 1500,
|
| 59 |
+
"max_target_positions": 448,
|
| 60 |
+
"median_filter_width": 7,
|
| 61 |
+
"model_type": "whisper",
|
| 62 |
+
"num_hidden_layers": 24,
|
| 63 |
+
"num_mel_bins": 80,
|
| 64 |
+
"pad_token_id": 50257,
|
| 65 |
+
"scale_embedding": false,
|
| 66 |
+
"suppress_tokens": [
|
| 67 |
+
1,
|
| 68 |
+
2,
|
| 69 |
+
7,
|
| 70 |
+
8,
|
| 71 |
+
9,
|
| 72 |
+
10,
|
| 73 |
+
14,
|
| 74 |
+
25,
|
| 75 |
+
26,
|
| 76 |
+
27,
|
| 77 |
+
28,
|
| 78 |
+
29,
|
| 79 |
+
31,
|
| 80 |
+
58,
|
| 81 |
+
59,
|
| 82 |
+
60,
|
| 83 |
+
61,
|
| 84 |
+
62,
|
| 85 |
+
63,
|
| 86 |
+
90,
|
| 87 |
+
91,
|
| 88 |
+
92,
|
| 89 |
+
93,
|
| 90 |
+
359,
|
| 91 |
+
503,
|
| 92 |
+
522,
|
| 93 |
+
542,
|
| 94 |
+
873,
|
| 95 |
+
893,
|
| 96 |
+
902,
|
| 97 |
+
918,
|
| 98 |
+
922,
|
| 99 |
+
931,
|
| 100 |
+
1350,
|
| 101 |
+
1853,
|
| 102 |
+
1982,
|
| 103 |
+
2460,
|
| 104 |
+
2627,
|
| 105 |
+
3246,
|
| 106 |
+
3253,
|
| 107 |
+
3268,
|
| 108 |
+
3536,
|
| 109 |
+
3846,
|
| 110 |
+
3961,
|
| 111 |
+
4183,
|
| 112 |
+
4667,
|
| 113 |
+
6585,
|
| 114 |
+
6647,
|
| 115 |
+
7273,
|
| 116 |
+
9061,
|
| 117 |
+
9383,
|
| 118 |
+
10428,
|
| 119 |
+
10929,
|
| 120 |
+
11938,
|
| 121 |
+
12033,
|
| 122 |
+
12331,
|
| 123 |
+
12562,
|
| 124 |
+
13793,
|
| 125 |
+
14157,
|
| 126 |
+
14635,
|
| 127 |
+
15265,
|
| 128 |
+
15618,
|
| 129 |
+
16553,
|
| 130 |
+
16604,
|
| 131 |
+
18362,
|
| 132 |
+
18956,
|
| 133 |
+
20075,
|
| 134 |
+
21675,
|
| 135 |
+
22520,
|
| 136 |
+
26130,
|
| 137 |
+
26161,
|
| 138 |
+
26435,
|
| 139 |
+
28279,
|
| 140 |
+
29464,
|
| 141 |
+
31650,
|
| 142 |
+
32302,
|
| 143 |
+
32470,
|
| 144 |
+
36865,
|
| 145 |
+
42863,
|
| 146 |
+
47425,
|
| 147 |
+
49870,
|
| 148 |
+
50254,
|
| 149 |
+
50258,
|
| 150 |
+
50358,
|
| 151 |
+
50359,
|
| 152 |
+
50360,
|
| 153 |
+
50361,
|
| 154 |
+
50362
|
| 155 |
+
],
|
| 156 |
+
"torch_dtype": "float32",
|
| 157 |
+
"use_cache": true,
|
| 158 |
+
"use_weighted_layer_sum": false,
|
| 159 |
+
"vocab_size": 51865
|
| 160 |
+
},
|
| 161 |
+
"audio_pool_step": 5,
|
| 162 |
+
"auto_map": {
|
| 163 |
+
"AutoConfig": "configuration_minicpmo.MiniCPMOConfig",
|
| 164 |
+
"AutoModel": "modeling_minicpmo.MiniCPMO",
|
| 165 |
+
"AutoModelForCausalLM": "modeling_minicpmo.MiniCPMO"
|
| 166 |
+
},
|
| 167 |
+
"batch_vision_input": true,
|
| 168 |
+
"bos_token_id": 151643,
|
| 169 |
+
"drop_vision_last_layer": false,
|
| 170 |
+
"eos_token_id": [
|
| 171 |
+
151645,
|
| 172 |
+
151643
|
| 173 |
+
],
|
| 174 |
+
"head_dim": 128,
|
| 175 |
+
"hidden_act": "silu",
|
| 176 |
+
"hidden_size": 4096,
|
| 177 |
+
"image_size": 448,
|
| 178 |
+
"init_audio": true,
|
| 179 |
+
"init_tts": true,
|
| 180 |
+
"init_vision": true,
|
| 181 |
+
"initializer_range": 0.02,
|
| 182 |
+
"intermediate_size": 12288,
|
| 183 |
+
"listen_speak_type": "asr",
|
| 184 |
+
"max_position_embeddings": 40960,
|
| 185 |
+
"max_window_layers": 36,
|
| 186 |
+
"model_type": "minicpmo",
|
| 187 |
+
"num_attention_heads": 32,
|
| 188 |
+
"num_hidden_layers": 36,
|
| 189 |
+
"num_key_value_heads": 8,
|
| 190 |
+
"patch_size": 14,
|
| 191 |
+
"quantization": {
|
| 192 |
+
"group_size": 64,
|
| 193 |
+
"bits": 4,
|
| 194 |
+
"mode": "affine"
|
| 195 |
+
},
|
| 196 |
+
"quantization_config": {
|
| 197 |
+
"group_size": 64,
|
| 198 |
+
"bits": 4,
|
| 199 |
+
"mode": "affine"
|
| 200 |
+
},
|
| 201 |
+
"query_num": 64,
|
| 202 |
+
"rms_norm_eps": 1e-06,
|
| 203 |
+
"rope_scaling": null,
|
| 204 |
+
"rope_theta": 1000000,
|
| 205 |
+
"slice_config": {
|
| 206 |
+
"max_slice_nums": 1,
|
| 207 |
+
"model_type": "minicpmv",
|
| 208 |
+
"patch_size": 14,
|
| 209 |
+
"scale_resolution": 448
|
| 210 |
+
},
|
| 211 |
+
"slice_mode": true,
|
| 212 |
+
"sliding_window": null,
|
| 213 |
+
"stream_input": true,
|
| 214 |
+
"tie_word_embeddings": false,
|
| 215 |
+
"transformers_version": "4.51.0",
|
| 216 |
+
"tts_config": {
|
| 217 |
+
"_attn_implementation_autoset": true,
|
| 218 |
+
"attention_type": "full_attention",
|
| 219 |
+
"attn_implementation": "sdpa",
|
| 220 |
+
"audio_bos_token_id": 151687,
|
| 221 |
+
"audio_tokenizer_sample_rate": 16000,
|
| 222 |
+
"audio_tokenizer_type": "s3tokenizer",
|
| 223 |
+
"aug_layer_loss_weight": false,
|
| 224 |
+
"aug_loss_weight": false,
|
| 225 |
+
"backbone_model": "llama",
|
| 226 |
+
"condition_type": "hidden_text_merge",
|
| 227 |
+
"cosyvoice_config_path": null,
|
| 228 |
+
"cosyvoice_model_dir": null,
|
| 229 |
+
"filter_tts_loss": false,
|
| 230 |
+
"hidden_act": "silu",
|
| 231 |
+
"hidden_size": 768,
|
| 232 |
+
"interleaved": false,
|
| 233 |
+
"intermediate_size": 3072,
|
| 234 |
+
"llm_dim": 4096,
|
| 235 |
+
"llm_dim_model_base": 256,
|
| 236 |
+
"llm_down_scale": false,
|
| 237 |
+
"llm_hidden_size": 4096,
|
| 238 |
+
"llm_intermediate_size": 768,
|
| 239 |
+
"long_weight": 0.1,
|
| 240 |
+
"max_position_embeddings": 4096,
|
| 241 |
+
"model_type": "minicpmtts",
|
| 242 |
+
"normalize_projected_hidden": true,
|
| 243 |
+
"num_attention_heads": 12,
|
| 244 |
+
"num_audio_tokens": 6562,
|
| 245 |
+
"num_hidden_layers": 20,
|
| 246 |
+
"num_key_value_heads": 12,
|
| 247 |
+
"num_mel_bins": 100,
|
| 248 |
+
"num_text_tokens": 152064,
|
| 249 |
+
"num_vq": 1,
|
| 250 |
+
"projector_type": "mlp",
|
| 251 |
+
"recomputed_chunks": 1,
|
| 252 |
+
"s3_stream_chunk_size": 25,
|
| 253 |
+
"s3_stream_generate": false,
|
| 254 |
+
"s3_stream_n_timesteps": 10,
|
| 255 |
+
"s3_stream_prelook_size": 3,
|
| 256 |
+
"short_weight": 0.1,
|
| 257 |
+
"streaming": false,
|
| 258 |
+
"streaming_audio_chunk_size": 50,
|
| 259 |
+
"streaming_sliding_window": false,
|
| 260 |
+
"streaming_sliding_window_audio_frame_rate": 50,
|
| 261 |
+
"streaming_sliding_window_audio_init_text_length": 10,
|
| 262 |
+
"streaming_sliding_window_audio_window_size": 300,
|
| 263 |
+
"streaming_sliding_window_average_speed": 5,
|
| 264 |
+
"streaming_sliding_window_fast_speed": 7,
|
| 265 |
+
"streaming_sliding_window_max_text_len": 500,
|
| 266 |
+
"streaming_sliding_window_slow_speed": 3,
|
| 267 |
+
"streaming_sliding_window_text_window_size": 50,
|
| 268 |
+
"streaming_text_chunk_max": 7,
|
| 269 |
+
"streaming_text_chunk_min": 3,
|
| 270 |
+
"streaming_text_reserved_len": 300,
|
| 271 |
+
"text_eos_token_id": 151692,
|
| 272 |
+
"tts_filter_loss_fix": false,
|
| 273 |
+
"use_llm_hidden_state": false,
|
| 274 |
+
"use_text": true,
|
| 275 |
+
"window_size": 2
|
| 276 |
+
},
|
| 277 |
+
"use_cache": true,
|
| 278 |
+
"use_image_id": true,
|
| 279 |
+
"use_sliding_window": false,
|
| 280 |
+
"version": "4.5",
|
| 281 |
+
"vision_batch_size": 16,
|
| 282 |
+
"vision_config": {
|
| 283 |
+
"_attn_implementation_autoset": true,
|
| 284 |
+
"attention_dropout": 0.0,
|
| 285 |
+
"hidden_act": "gelu_pytorch_tanh",
|
| 286 |
+
"hidden_size": 1152,
|
| 287 |
+
"image_size": 980,
|
| 288 |
+
"intermediate_size": 4304,
|
| 289 |
+
"layer_norm_eps": 1e-06,
|
| 290 |
+
"model_type": "siglip_vision_model",
|
| 291 |
+
"num_attention_heads": 16,
|
| 292 |
+
"num_channels": 3,
|
| 293 |
+
"num_hidden_layers": 27,
|
| 294 |
+
"patch_size": 14
|
| 295 |
+
},
|
| 296 |
+
"vocab_size": 151748
|
| 297 |
+
}
|
configuration_minicpmo.py
ADDED
|
@@ -0,0 +1,260 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python
|
| 2 |
+
# -*- coding: utf-8 -*-
|
| 3 |
+
# Copyright 2026 The OpenBMB Team. All rights reserved.
|
| 4 |
+
#
|
| 5 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 6 |
+
# you may not use this file except in compliance with the License.
|
| 7 |
+
# You may obtain a copy of the License at
|
| 8 |
+
#
|
| 9 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 10 |
+
#
|
| 11 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 12 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 13 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 14 |
+
# See the License for the specific language governing permissions and
|
| 15 |
+
# limitations under the License.
|
| 16 |
+
|
| 17 |
+
import os
|
| 18 |
+
from typing import Union
|
| 19 |
+
|
| 20 |
+
from transformers import PretrainedConfig
|
| 21 |
+
from transformers import Qwen3Config
|
| 22 |
+
from transformers import WhisperConfig
|
| 23 |
+
from transformers.utils import logging
|
| 24 |
+
|
| 25 |
+
from .modeling_navit_siglip import SiglipVisionConfig
|
| 26 |
+
|
| 27 |
+
logger = logging.get_logger(__name__)
|
| 28 |
+
|
| 29 |
+
|
| 30 |
+
class MiniCPMVSliceConfig(PretrainedConfig):
|
| 31 |
+
model_type = "minicpmv"
|
| 32 |
+
|
| 33 |
+
def __init__(
|
| 34 |
+
self,
|
| 35 |
+
patch_size=14,
|
| 36 |
+
max_slice_nums=9,
|
| 37 |
+
scale_resolution=448,
|
| 38 |
+
**kwargs,
|
| 39 |
+
):
|
| 40 |
+
super().__init__(**kwargs)
|
| 41 |
+
self.patch_size = patch_size
|
| 42 |
+
self.max_slice_nums = max_slice_nums
|
| 43 |
+
self.scale_resolution = scale_resolution
|
| 44 |
+
|
| 45 |
+
@classmethod
|
| 46 |
+
def from_pretrained(cls, pretrained_model_name_or_path: Union[str, os.PathLike], **kwargs) -> "PretrainedConfig":
|
| 47 |
+
cls._set_token_in_kwargs(kwargs)
|
| 48 |
+
|
| 49 |
+
config_dict, kwargs = cls.get_config_dict(pretrained_model_name_or_path, **kwargs)
|
| 50 |
+
|
| 51 |
+
if config_dict.get("model_type") == "minicpmv":
|
| 52 |
+
config_dict = config_dict["slice_config"]
|
| 53 |
+
|
| 54 |
+
if "model_type" in config_dict and hasattr(cls, "model_type") and config_dict["model_type"] != cls.model_type:
|
| 55 |
+
logger.warning(
|
| 56 |
+
f"You are using a model of type {config_dict['model_type']} to instantiate a model of type "
|
| 57 |
+
f"{cls.model_type}. This is not supported for all configurations of models and can yield errors."
|
| 58 |
+
)
|
| 59 |
+
|
| 60 |
+
return cls.from_dict(config_dict, **kwargs)
|
| 61 |
+
|
| 62 |
+
|
| 63 |
+
class MiniCPMTTSConfig(PretrainedConfig):
|
| 64 |
+
model_type = "minicpmtts"
|
| 65 |
+
|
| 66 |
+
def __init__(
|
| 67 |
+
self,
|
| 68 |
+
llm_dim: int = 2560,
|
| 69 |
+
llm_intermediate_size: int = 768,
|
| 70 |
+
llm_down_scale: bool = False,
|
| 71 |
+
llm_dim_model_base: int = 256,
|
| 72 |
+
projector_type: str = "mlp",
|
| 73 |
+
hidden_act: str = "silu",
|
| 74 |
+
aug_loss_weight: bool = False,
|
| 75 |
+
aug_layer_loss_weight: bool = False,
|
| 76 |
+
filter_tts_loss: bool = False,
|
| 77 |
+
tts_filter_loss_fix: bool = False,
|
| 78 |
+
long_weight: float = 0.1,
|
| 79 |
+
short_weight: float = 0.1,
|
| 80 |
+
hidden_size: int = 768,
|
| 81 |
+
intermediate_size: int = 3072,
|
| 82 |
+
num_attention_heads: int = 12,
|
| 83 |
+
num_hidden_layers: int = 20,
|
| 84 |
+
num_key_value_heads: int = 12,
|
| 85 |
+
max_position_embeddings: int = 4096,
|
| 86 |
+
num_audio_tokens: int = 4097,
|
| 87 |
+
num_text_tokens: int = 21178,
|
| 88 |
+
num_mel_bins: int = 100,
|
| 89 |
+
num_vq: int = 1,
|
| 90 |
+
use_llm_hidden_state: bool = False,
|
| 91 |
+
audio_bos_token_id: int = 21132,
|
| 92 |
+
text_eos_token_id: int = 21133,
|
| 93 |
+
use_text: bool = True,
|
| 94 |
+
streaming: bool = False,
|
| 95 |
+
streaming_text_chunk_min: int = 3,
|
| 96 |
+
streaming_text_chunk_max: int = 7,
|
| 97 |
+
streaming_text_reserved_len: int = 300,
|
| 98 |
+
streaming_audio_chunk_size: int = 50,
|
| 99 |
+
attn_implementation: str = "sdpa",
|
| 100 |
+
condition_type: str = "llm_hidden",
|
| 101 |
+
backbone_model: str = "llama",
|
| 102 |
+
audio_tokenizer_type: str = "wavtokenizer",
|
| 103 |
+
audio_tokenizer_sample_rate: int = 24000,
|
| 104 |
+
streaming_sliding_window: bool = False,
|
| 105 |
+
streaming_sliding_window_max_text_len: int = 500,
|
| 106 |
+
streaming_sliding_window_average_speed: int = 5,
|
| 107 |
+
streaming_sliding_window_fast_speed: int = 7,
|
| 108 |
+
streaming_sliding_window_slow_speed: int = 3,
|
| 109 |
+
streaming_sliding_window_audio_frame_rate: int = 50,
|
| 110 |
+
streaming_sliding_window_audio_init_text_length: int = 10,
|
| 111 |
+
streaming_sliding_window_audio_window_size: int = 300,
|
| 112 |
+
normalize_projected_hidden: bool = False,
|
| 113 |
+
interleaved: bool = False,
|
| 114 |
+
attention_type: str = "sliding_recompute",
|
| 115 |
+
recomputed_chunks: int = 1,
|
| 116 |
+
window_size: int = 2,
|
| 117 |
+
**kwargs,
|
| 118 |
+
):
|
| 119 |
+
super().__init__(**kwargs)
|
| 120 |
+
|
| 121 |
+
self.llm_dim = llm_dim
|
| 122 |
+
self.llm_hidden_size = llm_dim
|
| 123 |
+
self.llm_intermediate_size = llm_intermediate_size
|
| 124 |
+
self.llm_down_scale = llm_down_scale
|
| 125 |
+
self.llm_dim_model_base = llm_dim_model_base
|
| 126 |
+
self.projector_type = projector_type
|
| 127 |
+
self.aug_loss_weight = aug_loss_weight
|
| 128 |
+
self.aug_layer_loss_weight = aug_layer_loss_weight
|
| 129 |
+
self.tts_filter_loss_fix = tts_filter_loss_fix
|
| 130 |
+
self.filter_tts_loss = filter_tts_loss
|
| 131 |
+
self.long_weight = long_weight
|
| 132 |
+
self.short_weight = short_weight
|
| 133 |
+
self.hidden_act = hidden_act
|
| 134 |
+
|
| 135 |
+
self.hidden_size = hidden_size
|
| 136 |
+
self.intermediate_size = intermediate_size
|
| 137 |
+
self.num_attention_heads = num_attention_heads
|
| 138 |
+
self.num_hidden_layers = num_hidden_layers
|
| 139 |
+
self.num_key_value_heads = num_key_value_heads
|
| 140 |
+
self.max_position_embeddings = max_position_embeddings
|
| 141 |
+
self.num_audio_tokens = num_audio_tokens
|
| 142 |
+
self.num_text_tokens = num_text_tokens
|
| 143 |
+
self.num_mel_bins = num_mel_bins
|
| 144 |
+
self.num_vq = num_vq
|
| 145 |
+
self.use_llm_hidden_state = use_llm_hidden_state
|
| 146 |
+
self.audio_bos_token_id = audio_bos_token_id
|
| 147 |
+
self.text_eos_token_id = text_eos_token_id
|
| 148 |
+
self.use_text = use_text
|
| 149 |
+
self.streaming = streaming
|
| 150 |
+
self.streaming_text_chunk_min = streaming_text_chunk_min
|
| 151 |
+
self.streaming_text_chunk_max = streaming_text_chunk_max
|
| 152 |
+
self.streaming_text_reserved_len = streaming_text_reserved_len
|
| 153 |
+
self.streaming_audio_chunk_size = streaming_audio_chunk_size
|
| 154 |
+
self.attn_implementation = attn_implementation
|
| 155 |
+
self.condition_type = condition_type
|
| 156 |
+
self.backbone_model = backbone_model
|
| 157 |
+
self.audio_tokenizer_type = audio_tokenizer_type
|
| 158 |
+
self.audio_tokenizer_sample_rate = audio_tokenizer_sample_rate
|
| 159 |
+
|
| 160 |
+
self.streaming_sliding_window = streaming_sliding_window
|
| 161 |
+
self.streaming_sliding_window_max_text_len = streaming_sliding_window_max_text_len
|
| 162 |
+
self.streaming_sliding_window_average_speed = streaming_sliding_window_average_speed
|
| 163 |
+
self.streaming_sliding_window_fast_speed = streaming_sliding_window_fast_speed
|
| 164 |
+
self.streaming_sliding_window_slow_speed = streaming_sliding_window_slow_speed
|
| 165 |
+
self.streaming_sliding_window_audio_frame_rate = streaming_sliding_window_audio_frame_rate
|
| 166 |
+
self.streaming_sliding_window_audio_init_text_length = streaming_sliding_window_audio_init_text_length
|
| 167 |
+
self.streaming_sliding_window_audio_window_size = streaming_sliding_window_audio_window_size
|
| 168 |
+
|
| 169 |
+
self.normalize_projected_hidden = normalize_projected_hidden
|
| 170 |
+
|
| 171 |
+
self.interleaved = interleaved
|
| 172 |
+
self.attention_type = attention_type
|
| 173 |
+
self.recomputed_chunks = recomputed_chunks
|
| 174 |
+
self.window_size = window_size
|
| 175 |
+
|
| 176 |
+
|
| 177 |
+
class MiniCPMOConfig(Qwen3Config):
|
| 178 |
+
model_type = "minicpmo"
|
| 179 |
+
keys_to_ignore_at_inference = ["past_key_values"]
|
| 180 |
+
|
| 181 |
+
default_vision_config = {
|
| 182 |
+
"hidden_size": 1152,
|
| 183 |
+
"image_size": 980,
|
| 184 |
+
"intermediate_size": 4304,
|
| 185 |
+
"model_type": "siglip",
|
| 186 |
+
"num_attention_heads": 16,
|
| 187 |
+
"num_hidden_layers": 27,
|
| 188 |
+
"patch_size": 14,
|
| 189 |
+
}
|
| 190 |
+
|
| 191 |
+
def __init__(
|
| 192 |
+
self,
|
| 193 |
+
use_cache=True,
|
| 194 |
+
query_num=64,
|
| 195 |
+
image_size=448,
|
| 196 |
+
drop_vision_last_layer=True,
|
| 197 |
+
batch_vision_input=True,
|
| 198 |
+
slice_config=None,
|
| 199 |
+
vision_config=None,
|
| 200 |
+
audio_config=None,
|
| 201 |
+
tts_config=None,
|
| 202 |
+
use_image_id=True,
|
| 203 |
+
vision_batch_size=16,
|
| 204 |
+
audio_pool_step=5,
|
| 205 |
+
audio_chunk_length=1.0,
|
| 206 |
+
stream_input=False,
|
| 207 |
+
listen_speak_type="asr",
|
| 208 |
+
init_vision=True,
|
| 209 |
+
init_audio=True,
|
| 210 |
+
init_tts=True,
|
| 211 |
+
**kwargs,
|
| 212 |
+
):
|
| 213 |
+
self.use_cache = use_cache
|
| 214 |
+
self.query_num = query_num
|
| 215 |
+
self.image_size = image_size
|
| 216 |
+
self.drop_vision_last_layer = drop_vision_last_layer
|
| 217 |
+
self.batch_vision_input = batch_vision_input
|
| 218 |
+
self.use_image_id = use_image_id
|
| 219 |
+
self.vision_batch_size = vision_batch_size
|
| 220 |
+
self.audio_pool_step = audio_pool_step
|
| 221 |
+
self.audio_chunk_length = audio_chunk_length
|
| 222 |
+
self.stream_input = stream_input
|
| 223 |
+
self.listen_speak_type = listen_speak_type
|
| 224 |
+
|
| 225 |
+
self.init_vision = init_vision
|
| 226 |
+
self.init_audio = init_audio
|
| 227 |
+
self.init_tts = init_tts
|
| 228 |
+
|
| 229 |
+
if slice_config is None:
|
| 230 |
+
self.slice_config = MiniCPMVSliceConfig(max_slice_nums=1)
|
| 231 |
+
else:
|
| 232 |
+
self.slice_config = MiniCPMVSliceConfig(**slice_config)
|
| 233 |
+
self.slice_mode = True
|
| 234 |
+
|
| 235 |
+
# same as HuggingFaceM4/siglip-so400m-14-980-flash-attn2-navit add tgt_sizes
|
| 236 |
+
if vision_config is None:
|
| 237 |
+
self.vision_config = SiglipVisionConfig(**self.default_vision_config)
|
| 238 |
+
logger.info("vision_config is None, using default vision config")
|
| 239 |
+
elif isinstance(vision_config, dict):
|
| 240 |
+
self.vision_config = SiglipVisionConfig(**vision_config)
|
| 241 |
+
elif isinstance(vision_config, SiglipVisionConfig):
|
| 242 |
+
self.vision_config = vision_config
|
| 243 |
+
|
| 244 |
+
if audio_config is None:
|
| 245 |
+
self.audio_config = WhisperConfig()
|
| 246 |
+
elif isinstance(audio_config, dict):
|
| 247 |
+
self.audio_config = WhisperConfig(**audio_config)
|
| 248 |
+
elif isinstance(audio_config, WhisperConfig):
|
| 249 |
+
self.audio_config = audio_config
|
| 250 |
+
|
| 251 |
+
if tts_config is None:
|
| 252 |
+
self.tts_config = MiniCPMTTSConfig()
|
| 253 |
+
elif isinstance(tts_config, dict):
|
| 254 |
+
self.tts_config = MiniCPMTTSConfig(**tts_config)
|
| 255 |
+
elif isinstance(tts_config, MiniCPMTTSConfig):
|
| 256 |
+
self.tts_config = tts_config
|
| 257 |
+
|
| 258 |
+
self.patch_size = self.vision_config.patch_size
|
| 259 |
+
|
| 260 |
+
super().__init__(**kwargs)
|
generation_config.json
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"bos_token_id": 151643,
|
| 3 |
+
"do_sample": true,
|
| 4 |
+
"eos_token_id": [
|
| 5 |
+
151645,
|
| 6 |
+
151643
|
| 7 |
+
],
|
| 8 |
+
"pad_token_id": 151643,
|
| 9 |
+
"temperature": 0.6,
|
| 10 |
+
"top_k": 20,
|
| 11 |
+
"top_p": 0.95
|
| 12 |
+
}
|
model-00001-of-00002.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:f90098983cc0aa9ebbe229df10c3de352f33a07ef57c321e76437bab5fa5a2c7
|
| 3 |
+
size 5361810143
|
model-00002-of-00002.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:94eec5685bbbdd2611070d789aa5e5beba9a8fcbd9ba6849762160a9813a0a1d
|
| 3 |
+
size 781665788
|
model.safetensors.index.json
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
modeling_minicpmo.py
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
modeling_navit_siglip.py
ADDED
|
@@ -0,0 +1,981 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# coding=utf-8
|
| 2 |
+
# Copyright 2024 Google AI and The HuggingFace Team. All rights reserved.
|
| 3 |
+
#
|
| 4 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 5 |
+
# you may not use this file except in compliance with the License.
|
| 6 |
+
# You may obtain a copy of the License at
|
| 7 |
+
#
|
| 8 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 9 |
+
#
|
| 10 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 11 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 12 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 13 |
+
# See the License for the specific language governing permissions and
|
| 14 |
+
# limitations under the License.
|
| 15 |
+
"""PyTorch Siglip model."""
|
| 16 |
+
# Copied from HuggingFaceM4/siglip-so400m-14-980-flash-attn2-navit and add tgt_sizes
|
| 17 |
+
|
| 18 |
+
|
| 19 |
+
import math
|
| 20 |
+
import os
|
| 21 |
+
import warnings
|
| 22 |
+
from dataclasses import dataclass
|
| 23 |
+
from typing import Optional
|
| 24 |
+
from typing import Tuple
|
| 25 |
+
from typing import Union
|
| 26 |
+
|
| 27 |
+
import numpy as np
|
| 28 |
+
import torch
|
| 29 |
+
import torch.nn.functional as F
|
| 30 |
+
import torch.utils.checkpoint
|
| 31 |
+
from torch import nn
|
| 32 |
+
from torch.nn.init import _calculate_fan_in_and_fan_out
|
| 33 |
+
from transformers.activations import ACT2FN
|
| 34 |
+
from transformers.configuration_utils import PretrainedConfig
|
| 35 |
+
from transformers.modeling_attn_mask_utils import _prepare_4d_attention_mask
|
| 36 |
+
from transformers.modeling_outputs import BaseModelOutput
|
| 37 |
+
from transformers.modeling_outputs import BaseModelOutputWithPooling
|
| 38 |
+
from transformers.modeling_utils import PreTrainedModel
|
| 39 |
+
from transformers.utils import add_start_docstrings
|
| 40 |
+
from transformers.utils import add_start_docstrings_to_model_forward
|
| 41 |
+
from transformers.utils import is_flash_attn_2_available
|
| 42 |
+
from transformers.utils import logging
|
| 43 |
+
from transformers.utils import ModelOutput
|
| 44 |
+
from transformers.utils import replace_return_docstrings
|
| 45 |
+
|
| 46 |
+
logger = logging.get_logger(__name__)
|
| 47 |
+
|
| 48 |
+
|
| 49 |
+
class SiglipVisionConfig(PretrainedConfig):
|
| 50 |
+
r"""
|
| 51 |
+
This is the configuration class to store the configuration of a [`SiglipVisionModel`]. It is used to instantiate a
|
| 52 |
+
Siglip vision encoder according to the specified arguments, defining the model architecture. Instantiating a
|
| 53 |
+
configuration with the defaults will yield a similar configuration to that of the vision encoder of the Siglip
|
| 54 |
+
[google/siglip-base-patch16-224](https://huggingface.co/google/siglip-base-patch16-224) architecture.
|
| 55 |
+
Configuration objects inherit from [`PretrainedConfig`] and can be used to control the model outputs. Read the
|
| 56 |
+
documentation from [`PretrainedConfig`] for more information.
|
| 57 |
+
Args:
|
| 58 |
+
hidden_size (`int`, *optional*, defaults to 768):
|
| 59 |
+
Dimensionality of the encoder layers and the pooler layer.
|
| 60 |
+
intermediate_size (`int`, *optional*, defaults to 3072):
|
| 61 |
+
Dimensionality of the "intermediate" (i.e., feed-forward) layer in the Transformer encoder.
|
| 62 |
+
num_hidden_layers (`int`, *optional*, defaults to 12):
|
| 63 |
+
Number of hidden layers in the Transformer encoder.
|
| 64 |
+
num_attention_heads (`int`, *optional*, defaults to 12):
|
| 65 |
+
Number of attention heads for each attention layer in the Transformer encoder.
|
| 66 |
+
num_channels (`int`, *optional*, defaults to 3):
|
| 67 |
+
Number of channels in the input images.
|
| 68 |
+
image_size (`int`, *optional*, defaults to 224):
|
| 69 |
+
The size (resolution) of each image.
|
| 70 |
+
patch_size (`int`, *optional*, defaults to 16):
|
| 71 |
+
The size (resolution) of each patch.
|
| 72 |
+
hidden_act (`str` or `function`, *optional*, defaults to `"gelu_pytorch_tanh"`):
|
| 73 |
+
The non-linear activation function (function or string) in the encoder and pooler. If string, `"gelu"`,
|
| 74 |
+
`"relu"`, `"selu"` and `"gelu_new"` ``"quick_gelu"` are supported.
|
| 75 |
+
layer_norm_eps (`float`, *optional*, defaults to 1e-06):
|
| 76 |
+
The epsilon used by the layer normalization layers.
|
| 77 |
+
attention_dropout (`float`, *optional*, defaults to 0.0):
|
| 78 |
+
The dropout ratio for the attention probabilities.
|
| 79 |
+
Example:
|
| 80 |
+
```python
|
| 81 |
+
>>> from transformers import SiglipVisionConfig, SiglipVisionModel
|
| 82 |
+
>>> # Initializing a SiglipVisionConfig with google/siglip-base-patch16-224 style configuration
|
| 83 |
+
>>> configuration = SiglipVisionConfig()
|
| 84 |
+
>>> # Initializing a SiglipVisionModel (with random weights) from the google/siglip-base-patch16-224 style configuration
|
| 85 |
+
>>> model = SiglipVisionModel(configuration)
|
| 86 |
+
>>> # Accessing the model configuration
|
| 87 |
+
>>> configuration = model.config
|
| 88 |
+
```"""
|
| 89 |
+
|
| 90 |
+
model_type = "siglip_vision_model"
|
| 91 |
+
|
| 92 |
+
def __init__(
|
| 93 |
+
self,
|
| 94 |
+
hidden_size=768,
|
| 95 |
+
intermediate_size=3072,
|
| 96 |
+
num_hidden_layers=12,
|
| 97 |
+
num_attention_heads=12,
|
| 98 |
+
num_channels=3,
|
| 99 |
+
image_size=224,
|
| 100 |
+
patch_size=16,
|
| 101 |
+
hidden_act="gelu_pytorch_tanh",
|
| 102 |
+
layer_norm_eps=1e-6,
|
| 103 |
+
attention_dropout=0.0,
|
| 104 |
+
**kwargs,
|
| 105 |
+
):
|
| 106 |
+
super().__init__(**kwargs)
|
| 107 |
+
|
| 108 |
+
self.hidden_size = hidden_size
|
| 109 |
+
self.intermediate_size = intermediate_size
|
| 110 |
+
self.num_hidden_layers = num_hidden_layers
|
| 111 |
+
self.num_attention_heads = num_attention_heads
|
| 112 |
+
self.num_channels = num_channels
|
| 113 |
+
self.patch_size = patch_size
|
| 114 |
+
self.image_size = image_size
|
| 115 |
+
self.attention_dropout = attention_dropout
|
| 116 |
+
self.layer_norm_eps = layer_norm_eps
|
| 117 |
+
self.hidden_act = hidden_act
|
| 118 |
+
|
| 119 |
+
@classmethod
|
| 120 |
+
def from_pretrained(cls, pretrained_model_name_or_path: Union[str, os.PathLike], **kwargs) -> "PretrainedConfig":
|
| 121 |
+
cls._set_token_in_kwargs(kwargs)
|
| 122 |
+
|
| 123 |
+
config_dict, kwargs = cls.get_config_dict(pretrained_model_name_or_path, **kwargs)
|
| 124 |
+
|
| 125 |
+
# get the vision config dict if we are loading from SiglipConfig
|
| 126 |
+
if config_dict.get("model_type") == "siglip":
|
| 127 |
+
config_dict = config_dict["vision_config"]
|
| 128 |
+
|
| 129 |
+
if "model_type" in config_dict and hasattr(cls, "model_type") and config_dict["model_type"] != cls.model_type:
|
| 130 |
+
logger.warning(
|
| 131 |
+
f"You are using a model of type {config_dict['model_type']} to instantiate a model of type "
|
| 132 |
+
f"{cls.model_type}. This is not supported for all configurations of models and can yield errors."
|
| 133 |
+
)
|
| 134 |
+
|
| 135 |
+
return cls.from_dict(config_dict, **kwargs)
|
| 136 |
+
|
| 137 |
+
|
| 138 |
+
_CHECKPOINT_FOR_DOC = "google/siglip-base-patch16-224"
|
| 139 |
+
|
| 140 |
+
SIGLIP_PRETRAINED_MODEL_ARCHIVE_LIST = [
|
| 141 |
+
"google/siglip-base-patch16-224",
|
| 142 |
+
# See all SigLIP models at https://huggingface.co/models?filter=siglip
|
| 143 |
+
]
|
| 144 |
+
|
| 145 |
+
if is_flash_attn_2_available():
|
| 146 |
+
from flash_attn import flash_attn_func
|
| 147 |
+
from flash_attn import flash_attn_varlen_func
|
| 148 |
+
from flash_attn.bert_padding import index_first_axis # noqa
|
| 149 |
+
from flash_attn.bert_padding import pad_input
|
| 150 |
+
from flash_attn.bert_padding import unpad_input
|
| 151 |
+
|
| 152 |
+
|
| 153 |
+
# Copied from transformers.models.llama.modeling_llama._get_unpad_data
|
| 154 |
+
def _get_unpad_data(attention_mask):
|
| 155 |
+
seqlens_in_batch = attention_mask.sum(dim=-1, dtype=torch.int32)
|
| 156 |
+
indices = torch.nonzero(attention_mask.flatten(), as_tuple=False).flatten()
|
| 157 |
+
max_seqlen_in_batch = seqlens_in_batch.max().item()
|
| 158 |
+
cu_seqlens = F.pad(torch.cumsum(seqlens_in_batch, dim=0, dtype=torch.torch.int32), (1, 0))
|
| 159 |
+
return (
|
| 160 |
+
indices,
|
| 161 |
+
cu_seqlens,
|
| 162 |
+
max_seqlen_in_batch,
|
| 163 |
+
)
|
| 164 |
+
|
| 165 |
+
|
| 166 |
+
def _trunc_normal_(tensor, mean, std, a, b):
|
| 167 |
+
# Cut & paste from PyTorch official master until it's in a few official releases - RW
|
| 168 |
+
# Method based on https://people.sc.fsu.edu/~jburkardt/presentations/truncated_normal.pdf
|
| 169 |
+
def norm_cdf(x):
|
| 170 |
+
# Computes standard normal cumulative distribution function
|
| 171 |
+
return (1.0 + math.erf(x / math.sqrt(2.0))) / 2.0
|
| 172 |
+
|
| 173 |
+
if (mean < a - 2 * std) or (mean > b + 2 * std):
|
| 174 |
+
warnings.warn(
|
| 175 |
+
"mean is more than 2 std from [a, b] in nn.init.trunc_normal_. "
|
| 176 |
+
"The distribution of values may be incorrect.",
|
| 177 |
+
stacklevel=2,
|
| 178 |
+
)
|
| 179 |
+
|
| 180 |
+
# Values are generated by using a truncated uniform distribution and
|
| 181 |
+
# then using the inverse CDF for the normal distribution.
|
| 182 |
+
# Get upper and lower cdf values
|
| 183 |
+
l = norm_cdf((a - mean) / std)
|
| 184 |
+
u = norm_cdf((b - mean) / std)
|
| 185 |
+
|
| 186 |
+
# Uniformly fill tensor with values from [l, u], then translate to
|
| 187 |
+
# [2l-1, 2u-1].
|
| 188 |
+
tensor.uniform_(2 * l - 1, 2 * u - 1)
|
| 189 |
+
|
| 190 |
+
# Use inverse cdf transform for normal distribution to get truncated
|
| 191 |
+
# standard normal
|
| 192 |
+
if tensor.dtype in [torch.float16, torch.bfloat16]:
|
| 193 |
+
# The `erfinv_` op is not (yet?) defined in float16+cpu, bfloat16+gpu
|
| 194 |
+
og_dtype = tensor.dtype
|
| 195 |
+
tensor = tensor.to(torch.float32)
|
| 196 |
+
tensor.erfinv_()
|
| 197 |
+
tensor = tensor.to(og_dtype)
|
| 198 |
+
else:
|
| 199 |
+
tensor.erfinv_()
|
| 200 |
+
|
| 201 |
+
# Transform to proper mean, std
|
| 202 |
+
tensor.mul_(std * math.sqrt(2.0))
|
| 203 |
+
tensor.add_(mean)
|
| 204 |
+
|
| 205 |
+
# Clamp to ensure it's in the proper range
|
| 206 |
+
if tensor.dtype == torch.float16:
|
| 207 |
+
# The `clamp_` op is not (yet?) defined in float16+cpu
|
| 208 |
+
tensor = tensor.to(torch.float32)
|
| 209 |
+
tensor.clamp_(min=a, max=b)
|
| 210 |
+
tensor = tensor.to(torch.float16)
|
| 211 |
+
else:
|
| 212 |
+
tensor.clamp_(min=a, max=b)
|
| 213 |
+
|
| 214 |
+
|
| 215 |
+
def trunc_normal_tf_(
|
| 216 |
+
tensor: torch.Tensor,
|
| 217 |
+
mean: float = 0.0,
|
| 218 |
+
std: float = 1.0,
|
| 219 |
+
a: float = -2.0,
|
| 220 |
+
b: float = 2.0,
|
| 221 |
+
) -> torch.Tensor:
|
| 222 |
+
"""Fills the input Tensor with values drawn from a truncated
|
| 223 |
+
normal distribution. The values are effectively drawn from the
|
| 224 |
+
normal distribution :math:`\\mathcal{N}(\text{mean}, \text{std}^2)`
|
| 225 |
+
with values outside :math:`[a, b]` redrawn until they are within
|
| 226 |
+
the bounds. The method used for generating the random values works
|
| 227 |
+
best when :math:`a \\leq \text{mean} \\leq b`.
|
| 228 |
+
NOTE: this 'tf' variant behaves closer to Tensorflow / JAX impl where the
|
| 229 |
+
bounds [a, b] are applied when sampling the normal distribution with mean=0, std=1.0
|
| 230 |
+
and the result is subsquently scaled and shifted by the mean and std args.
|
| 231 |
+
Args:
|
| 232 |
+
tensor: an n-dimensional `torch.Tensor`
|
| 233 |
+
mean: the mean of the normal distribution
|
| 234 |
+
std: the standard deviation of the normal distribution
|
| 235 |
+
a: the minimum cutoff value
|
| 236 |
+
b: the maximum cutoff value
|
| 237 |
+
"""
|
| 238 |
+
with torch.no_grad():
|
| 239 |
+
_trunc_normal_(tensor, 0, 1.0, a, b)
|
| 240 |
+
tensor.mul_(std).add_(mean)
|
| 241 |
+
|
| 242 |
+
|
| 243 |
+
def variance_scaling_(tensor, scale=1.0, mode="fan_in", distribution="normal"):
|
| 244 |
+
fan_in, fan_out = _calculate_fan_in_and_fan_out(tensor)
|
| 245 |
+
if mode == "fan_in":
|
| 246 |
+
denom = fan_in
|
| 247 |
+
elif mode == "fan_out":
|
| 248 |
+
denom = fan_out
|
| 249 |
+
elif mode == "fan_avg":
|
| 250 |
+
denom = (fan_in + fan_out) / 2
|
| 251 |
+
|
| 252 |
+
variance = scale / denom
|
| 253 |
+
|
| 254 |
+
if distribution == "truncated_normal":
|
| 255 |
+
# constant is stddev of standard normal truncated to (-2, 2)
|
| 256 |
+
trunc_normal_tf_(tensor, std=math.sqrt(variance) / 0.87962566103423978)
|
| 257 |
+
elif distribution == "normal":
|
| 258 |
+
with torch.no_grad():
|
| 259 |
+
tensor.normal_(std=math.sqrt(variance))
|
| 260 |
+
elif distribution == "uniform":
|
| 261 |
+
bound = math.sqrt(3 * variance)
|
| 262 |
+
with torch.no_grad():
|
| 263 |
+
tensor.uniform_(-bound, bound)
|
| 264 |
+
else:
|
| 265 |
+
raise ValueError(f"invalid distribution {distribution}")
|
| 266 |
+
|
| 267 |
+
|
| 268 |
+
def lecun_normal_(tensor):
|
| 269 |
+
variance_scaling_(tensor, mode="fan_in", distribution="truncated_normal")
|
| 270 |
+
|
| 271 |
+
|
| 272 |
+
def default_flax_embed_init(tensor):
|
| 273 |
+
variance_scaling_(tensor, mode="fan_in", distribution="normal")
|
| 274 |
+
|
| 275 |
+
|
| 276 |
+
@dataclass
|
| 277 |
+
# Copied from transformers.models.clip.modeling_clip.CLIPVisionModelOutput with CLIP->Siglip
|
| 278 |
+
class SiglipVisionModelOutput(ModelOutput):
|
| 279 |
+
"""
|
| 280 |
+
Base class for vision model's outputs that also contains image embeddings of the pooling of the last hidden states.
|
| 281 |
+
Args:
|
| 282 |
+
image_embeds (`torch.FloatTensor` of shape `(batch_size, output_dim)` *optional* returned when model is initialized with `with_projection=True`):
|
| 283 |
+
The image embeddings obtained by applying the projection layer to the pooler_output.
|
| 284 |
+
last_hidden_state (`torch.FloatTensor` of shape `(batch_size, sequence_length, hidden_size)`):
|
| 285 |
+
Sequence of hidden-states at the output of the last layer of the model.
|
| 286 |
+
hidden_states (`tuple(torch.FloatTensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`):
|
| 287 |
+
Tuple of `torch.FloatTensor` (one for the output of the embeddings, if the model has an embedding layer, +
|
| 288 |
+
one for the output of each layer) of shape `(batch_size, sequence_length, hidden_size)`.
|
| 289 |
+
Hidden-states of the model at the output of each layer plus the optional initial embedding outputs.
|
| 290 |
+
attentions (`tuple(torch.FloatTensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`):
|
| 291 |
+
Tuple of `torch.FloatTensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length,
|
| 292 |
+
sequence_length)`.
|
| 293 |
+
Attentions weights after the attention softmax, used to compute the weighted average in the self-attention
|
| 294 |
+
heads.
|
| 295 |
+
"""
|
| 296 |
+
|
| 297 |
+
image_embeds: Optional[torch.FloatTensor] = None
|
| 298 |
+
last_hidden_state: torch.FloatTensor = None
|
| 299 |
+
hidden_states: Optional[Tuple[torch.FloatTensor]] = None
|
| 300 |
+
attentions: Optional[Tuple[torch.FloatTensor]] = None
|
| 301 |
+
|
| 302 |
+
|
| 303 |
+
class SiglipVisionEmbeddings(nn.Module):
|
| 304 |
+
def __init__(self, config: SiglipVisionConfig):
|
| 305 |
+
super().__init__()
|
| 306 |
+
self.config = config
|
| 307 |
+
self.embed_dim = config.hidden_size
|
| 308 |
+
self.image_size = config.image_size
|
| 309 |
+
self.patch_size = config.patch_size
|
| 310 |
+
|
| 311 |
+
self.patch_embedding = nn.Conv2d(
|
| 312 |
+
in_channels=config.num_channels,
|
| 313 |
+
out_channels=self.embed_dim,
|
| 314 |
+
kernel_size=self.patch_size,
|
| 315 |
+
stride=self.patch_size,
|
| 316 |
+
padding="valid",
|
| 317 |
+
)
|
| 318 |
+
|
| 319 |
+
self.num_patches_per_side = self.image_size // self.patch_size
|
| 320 |
+
self.num_patches = self.num_patches_per_side**2
|
| 321 |
+
self.num_positions = self.num_patches
|
| 322 |
+
self.position_embedding = nn.Embedding(self.num_positions, self.embed_dim)
|
| 323 |
+
|
| 324 |
+
def forward(
|
| 325 |
+
self,
|
| 326 |
+
pixel_values: torch.FloatTensor,
|
| 327 |
+
patch_attention_mask: torch.BoolTensor,
|
| 328 |
+
tgt_sizes: Optional[torch.IntTensor] = None,
|
| 329 |
+
) -> torch.Tensor:
|
| 330 |
+
batch_size = pixel_values.size(0)
|
| 331 |
+
|
| 332 |
+
patch_embeds = self.patch_embedding(pixel_values)
|
| 333 |
+
embeddings = patch_embeds.flatten(2).transpose(1, 2)
|
| 334 |
+
|
| 335 |
+
max_im_h, max_im_w = pixel_values.size(2), pixel_values.size(3)
|
| 336 |
+
max_nb_patches_h, max_nb_patches_w = (
|
| 337 |
+
max_im_h // self.patch_size,
|
| 338 |
+
max_im_w // self.patch_size,
|
| 339 |
+
)
|
| 340 |
+
boundaries = torch.arange(1 / self.num_patches_per_side, 1.0, 1 / self.num_patches_per_side)
|
| 341 |
+
position_ids = torch.full(
|
| 342 |
+
size=(
|
| 343 |
+
batch_size,
|
| 344 |
+
max_nb_patches_h * max_nb_patches_w,
|
| 345 |
+
),
|
| 346 |
+
fill_value=0,
|
| 347 |
+
)
|
| 348 |
+
|
| 349 |
+
for batch_idx, p_attn_mask in enumerate(patch_attention_mask):
|
| 350 |
+
if tgt_sizes is not None:
|
| 351 |
+
nb_patches_h = tgt_sizes[batch_idx][0]
|
| 352 |
+
nb_patches_w = tgt_sizes[batch_idx][1]
|
| 353 |
+
else:
|
| 354 |
+
nb_patches_h = p_attn_mask[:, 0].sum()
|
| 355 |
+
nb_patches_w = p_attn_mask[0].sum()
|
| 356 |
+
|
| 357 |
+
fractional_coords_h = torch.arange(0, 1 - 1e-6, 1 / nb_patches_h)
|
| 358 |
+
fractional_coords_w = torch.arange(0, 1 - 1e-6, 1 / nb_patches_w)
|
| 359 |
+
|
| 360 |
+
bucket_coords_h = torch.bucketize(fractional_coords_h, boundaries, right=True)
|
| 361 |
+
bucket_coords_w = torch.bucketize(fractional_coords_w, boundaries, right=True)
|
| 362 |
+
|
| 363 |
+
pos_ids = (bucket_coords_h[:, None] * self.num_patches_per_side + bucket_coords_w).flatten()
|
| 364 |
+
position_ids[batch_idx][p_attn_mask.view(-1).cpu()] = pos_ids
|
| 365 |
+
|
| 366 |
+
position_ids = position_ids.to(self.position_embedding.weight.device)
|
| 367 |
+
|
| 368 |
+
embeddings = embeddings + self.position_embedding(position_ids)
|
| 369 |
+
return embeddings
|
| 370 |
+
|
| 371 |
+
|
| 372 |
+
class SiglipAttention(nn.Module):
|
| 373 |
+
"""Multi-headed attention from 'Attention Is All You Need' paper"""
|
| 374 |
+
|
| 375 |
+
# Copied from transformers.models.clip.modeling_clip.CLIPAttention.__init__
|
| 376 |
+
def __init__(self, config):
|
| 377 |
+
super().__init__()
|
| 378 |
+
self.config = config
|
| 379 |
+
self.embed_dim = config.hidden_size
|
| 380 |
+
self.num_heads = config.num_attention_heads
|
| 381 |
+
self.head_dim = self.embed_dim // self.num_heads
|
| 382 |
+
if self.head_dim * self.num_heads != self.embed_dim:
|
| 383 |
+
raise ValueError(
|
| 384 |
+
f"embed_dim must be divisible by num_heads (got `embed_dim`: {self.embed_dim} and `num_heads`:"
|
| 385 |
+
f" {self.num_heads})."
|
| 386 |
+
)
|
| 387 |
+
self.scale = self.head_dim**-0.5
|
| 388 |
+
self.dropout = config.attention_dropout
|
| 389 |
+
|
| 390 |
+
self.k_proj = nn.Linear(self.embed_dim, self.embed_dim)
|
| 391 |
+
self.v_proj = nn.Linear(self.embed_dim, self.embed_dim)
|
| 392 |
+
self.q_proj = nn.Linear(self.embed_dim, self.embed_dim)
|
| 393 |
+
self.out_proj = nn.Linear(self.embed_dim, self.embed_dim)
|
| 394 |
+
|
| 395 |
+
def forward(
|
| 396 |
+
self,
|
| 397 |
+
hidden_states: torch.Tensor,
|
| 398 |
+
attention_mask: Optional[torch.Tensor] = None,
|
| 399 |
+
output_attentions: Optional[bool] = False,
|
| 400 |
+
) -> Tuple[torch.Tensor, Optional[torch.Tensor], Optional[Tuple[torch.Tensor]]]:
|
| 401 |
+
"""Input shape: Batch x Time x Channel"""
|
| 402 |
+
|
| 403 |
+
batch_size, q_len, _ = hidden_states.size()
|
| 404 |
+
|
| 405 |
+
query_states = self.q_proj(hidden_states)
|
| 406 |
+
key_states = self.k_proj(hidden_states)
|
| 407 |
+
value_states = self.v_proj(hidden_states)
|
| 408 |
+
|
| 409 |
+
query_states = query_states.view(batch_size, q_len, self.num_heads, self.head_dim).transpose(1, 2)
|
| 410 |
+
key_states = key_states.view(batch_size, q_len, self.num_heads, self.head_dim).transpose(1, 2)
|
| 411 |
+
value_states = value_states.view(batch_size, q_len, self.num_heads, self.head_dim).transpose(1, 2)
|
| 412 |
+
|
| 413 |
+
k_v_seq_len = key_states.shape[-2]
|
| 414 |
+
attn_weights = torch.matmul(query_states, key_states.transpose(2, 3)) * self.scale
|
| 415 |
+
|
| 416 |
+
if attn_weights.size() != (batch_size, self.num_heads, q_len, k_v_seq_len):
|
| 417 |
+
raise ValueError(
|
| 418 |
+
f"Attention weights should be of size {(batch_size, self.num_heads, q_len, k_v_seq_len)}, but is"
|
| 419 |
+
f" {attn_weights.size()}"
|
| 420 |
+
)
|
| 421 |
+
|
| 422 |
+
if attention_mask is not None:
|
| 423 |
+
if attention_mask.size() != (batch_size, 1, q_len, k_v_seq_len):
|
| 424 |
+
raise ValueError(
|
| 425 |
+
f"Attention mask should be of size {(batch_size, 1, q_len, k_v_seq_len)}, but is {attention_mask.size()}"
|
| 426 |
+
)
|
| 427 |
+
attn_weights = attn_weights + attention_mask
|
| 428 |
+
|
| 429 |
+
# upcast attention to fp32
|
| 430 |
+
attn_weights = nn.functional.softmax(attn_weights, dim=-1, dtype=torch.float32).to(query_states.dtype)
|
| 431 |
+
attn_weights = nn.functional.dropout(attn_weights, p=self.dropout, training=self.training)
|
| 432 |
+
attn_output = torch.matmul(attn_weights, value_states)
|
| 433 |
+
|
| 434 |
+
if attn_output.size() != (batch_size, self.num_heads, q_len, self.head_dim):
|
| 435 |
+
raise ValueError(
|
| 436 |
+
f"`attn_output` should be of size {(batch_size, self.num_heads, q_len, self.head_dim)}, but is"
|
| 437 |
+
f" {attn_output.size()}"
|
| 438 |
+
)
|
| 439 |
+
|
| 440 |
+
attn_output = attn_output.transpose(1, 2).contiguous()
|
| 441 |
+
attn_output = attn_output.reshape(batch_size, q_len, self.embed_dim)
|
| 442 |
+
|
| 443 |
+
attn_output = self.out_proj(attn_output)
|
| 444 |
+
|
| 445 |
+
return attn_output, attn_weights
|
| 446 |
+
|
| 447 |
+
|
| 448 |
+
class SiglipFlashAttention2(SiglipAttention):
|
| 449 |
+
"""
|
| 450 |
+
Llama flash attention module. This module inherits from `LlamaAttention` as the weights of the module stays
|
| 451 |
+
untouched. The only required change would be on the forward pass where it needs to correctly call the public API of
|
| 452 |
+
flash attention and deal with padding tokens in case the input contains any of them.
|
| 453 |
+
"""
|
| 454 |
+
|
| 455 |
+
def __init__(self, *args, **kwargs):
|
| 456 |
+
super().__init__(*args, **kwargs)
|
| 457 |
+
self.is_causal = False # Hack to make sure we don't use a causal mask
|
| 458 |
+
|
| 459 |
+
def forward(
|
| 460 |
+
self,
|
| 461 |
+
hidden_states: torch.Tensor,
|
| 462 |
+
attention_mask: Optional[torch.LongTensor] = None,
|
| 463 |
+
position_ids: Optional[torch.LongTensor] = None,
|
| 464 |
+
past_key_value: Optional[Tuple[torch.Tensor]] = None,
|
| 465 |
+
output_attentions: bool = False,
|
| 466 |
+
use_cache: bool = False,
|
| 467 |
+
**kwargs,
|
| 468 |
+
) -> Tuple[torch.Tensor, Optional[torch.Tensor], Optional[Tuple[torch.Tensor]]]:
|
| 469 |
+
output_attentions = False
|
| 470 |
+
|
| 471 |
+
bsz, q_len, _ = hidden_states.size()
|
| 472 |
+
|
| 473 |
+
query_states = self.q_proj(hidden_states)
|
| 474 |
+
key_states = self.k_proj(hidden_states)
|
| 475 |
+
value_states = self.v_proj(hidden_states)
|
| 476 |
+
|
| 477 |
+
# Flash attention requires the input to have the shape
|
| 478 |
+
# batch_size x seq_length x head_dim x hidden_dim
|
| 479 |
+
# therefore we just need to keep the original shape
|
| 480 |
+
query_states = query_states.view(bsz, q_len, self.num_heads, self.head_dim).transpose(1, 2)
|
| 481 |
+
key_states = key_states.view(bsz, q_len, self.num_heads, self.head_dim).transpose(1, 2)
|
| 482 |
+
value_states = value_states.view(bsz, q_len, self.num_heads, self.head_dim).transpose(1, 2)
|
| 483 |
+
|
| 484 |
+
kv_seq_len = key_states.shape[-2]
|
| 485 |
+
if past_key_value is not None:
|
| 486 |
+
kv_seq_len += past_key_value.get_usable_length(kv_seq_len, self.layer_idx)
|
| 487 |
+
# cos, sin = self.rotary_emb(value_states, seq_len=kv_seq_len)
|
| 488 |
+
# query_states, key_states = apply_rotary_pos_emb(query_states, key_states, cos, sin, position_ids)
|
| 489 |
+
|
| 490 |
+
# if past_key_value is not None:
|
| 491 |
+
# cache_kwargs = {"sin": sin, "cos": cos} # Specific to RoPE models
|
| 492 |
+
# key_states, value_states = past_key_value.update(key_states, value_states, self.layer_idx, cache_kwargs)
|
| 493 |
+
|
| 494 |
+
# TODO: These transpose are quite inefficient but Flash Attention requires the layout [batch_size, sequence_length, num_heads, head_dim]. We would need to refactor the KV cache
|
| 495 |
+
# to be able to avoid many of these transpose/reshape/view.
|
| 496 |
+
query_states = query_states.transpose(1, 2)
|
| 497 |
+
key_states = key_states.transpose(1, 2)
|
| 498 |
+
value_states = value_states.transpose(1, 2)
|
| 499 |
+
|
| 500 |
+
dropout_rate = self.dropout if self.training else 0.0
|
| 501 |
+
|
| 502 |
+
# In PEFT, usually we cast the layer norms in float32 for training stability reasons
|
| 503 |
+
# therefore the input hidden states gets silently casted in float32. Hence, we need
|
| 504 |
+
# cast them back in the correct dtype just to be sure everything works as expected.
|
| 505 |
+
# This might slowdown training & inference so it is recommended to not cast the LayerNorms
|
| 506 |
+
# in fp32. (LlamaRMSNorm handles it correctly)
|
| 507 |
+
|
| 508 |
+
input_dtype = query_states.dtype
|
| 509 |
+
if input_dtype == torch.float32:
|
| 510 |
+
if torch.is_autocast_enabled():
|
| 511 |
+
target_dtype = torch.get_autocast_gpu_dtype()
|
| 512 |
+
# Handle the case where the model is quantized
|
| 513 |
+
elif hasattr(self.config, "_pre_quantization_dtype"):
|
| 514 |
+
target_dtype = self.config._pre_quantization_dtype
|
| 515 |
+
else:
|
| 516 |
+
target_dtype = self.q_proj.weight.dtype
|
| 517 |
+
|
| 518 |
+
logger.warning_once(
|
| 519 |
+
"The input hidden states seems to be silently casted in float32, this might be related to the fact"
|
| 520 |
+
" you have upcasted embedding or layer norm layers in float32. We will cast back the input in"
|
| 521 |
+
f" {target_dtype}."
|
| 522 |
+
)
|
| 523 |
+
|
| 524 |
+
query_states = query_states.to(target_dtype)
|
| 525 |
+
key_states = key_states.to(target_dtype)
|
| 526 |
+
value_states = value_states.to(target_dtype)
|
| 527 |
+
|
| 528 |
+
attn_output = self._flash_attention_forward(
|
| 529 |
+
query_states,
|
| 530 |
+
key_states,
|
| 531 |
+
value_states,
|
| 532 |
+
attention_mask,
|
| 533 |
+
q_len,
|
| 534 |
+
dropout=dropout_rate,
|
| 535 |
+
)
|
| 536 |
+
|
| 537 |
+
attn_output = attn_output.reshape(bsz, q_len, self.embed_dim).contiguous()
|
| 538 |
+
attn_output = self.out_proj(attn_output)
|
| 539 |
+
|
| 540 |
+
if not output_attentions:
|
| 541 |
+
attn_weights = None
|
| 542 |
+
|
| 543 |
+
return attn_output, attn_weights
|
| 544 |
+
|
| 545 |
+
def _flash_attention_forward(
|
| 546 |
+
self,
|
| 547 |
+
query_states,
|
| 548 |
+
key_states,
|
| 549 |
+
value_states,
|
| 550 |
+
attention_mask,
|
| 551 |
+
query_length,
|
| 552 |
+
dropout=0.0,
|
| 553 |
+
softmax_scale=None,
|
| 554 |
+
):
|
| 555 |
+
"""
|
| 556 |
+
Calls the forward method of Flash Attention - if the input hidden states contain at least one padding token
|
| 557 |
+
first unpad the input, then computes the attention scores and pad the final attention scores.
|
| 558 |
+
Args:
|
| 559 |
+
query_states (`torch.Tensor`):
|
| 560 |
+
Input query states to be passed to Flash Attention API
|
| 561 |
+
key_states (`torch.Tensor`):
|
| 562 |
+
Input key states to be passed to Flash Attention API
|
| 563 |
+
value_states (`torch.Tensor`):
|
| 564 |
+
Input value states to be passed to Flash Attention API
|
| 565 |
+
attention_mask (`torch.Tensor`):
|
| 566 |
+
The padding mask - corresponds to a tensor of size `(batch_size, seq_len)` where 0 stands for the
|
| 567 |
+
position of padding tokens and 1 for the position of non-padding tokens.
|
| 568 |
+
dropout (`int`, *optional*):
|
| 569 |
+
Attention dropout
|
| 570 |
+
softmax_scale (`float`, *optional*):
|
| 571 |
+
The scaling of QK^T before applying softmax. Default to 1 / sqrt(head_dim)
|
| 572 |
+
"""
|
| 573 |
+
|
| 574 |
+
# TODO: Remove the `query_length != 1` check once Flash Attention for RoCm is bumped to 2.1. For details, please see the comment in LlamaFlashAttention2 __init__.
|
| 575 |
+
causal = self.is_causal and query_length != 1
|
| 576 |
+
|
| 577 |
+
# Contains at least one padding token in the sequence
|
| 578 |
+
if attention_mask is not None:
|
| 579 |
+
batch_size = query_states.shape[0]
|
| 580 |
+
(
|
| 581 |
+
query_states,
|
| 582 |
+
key_states,
|
| 583 |
+
value_states,
|
| 584 |
+
indices_q,
|
| 585 |
+
cu_seq_lens,
|
| 586 |
+
max_seq_lens,
|
| 587 |
+
) = self._upad_input(query_states, key_states, value_states, attention_mask, query_length)
|
| 588 |
+
|
| 589 |
+
cu_seqlens_q, cu_seqlens_k = cu_seq_lens
|
| 590 |
+
max_seqlen_in_batch_q, max_seqlen_in_batch_k = max_seq_lens
|
| 591 |
+
|
| 592 |
+
attn_output_unpad = flash_attn_varlen_func(
|
| 593 |
+
query_states,
|
| 594 |
+
key_states,
|
| 595 |
+
value_states,
|
| 596 |
+
cu_seqlens_q=cu_seqlens_q,
|
| 597 |
+
cu_seqlens_k=cu_seqlens_k,
|
| 598 |
+
max_seqlen_q=max_seqlen_in_batch_q,
|
| 599 |
+
max_seqlen_k=max_seqlen_in_batch_k,
|
| 600 |
+
dropout_p=dropout,
|
| 601 |
+
softmax_scale=softmax_scale,
|
| 602 |
+
causal=causal,
|
| 603 |
+
)
|
| 604 |
+
|
| 605 |
+
attn_output = pad_input(attn_output_unpad, indices_q, batch_size, query_length)
|
| 606 |
+
else:
|
| 607 |
+
attn_output = flash_attn_func(
|
| 608 |
+
query_states,
|
| 609 |
+
key_states,
|
| 610 |
+
value_states,
|
| 611 |
+
dropout,
|
| 612 |
+
softmax_scale=softmax_scale,
|
| 613 |
+
causal=causal,
|
| 614 |
+
)
|
| 615 |
+
|
| 616 |
+
return attn_output
|
| 617 |
+
|
| 618 |
+
def _upad_input(self, query_layer, key_layer, value_layer, attention_mask, query_length):
|
| 619 |
+
indices_k, cu_seqlens_k, max_seqlen_in_batch_k = _get_unpad_data(attention_mask)
|
| 620 |
+
batch_size, kv_seq_len, num_key_value_heads, head_dim = key_layer.shape
|
| 621 |
+
|
| 622 |
+
key_layer = index_first_axis(
|
| 623 |
+
key_layer.reshape(batch_size * kv_seq_len, num_key_value_heads, head_dim),
|
| 624 |
+
indices_k,
|
| 625 |
+
)
|
| 626 |
+
value_layer = index_first_axis(
|
| 627 |
+
value_layer.reshape(batch_size * kv_seq_len, num_key_value_heads, head_dim),
|
| 628 |
+
indices_k,
|
| 629 |
+
)
|
| 630 |
+
if query_length == kv_seq_len:
|
| 631 |
+
query_layer = index_first_axis(
|
| 632 |
+
query_layer.reshape(batch_size * kv_seq_len, self.num_heads, head_dim),
|
| 633 |
+
indices_k,
|
| 634 |
+
)
|
| 635 |
+
cu_seqlens_q = cu_seqlens_k
|
| 636 |
+
max_seqlen_in_batch_q = max_seqlen_in_batch_k
|
| 637 |
+
indices_q = indices_k
|
| 638 |
+
elif query_length == 1:
|
| 639 |
+
max_seqlen_in_batch_q = 1
|
| 640 |
+
cu_seqlens_q = torch.arange(
|
| 641 |
+
batch_size + 1, dtype=torch.int32, device=query_layer.device
|
| 642 |
+
) # There is a memcpy here, that is very bad.
|
| 643 |
+
indices_q = cu_seqlens_q[:-1]
|
| 644 |
+
query_layer = query_layer.squeeze(1)
|
| 645 |
+
else:
|
| 646 |
+
# The -q_len: slice assumes left padding.
|
| 647 |
+
attention_mask = attention_mask[:, -query_length:]
|
| 648 |
+
query_layer, indices_q, cu_seqlens_q, max_seqlen_in_batch_q = unpad_input(query_layer, attention_mask)
|
| 649 |
+
|
| 650 |
+
return (
|
| 651 |
+
query_layer,
|
| 652 |
+
key_layer,
|
| 653 |
+
value_layer,
|
| 654 |
+
indices_q,
|
| 655 |
+
(cu_seqlens_q, cu_seqlens_k),
|
| 656 |
+
(max_seqlen_in_batch_q, max_seqlen_in_batch_k),
|
| 657 |
+
)
|
| 658 |
+
|
| 659 |
+
|
| 660 |
+
# Copied from transformers.models.clip.modeling_clip.CLIPMLP with CLIP->Siglip
|
| 661 |
+
class SiglipMLP(nn.Module):
|
| 662 |
+
def __init__(self, config):
|
| 663 |
+
super().__init__()
|
| 664 |
+
self.config = config
|
| 665 |
+
self.activation_fn = ACT2FN[config.hidden_act]
|
| 666 |
+
self.fc1 = nn.Linear(config.hidden_size, config.intermediate_size)
|
| 667 |
+
self.fc2 = nn.Linear(config.intermediate_size, config.hidden_size)
|
| 668 |
+
|
| 669 |
+
def forward(self, hidden_states: torch.Tensor) -> torch.Tensor:
|
| 670 |
+
hidden_states = self.fc1(hidden_states)
|
| 671 |
+
hidden_states = self.activation_fn(hidden_states)
|
| 672 |
+
hidden_states = self.fc2(hidden_states)
|
| 673 |
+
return hidden_states
|
| 674 |
+
|
| 675 |
+
|
| 676 |
+
# Copied from transformers.models.clip.modeling_clip.CLIPEncoderLayer with CLIP->Siglip
|
| 677 |
+
class SiglipEncoderLayer(nn.Module):
|
| 678 |
+
def __init__(self, config: SiglipVisionConfig):
|
| 679 |
+
super().__init__()
|
| 680 |
+
self.embed_dim = config.hidden_size
|
| 681 |
+
self._use_flash_attention_2 = config._attn_implementation == "flash_attention_2"
|
| 682 |
+
self.self_attn = SiglipAttention(config) if not self._use_flash_attention_2 else SiglipFlashAttention2(config)
|
| 683 |
+
self.layer_norm1 = nn.LayerNorm(self.embed_dim, eps=config.layer_norm_eps)
|
| 684 |
+
self.mlp = SiglipMLP(config)
|
| 685 |
+
self.layer_norm2 = nn.LayerNorm(self.embed_dim, eps=config.layer_norm_eps)
|
| 686 |
+
|
| 687 |
+
def forward(
|
| 688 |
+
self,
|
| 689 |
+
hidden_states: torch.Tensor,
|
| 690 |
+
attention_mask: torch.Tensor,
|
| 691 |
+
output_attentions: Optional[bool] = False,
|
| 692 |
+
) -> Tuple[torch.FloatTensor]:
|
| 693 |
+
"""
|
| 694 |
+
Args:
|
| 695 |
+
hidden_states (`torch.FloatTensor`):
|
| 696 |
+
Input to the layer of shape `(batch, seq_len, embed_dim)`.
|
| 697 |
+
attention_mask (`torch.FloatTensor`):
|
| 698 |
+
Attention mask of shape `(batch, 1, q_len, k_v_seq_len)` where padding elements are indicated by very large negative values.
|
| 699 |
+
output_attentions (`bool`, *optional*, defaults to `False`):
|
| 700 |
+
Whether or not to return the attentions tensors of all attention layers. See `attentions` under
|
| 701 |
+
returned tensors for more detail.
|
| 702 |
+
"""
|
| 703 |
+
residual = hidden_states
|
| 704 |
+
|
| 705 |
+
hidden_states = self.layer_norm1(hidden_states)
|
| 706 |
+
hidden_states, attn_weights = self.self_attn(
|
| 707 |
+
hidden_states=hidden_states,
|
| 708 |
+
attention_mask=attention_mask,
|
| 709 |
+
output_attentions=output_attentions,
|
| 710 |
+
)
|
| 711 |
+
hidden_states = residual + hidden_states
|
| 712 |
+
|
| 713 |
+
residual = hidden_states
|
| 714 |
+
hidden_states = self.layer_norm2(hidden_states)
|
| 715 |
+
hidden_states = self.mlp(hidden_states)
|
| 716 |
+
hidden_states = residual + hidden_states
|
| 717 |
+
|
| 718 |
+
outputs = (hidden_states,)
|
| 719 |
+
|
| 720 |
+
if output_attentions:
|
| 721 |
+
outputs += (attn_weights,)
|
| 722 |
+
|
| 723 |
+
return outputs
|
| 724 |
+
|
| 725 |
+
|
| 726 |
+
class SiglipPreTrainedModel(PreTrainedModel):
|
| 727 |
+
"""
|
| 728 |
+
An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained
|
| 729 |
+
models.
|
| 730 |
+
"""
|
| 731 |
+
|
| 732 |
+
config_class = SiglipVisionConfig
|
| 733 |
+
base_model_prefix = "siglip"
|
| 734 |
+
supports_gradient_checkpointing = True
|
| 735 |
+
|
| 736 |
+
def _init_weights(self, module):
|
| 737 |
+
"""Initialize the weights"""
|
| 738 |
+
|
| 739 |
+
if isinstance(module, SiglipVisionEmbeddings):
|
| 740 |
+
width = self.config.hidden_size
|
| 741 |
+
nn.init.normal_(module.position_embedding.weight, std=1 / np.sqrt(width))
|
| 742 |
+
elif isinstance(module, nn.Embedding):
|
| 743 |
+
default_flax_embed_init(module.weight)
|
| 744 |
+
elif isinstance(module, SiglipAttention):
|
| 745 |
+
nn.init.normal_(module.q_proj.weight)
|
| 746 |
+
nn.init.normal_(module.k_proj.weight)
|
| 747 |
+
nn.init.normal_(module.v_proj.weight)
|
| 748 |
+
nn.init.normal_(module.out_proj.weight)
|
| 749 |
+
nn.init.zeros_(module.q_proj.bias)
|
| 750 |
+
nn.init.zeros_(module.k_proj.bias)
|
| 751 |
+
nn.init.zeros_(module.v_proj.bias)
|
| 752 |
+
nn.init.zeros_(module.out_proj.bias)
|
| 753 |
+
elif isinstance(module, SiglipMLP):
|
| 754 |
+
nn.init.normal_(module.fc1.weight)
|
| 755 |
+
nn.init.normal_(module.fc2.weight)
|
| 756 |
+
nn.init.normal_(module.fc1.bias, std=1e-6)
|
| 757 |
+
nn.init.normal_(module.fc2.bias, std=1e-6)
|
| 758 |
+
elif isinstance(module, (nn.Linear, nn.Conv2d)):
|
| 759 |
+
lecun_normal_(module.weight)
|
| 760 |
+
if module.bias is not None:
|
| 761 |
+
nn.init.zeros_(module.bias)
|
| 762 |
+
elif isinstance(module, nn.LayerNorm):
|
| 763 |
+
module.bias.data.zero_()
|
| 764 |
+
module.weight.data.fill_(1.0)
|
| 765 |
+
|
| 766 |
+
|
| 767 |
+
SIGLIP_START_DOCSTRING = r"""
|
| 768 |
+
This model inherits from [`PreTrainedModel`]. Check the superclass documentation for the generic methods the
|
| 769 |
+
library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads
|
| 770 |
+
etc.)
|
| 771 |
+
This model is also a PyTorch [torch.nn.Module](https://pytorch.org/docs/stable/nn.html#torch.nn.Module) subclass.
|
| 772 |
+
Use it as a regular PyTorch Module and refer to the PyTorch documentation for all matter related to general usage
|
| 773 |
+
and behavior.
|
| 774 |
+
Parameters:
|
| 775 |
+
config ([`SiglipVisionConfig`]): Model configuration class with all the parameters of the model.
|
| 776 |
+
Initializing with a config file does not load the weights associated with the model, only the
|
| 777 |
+
configuration. Check out the [`~PreTrainedModel.from_pretrained`] method to load the model weights.
|
| 778 |
+
"""
|
| 779 |
+
|
| 780 |
+
|
| 781 |
+
SIGLIP_VISION_INPUTS_DOCSTRING = r"""
|
| 782 |
+
Args:
|
| 783 |
+
pixel_values (`torch.FloatTensor` of shape `(batch_size, num_channels, height, width)`):
|
| 784 |
+
Pixel values. Padding will be ignored by default should you provide it. Pixel values can be obtained using
|
| 785 |
+
[`AutoImageProcessor`]. See [`CLIPImageProcessor.__call__`] for details.
|
| 786 |
+
output_attentions (`bool`, *optional*):
|
| 787 |
+
Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned
|
| 788 |
+
tensors for more detail.
|
| 789 |
+
output_hidden_states (`bool`, *optional*):
|
| 790 |
+
Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for
|
| 791 |
+
more detail.
|
| 792 |
+
return_dict (`bool`, *optional*):
|
| 793 |
+
Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple.
|
| 794 |
+
"""
|
| 795 |
+
|
| 796 |
+
|
| 797 |
+
# Copied from transformers.models.clip.modeling_clip.CLIPEncoder with CLIP->Siglip
|
| 798 |
+
class SiglipEncoder(nn.Module):
|
| 799 |
+
"""
|
| 800 |
+
Transformer encoder consisting of `config.num_hidden_layers` self attention layers. Each layer is a
|
| 801 |
+
[`SiglipEncoderLayer`].
|
| 802 |
+
Args:
|
| 803 |
+
config: SiglipConfig
|
| 804 |
+
"""
|
| 805 |
+
|
| 806 |
+
def __init__(self, config: SiglipVisionConfig):
|
| 807 |
+
super().__init__()
|
| 808 |
+
self.config = config
|
| 809 |
+
self.layers = nn.ModuleList([SiglipEncoderLayer(config) for _ in range(config.num_hidden_layers)])
|
| 810 |
+
self.gradient_checkpointing = False
|
| 811 |
+
|
| 812 |
+
# Ignore copy
|
| 813 |
+
def forward(
|
| 814 |
+
self,
|
| 815 |
+
inputs_embeds,
|
| 816 |
+
attention_mask: Optional[torch.Tensor] = None,
|
| 817 |
+
output_attentions: Optional[bool] = None,
|
| 818 |
+
output_hidden_states: Optional[bool] = None,
|
| 819 |
+
return_dict: Optional[bool] = None,
|
| 820 |
+
) -> Union[Tuple, BaseModelOutput]:
|
| 821 |
+
r"""
|
| 822 |
+
Args:
|
| 823 |
+
inputs_embeds (`torch.FloatTensor` of shape `(batch_size, sequence_length, hidden_size)`):
|
| 824 |
+
Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation.
|
| 825 |
+
This is useful if you want more control over how to convert `input_ids` indices into associated vectors
|
| 826 |
+
than the model's internal embedding lookup matrix.
|
| 827 |
+
attention_mask (`torch.Tensor` of shape `(batch_size, sequence_length)`, *optional*):
|
| 828 |
+
Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`:
|
| 829 |
+
- 1 for tokens that are **not masked**,
|
| 830 |
+
- 0 for tokens that are **masked**.
|
| 831 |
+
[What are attention masks?](../glossary#attention-mask)
|
| 832 |
+
output_attentions (`bool`, *optional*):
|
| 833 |
+
Whether or not to return the attentions tensors of all attention layers. See `attentions` under
|
| 834 |
+
returned tensors for more detail.
|
| 835 |
+
output_hidden_states (`bool`, *optional*):
|
| 836 |
+
Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors
|
| 837 |
+
for more detail.
|
| 838 |
+
return_dict (`bool`, *optional*):
|
| 839 |
+
Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple.
|
| 840 |
+
"""
|
| 841 |
+
output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions
|
| 842 |
+
output_hidden_states = (
|
| 843 |
+
output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states
|
| 844 |
+
)
|
| 845 |
+
return_dict = return_dict if return_dict is not None else self.config.use_return_dict
|
| 846 |
+
|
| 847 |
+
encoder_states = () if output_hidden_states else None
|
| 848 |
+
all_attentions = () if output_attentions else None
|
| 849 |
+
|
| 850 |
+
hidden_states = inputs_embeds
|
| 851 |
+
for encoder_layer in self.layers:
|
| 852 |
+
if output_hidden_states:
|
| 853 |
+
encoder_states = encoder_states + (hidden_states,)
|
| 854 |
+
if self.gradient_checkpointing and self.training:
|
| 855 |
+
layer_outputs = self._gradient_checkpointing_func(
|
| 856 |
+
encoder_layer.__call__,
|
| 857 |
+
hidden_states,
|
| 858 |
+
attention_mask,
|
| 859 |
+
output_attentions,
|
| 860 |
+
)
|
| 861 |
+
else:
|
| 862 |
+
layer_outputs = encoder_layer(
|
| 863 |
+
hidden_states,
|
| 864 |
+
attention_mask,
|
| 865 |
+
output_attentions=output_attentions,
|
| 866 |
+
)
|
| 867 |
+
|
| 868 |
+
hidden_states = layer_outputs[0]
|
| 869 |
+
|
| 870 |
+
if output_attentions:
|
| 871 |
+
all_attentions = all_attentions + (layer_outputs[1],)
|
| 872 |
+
|
| 873 |
+
if output_hidden_states:
|
| 874 |
+
encoder_states = encoder_states + (hidden_states,)
|
| 875 |
+
|
| 876 |
+
if not return_dict:
|
| 877 |
+
return tuple(v for v in [hidden_states, encoder_states, all_attentions] if v is not None)
|
| 878 |
+
return BaseModelOutput(
|
| 879 |
+
last_hidden_state=hidden_states,
|
| 880 |
+
hidden_states=encoder_states,
|
| 881 |
+
attentions=all_attentions,
|
| 882 |
+
)
|
| 883 |
+
|
| 884 |
+
|
| 885 |
+
@add_start_docstrings(
|
| 886 |
+
"""The vision model from SigLIP without any head or projection on top.""",
|
| 887 |
+
SIGLIP_START_DOCSTRING,
|
| 888 |
+
)
|
| 889 |
+
class SiglipVisionTransformer(SiglipPreTrainedModel):
|
| 890 |
+
config_class = SiglipVisionConfig
|
| 891 |
+
main_input_name = "pixel_values"
|
| 892 |
+
_supports_flash_attn_2 = True
|
| 893 |
+
_no_split_modules = []
|
| 894 |
+
|
| 895 |
+
def __init__(self, config: SiglipVisionConfig):
|
| 896 |
+
super().__init__(config)
|
| 897 |
+
self.config = config
|
| 898 |
+
embed_dim = config.hidden_size
|
| 899 |
+
|
| 900 |
+
self.embeddings = SiglipVisionEmbeddings(config)
|
| 901 |
+
self.encoder = SiglipEncoder(config)
|
| 902 |
+
self.post_layernorm = nn.LayerNorm(embed_dim, eps=config.layer_norm_eps)
|
| 903 |
+
self._use_flash_attention_2 = config._attn_implementation == "flash_attention_2"
|
| 904 |
+
|
| 905 |
+
# Initialize weights and apply final processing
|
| 906 |
+
self.post_init()
|
| 907 |
+
|
| 908 |
+
def get_input_embeddings(self) -> nn.Module:
|
| 909 |
+
return self.embeddings.patch_embedding
|
| 910 |
+
|
| 911 |
+
@add_start_docstrings_to_model_forward(SIGLIP_VISION_INPUTS_DOCSTRING)
|
| 912 |
+
@replace_return_docstrings(output_type=BaseModelOutputWithPooling, config_class=SiglipVisionConfig)
|
| 913 |
+
def forward(
|
| 914 |
+
self,
|
| 915 |
+
pixel_values,
|
| 916 |
+
patch_attention_mask: Optional[torch.BoolTensor] = None,
|
| 917 |
+
tgt_sizes: Optional[torch.IntTensor] = None,
|
| 918 |
+
output_attentions: Optional[bool] = None,
|
| 919 |
+
output_hidden_states: Optional[bool] = None,
|
| 920 |
+
return_dict: Optional[bool] = None,
|
| 921 |
+
) -> Union[Tuple, BaseModelOutputWithPooling]:
|
| 922 |
+
r"""
|
| 923 |
+
Returns:
|
| 924 |
+
"""
|
| 925 |
+
output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions
|
| 926 |
+
output_hidden_states = (
|
| 927 |
+
output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states
|
| 928 |
+
)
|
| 929 |
+
return_dict = return_dict if return_dict is not None else self.config.use_return_dict
|
| 930 |
+
|
| 931 |
+
batch_size = pixel_values.size(0)
|
| 932 |
+
if patch_attention_mask is None:
|
| 933 |
+
patch_attention_mask = torch.ones(
|
| 934 |
+
size=(
|
| 935 |
+
batch_size,
|
| 936 |
+
pixel_values.size(2) // self.config.patch_size,
|
| 937 |
+
pixel_values.size(3) // self.config.patch_size,
|
| 938 |
+
),
|
| 939 |
+
dtype=torch.bool,
|
| 940 |
+
device=pixel_values.device,
|
| 941 |
+
)
|
| 942 |
+
|
| 943 |
+
hidden_states = self.embeddings(
|
| 944 |
+
pixel_values=pixel_values,
|
| 945 |
+
patch_attention_mask=patch_attention_mask,
|
| 946 |
+
tgt_sizes=tgt_sizes,
|
| 947 |
+
)
|
| 948 |
+
|
| 949 |
+
patch_attention_mask = patch_attention_mask.view(batch_size, -1)
|
| 950 |
+
# The call to `_upad_input` in `_flash_attention_forward` is expensive
|
| 951 |
+
# So when the `patch_attention_mask` is full of 1s (i.e. attending to the whole sequence),
|
| 952 |
+
# avoiding passing the attention_mask, which is equivalent to attending to the full sequence
|
| 953 |
+
if not torch.any(~patch_attention_mask):
|
| 954 |
+
attention_mask = None
|
| 955 |
+
else:
|
| 956 |
+
attention_mask = (
|
| 957 |
+
_prepare_4d_attention_mask(patch_attention_mask, hidden_states.dtype)
|
| 958 |
+
if not self._use_flash_attention_2
|
| 959 |
+
else patch_attention_mask
|
| 960 |
+
)
|
| 961 |
+
|
| 962 |
+
encoder_outputs = self.encoder(
|
| 963 |
+
inputs_embeds=hidden_states,
|
| 964 |
+
attention_mask=attention_mask,
|
| 965 |
+
output_attentions=output_attentions,
|
| 966 |
+
output_hidden_states=output_hidden_states,
|
| 967 |
+
return_dict=return_dict,
|
| 968 |
+
)
|
| 969 |
+
|
| 970 |
+
last_hidden_state = encoder_outputs[0]
|
| 971 |
+
last_hidden_state = self.post_layernorm(last_hidden_state)
|
| 972 |
+
|
| 973 |
+
if not return_dict:
|
| 974 |
+
return (last_hidden_state, None) + encoder_outputs[1:]
|
| 975 |
+
|
| 976 |
+
return BaseModelOutputWithPooling(
|
| 977 |
+
last_hidden_state=last_hidden_state,
|
| 978 |
+
pooler_output=None,
|
| 979 |
+
hidden_states=encoder_outputs.hidden_states,
|
| 980 |
+
attentions=encoder_outputs.attentions,
|
| 981 |
+
)
|
preprocessor_config.json
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"image_processor_type": "MiniCPMVImageProcessor",
|
| 3 |
+
"feature_extractor_type": "MiniCPMAAudioProcessor",
|
| 4 |
+
"auto_map": {
|
| 5 |
+
"AutoProcessor": "processing_minicpmo.MiniCPMOProcessor",
|
| 6 |
+
"AutoImageProcessor": "processing_minicpmo.MiniCPMVImageProcessor",
|
| 7 |
+
"AutoFeatureExtractor": "processing_minicpmo.MiniCPMAAudioProcessor"
|
| 8 |
+
},
|
| 9 |
+
"processor_class": "MiniCPMOProcessor",
|
| 10 |
+
"max_slice_nums": 9,
|
| 11 |
+
"scale_resolution": 448,
|
| 12 |
+
"patch_size": 14,
|
| 13 |
+
"use_image_id": true,
|
| 14 |
+
"image_feature_size": 64,
|
| 15 |
+
"im_start": "<image>",
|
| 16 |
+
"im_end": "</image>",
|
| 17 |
+
"slice_start": "<slice>",
|
| 18 |
+
"slice_end": "</slice>",
|
| 19 |
+
"unk": "<unk>",
|
| 20 |
+
"im_id_start": "<image_id>",
|
| 21 |
+
"im_id_end": "</image_id>",
|
| 22 |
+
"slice_mode": true,
|
| 23 |
+
"audio_pool_step": 5,
|
| 24 |
+
"norm_mean": [
|
| 25 |
+
0.5,
|
| 26 |
+
0.5,
|
| 27 |
+
0.5
|
| 28 |
+
],
|
| 29 |
+
"norm_std": [
|
| 30 |
+
0.5,
|
| 31 |
+
0.5,
|
| 32 |
+
0.5
|
| 33 |
+
],
|
| 34 |
+
"version": 4.5
|
| 35 |
+
}
|
processing_minicpmo.py
ADDED
|
@@ -0,0 +1,1665 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python
|
| 2 |
+
# -*- coding: utf-8 -*-
|
| 3 |
+
# Copyright 2026 The OpenBMB Team. All rights reserved.
|
| 4 |
+
#
|
| 5 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 6 |
+
# you may not use this file except in compliance with the License.
|
| 7 |
+
# You may obtain a copy of the License at
|
| 8 |
+
#
|
| 9 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 10 |
+
#
|
| 11 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 12 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 13 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 14 |
+
# See the License for the specific language governing permissions and
|
| 15 |
+
# limitations under the License.
|
| 16 |
+
|
| 17 |
+
import copy
|
| 18 |
+
import math
|
| 19 |
+
import re
|
| 20 |
+
from typing import Any
|
| 21 |
+
from typing import Dict
|
| 22 |
+
from typing import List
|
| 23 |
+
from typing import Optional
|
| 24 |
+
from typing import Tuple
|
| 25 |
+
from typing import Union
|
| 26 |
+
|
| 27 |
+
import numpy as np
|
| 28 |
+
import torch
|
| 29 |
+
from PIL import Image
|
| 30 |
+
from transformers import AutoImageProcessor
|
| 31 |
+
from transformers.audio_utils import spectrogram
|
| 32 |
+
from transformers.audio_utils import window_function
|
| 33 |
+
from transformers.image_processing_utils import BaseImageProcessor
|
| 34 |
+
from transformers.image_processing_utils import BatchFeature
|
| 35 |
+
from transformers.image_transforms import to_channel_dimension_format
|
| 36 |
+
from transformers.image_utils import ChannelDimension
|
| 37 |
+
from transformers.image_utils import ImageInput
|
| 38 |
+
from transformers.image_utils import infer_channel_dimension_format
|
| 39 |
+
from transformers.image_utils import is_torch_tensor
|
| 40 |
+
from transformers.image_utils import to_numpy_array
|
| 41 |
+
from transformers.image_utils import valid_images
|
| 42 |
+
from transformers.models.whisper.feature_extraction_whisper import WhisperFeatureExtractor
|
| 43 |
+
from transformers.processing_utils import ProcessorMixin
|
| 44 |
+
from transformers.tokenization_utils_base import PreTokenizedInput
|
| 45 |
+
from transformers.tokenization_utils_base import TextInput
|
| 46 |
+
from transformers.utils import is_torch_device
|
| 47 |
+
from transformers.utils import is_torch_dtype
|
| 48 |
+
from transformers.utils import requires_backends
|
| 49 |
+
from transformers.utils import TensorType
|
| 50 |
+
|
| 51 |
+
|
| 52 |
+
def recursive_converter(converter, value):
|
| 53 |
+
if isinstance(value, list):
|
| 54 |
+
new_value = []
|
| 55 |
+
for v in value:
|
| 56 |
+
new_value += [recursive_converter(converter, v)]
|
| 57 |
+
return new_value
|
| 58 |
+
else:
|
| 59 |
+
return converter(value)
|
| 60 |
+
|
| 61 |
+
|
| 62 |
+
class MiniCPMOBatchFeature(BatchFeature):
|
| 63 |
+
"""Extend from BatchFeature for supporting various image size"""
|
| 64 |
+
|
| 65 |
+
def __init__(self, data: Optional[Dict[str, Any]] = None, tensor_type: Union[None, str, TensorType] = None):
|
| 66 |
+
super().__init__(data)
|
| 67 |
+
self.convert_to_tensors(tensor_type=tensor_type)
|
| 68 |
+
|
| 69 |
+
def convert_to_tensors(self, tensor_type: Optional[Union[str, TensorType]] = None):
|
| 70 |
+
if tensor_type is None:
|
| 71 |
+
return self
|
| 72 |
+
|
| 73 |
+
is_tensor, as_tensor = self._get_is_as_tensor_fns(tensor_type)
|
| 74 |
+
|
| 75 |
+
def converter(value):
|
| 76 |
+
try:
|
| 77 |
+
if not is_tensor(value):
|
| 78 |
+
tensor = as_tensor(value)
|
| 79 |
+
return tensor
|
| 80 |
+
except: # noqa E722
|
| 81 |
+
if key == "overflowing_values":
|
| 82 |
+
raise ValueError("Unable to create tensor returning overflowing values of different lengths. ")
|
| 83 |
+
raise ValueError(
|
| 84 |
+
"Unable to create tensor, you should probably activate padding "
|
| 85 |
+
"with 'padding=True' to have batched tensors with the same length."
|
| 86 |
+
)
|
| 87 |
+
|
| 88 |
+
for key, value in self.items():
|
| 89 |
+
self[key] = recursive_converter(converter, value)
|
| 90 |
+
return self
|
| 91 |
+
|
| 92 |
+
def to(self, *args, **kwargs) -> "MiniCPMOBatchFeature":
|
| 93 |
+
requires_backends(self, ["torch"])
|
| 94 |
+
import torch
|
| 95 |
+
|
| 96 |
+
def cast_tensor(v):
|
| 97 |
+
if not torch.is_tensor(v):
|
| 98 |
+
return v
|
| 99 |
+
|
| 100 |
+
if torch.is_floating_point(v):
|
| 101 |
+
return v.to(*args, **kwargs)
|
| 102 |
+
elif device is not None:
|
| 103 |
+
return v.to(device=device)
|
| 104 |
+
else:
|
| 105 |
+
return v
|
| 106 |
+
|
| 107 |
+
new_data = {}
|
| 108 |
+
device = kwargs.get("device")
|
| 109 |
+
if device is None and len(args) > 0:
|
| 110 |
+
arg = args[0]
|
| 111 |
+
if is_torch_dtype(arg):
|
| 112 |
+
pass
|
| 113 |
+
elif isinstance(arg, str) or is_torch_device(arg) or isinstance(arg, int):
|
| 114 |
+
device = arg
|
| 115 |
+
else:
|
| 116 |
+
raise ValueError(f"Attempting to cast a BatchFeature to type {str(arg)}. This is not supported.")
|
| 117 |
+
|
| 118 |
+
# We cast only floating point tensors to avoid issues with tokenizers casting `LongTensor` to `FloatTensor`
|
| 119 |
+
for k, v in self.items():
|
| 120 |
+
new_data[k] = recursive_converter(cast_tensor, v)
|
| 121 |
+
self.data = new_data
|
| 122 |
+
return self
|
| 123 |
+
|
| 124 |
+
|
| 125 |
+
class MiniCPMVImageProcessor(BaseImageProcessor):
|
| 126 |
+
model_input_names = ["pixel_values"]
|
| 127 |
+
|
| 128 |
+
def __init__(self, max_slice_nums=9, scale_resolution=448, patch_size=14, **kwargs):
|
| 129 |
+
super().__init__(**kwargs)
|
| 130 |
+
self.max_slice_nums = max_slice_nums
|
| 131 |
+
self.scale_resolution = scale_resolution
|
| 132 |
+
self.patch_size = patch_size
|
| 133 |
+
self.use_image_id = kwargs.pop("use_image_id", False)
|
| 134 |
+
self.image_feature_size = kwargs.pop("image_feature_size", 64)
|
| 135 |
+
self.im_start_token = kwargs.pop("im_start", "<image>")
|
| 136 |
+
self.im_end_token = kwargs.pop("im_end", "</image>")
|
| 137 |
+
self.slice_start_token = kwargs.pop("slice_start", "<slice>")
|
| 138 |
+
self.slice_end_token = kwargs.pop("slice_end", "</slice>")
|
| 139 |
+
self.unk_token = kwargs.pop("unk", "<unk>")
|
| 140 |
+
self.im_id_start = kwargs.pop("im_id_start", "<image_id>")
|
| 141 |
+
self.im_id_end = kwargs.pop("im_id_end", "</image_id>")
|
| 142 |
+
self.slice_mode = kwargs.pop("slice_mode", True)
|
| 143 |
+
|
| 144 |
+
self.mean = np.array(kwargs.pop("norm_mean", [0.5, 0.5, 0.5]))
|
| 145 |
+
self.std = np.array(kwargs.pop("norm_std", [0.5, 0.5, 0.5]))
|
| 146 |
+
self.version = kwargs.pop("version", 2.0)
|
| 147 |
+
|
| 148 |
+
@staticmethod
|
| 149 |
+
def ensure_divide(length, patch_size):
|
| 150 |
+
return max(round(length / patch_size) * patch_size, patch_size)
|
| 151 |
+
|
| 152 |
+
def find_best_resize(self, original_size, scale_resolution, patch_size, allow_upscale=False):
|
| 153 |
+
width, height = original_size
|
| 154 |
+
if (width * height > scale_resolution * scale_resolution) or allow_upscale:
|
| 155 |
+
r = width / height
|
| 156 |
+
height = int(scale_resolution / math.sqrt(r))
|
| 157 |
+
width = int(height * r)
|
| 158 |
+
best_width = self.ensure_divide(width, patch_size)
|
| 159 |
+
best_height = self.ensure_divide(height, patch_size)
|
| 160 |
+
return best_width, best_height
|
| 161 |
+
|
| 162 |
+
def get_refine_size(self, original_size, grid, scale_resolution, patch_size, allow_upscale=False):
|
| 163 |
+
width, height = original_size
|
| 164 |
+
grid_x, grid_y = grid
|
| 165 |
+
|
| 166 |
+
refine_width = self.ensure_divide(width, grid_x)
|
| 167 |
+
refine_height = self.ensure_divide(height, grid_y)
|
| 168 |
+
|
| 169 |
+
grid_width = refine_width / grid_x
|
| 170 |
+
grid_height = refine_height / grid_y
|
| 171 |
+
|
| 172 |
+
best_grid_size = self.find_best_resize(
|
| 173 |
+
(grid_width, grid_height), scale_resolution, patch_size, allow_upscale=allow_upscale
|
| 174 |
+
)
|
| 175 |
+
refine_size = (best_grid_size[0] * grid_x, best_grid_size[1] * grid_y)
|
| 176 |
+
return refine_size
|
| 177 |
+
|
| 178 |
+
@staticmethod
|
| 179 |
+
def split_to_patches(image, grid):
|
| 180 |
+
patches = []
|
| 181 |
+
width, height = image.size
|
| 182 |
+
grid_x = int(width / grid[0])
|
| 183 |
+
grid_y = int(height / grid[1])
|
| 184 |
+
for i in range(0, height, grid_y):
|
| 185 |
+
images = []
|
| 186 |
+
for j in range(0, width, grid_x):
|
| 187 |
+
box = (j, i, j + grid_x, i + grid_y)
|
| 188 |
+
patch = image.crop(box)
|
| 189 |
+
images.append(patch)
|
| 190 |
+
patches.append(images)
|
| 191 |
+
return patches
|
| 192 |
+
|
| 193 |
+
def slice_image(self, image, max_slice_nums=9, scale_resolution=448, patch_size=14, never_split=False):
|
| 194 |
+
original_size = image.size
|
| 195 |
+
source_image = None
|
| 196 |
+
best_grid = self.get_sliced_grid(original_size, max_slice_nums, never_split)
|
| 197 |
+
patches = []
|
| 198 |
+
|
| 199 |
+
if best_grid is None:
|
| 200 |
+
# dont need to slice, upsample
|
| 201 |
+
best_size = self.find_best_resize(original_size, scale_resolution, patch_size, allow_upscale=True)
|
| 202 |
+
source_image = image.resize(best_size, resample=Image.Resampling.BICUBIC)
|
| 203 |
+
else:
|
| 204 |
+
# source image, down-sampling and ensure divided by patch_size
|
| 205 |
+
best_resize = self.find_best_resize(original_size, scale_resolution, patch_size)
|
| 206 |
+
source_image = image.copy().resize(best_resize, resample=Image.Resampling.BICUBIC)
|
| 207 |
+
refine_size = self.get_refine_size(
|
| 208 |
+
original_size, best_grid, scale_resolution, patch_size, allow_upscale=True
|
| 209 |
+
)
|
| 210 |
+
refine_image = image.resize(refine_size, resample=Image.Resampling.BICUBIC)
|
| 211 |
+
patches = self.split_to_patches(refine_image, best_grid)
|
| 212 |
+
|
| 213 |
+
return source_image, patches, best_grid
|
| 214 |
+
|
| 215 |
+
def get_grid_placeholder(self, grid):
|
| 216 |
+
if grid is None:
|
| 217 |
+
return ""
|
| 218 |
+
slice_image_placeholder = (
|
| 219 |
+
self.slice_start_token + self.unk_token * self.image_feature_size + self.slice_end_token
|
| 220 |
+
)
|
| 221 |
+
|
| 222 |
+
cols = grid[0]
|
| 223 |
+
rows = grid[1]
|
| 224 |
+
slices = []
|
| 225 |
+
for i in range(rows):
|
| 226 |
+
lines = []
|
| 227 |
+
for j in range(cols):
|
| 228 |
+
lines.append(slice_image_placeholder)
|
| 229 |
+
slices.append("".join(lines))
|
| 230 |
+
|
| 231 |
+
slice_placeholder = "\n".join(slices)
|
| 232 |
+
return slice_placeholder
|
| 233 |
+
|
| 234 |
+
def get_image_id_placeholder(self, idx=0):
|
| 235 |
+
return f"{self.im_id_start}{idx}{self.im_id_end}"
|
| 236 |
+
|
| 237 |
+
def get_sliced_images(self, image, max_slice_nums=None):
|
| 238 |
+
slice_images = []
|
| 239 |
+
|
| 240 |
+
if not self.slice_mode:
|
| 241 |
+
return [image]
|
| 242 |
+
|
| 243 |
+
max_slice_nums = self.max_slice_nums if max_slice_nums is None else int(max_slice_nums)
|
| 244 |
+
assert max_slice_nums > 0
|
| 245 |
+
source_image, patches, sliced_grid = self.slice_image(
|
| 246 |
+
image, max_slice_nums, self.scale_resolution, self.patch_size # default: 9 # default: 448 # default: 14
|
| 247 |
+
)
|
| 248 |
+
|
| 249 |
+
slice_images.append(source_image)
|
| 250 |
+
if len(patches) > 0:
|
| 251 |
+
for i in range(len(patches)):
|
| 252 |
+
for j in range(len(patches[0])):
|
| 253 |
+
slice_images.append(patches[i][j])
|
| 254 |
+
return slice_images
|
| 255 |
+
|
| 256 |
+
def get_sliced_grid(self, image_size, max_slice_nums, nerver_split=False):
|
| 257 |
+
original_width, original_height = image_size
|
| 258 |
+
log_ratio = math.log(original_width / original_height)
|
| 259 |
+
ratio = original_width * original_height / (self.scale_resolution * self.scale_resolution)
|
| 260 |
+
multiple = min(math.ceil(ratio), max_slice_nums)
|
| 261 |
+
if multiple <= 1 or nerver_split:
|
| 262 |
+
return None
|
| 263 |
+
candidate_split_grids_nums = []
|
| 264 |
+
for i in [multiple - 1, multiple, multiple + 1]:
|
| 265 |
+
if i == 1 or i > max_slice_nums:
|
| 266 |
+
continue
|
| 267 |
+
candidate_split_grids_nums.append(i)
|
| 268 |
+
|
| 269 |
+
candidate_grids = []
|
| 270 |
+
for split_grids_nums in candidate_split_grids_nums:
|
| 271 |
+
m = 1
|
| 272 |
+
while m <= split_grids_nums:
|
| 273 |
+
if split_grids_nums % m == 0:
|
| 274 |
+
candidate_grids.append([m, split_grids_nums // m])
|
| 275 |
+
m += 1
|
| 276 |
+
|
| 277 |
+
best_grid = [1, 1]
|
| 278 |
+
min_error = float("inf")
|
| 279 |
+
for grid in candidate_grids:
|
| 280 |
+
error = abs(log_ratio - math.log(grid[0] / grid[1]))
|
| 281 |
+
if error < min_error:
|
| 282 |
+
best_grid = grid
|
| 283 |
+
min_error = error
|
| 284 |
+
|
| 285 |
+
return best_grid
|
| 286 |
+
|
| 287 |
+
def get_slice_image_placeholder(self, image_size, image_idx=0, max_slice_nums=None, use_image_id=None):
|
| 288 |
+
max_slice_nums = self.max_slice_nums if max_slice_nums is None else int(max_slice_nums)
|
| 289 |
+
assert max_slice_nums > 0
|
| 290 |
+
grid = self.get_sliced_grid(image_size=image_size, max_slice_nums=max_slice_nums)
|
| 291 |
+
|
| 292 |
+
image_placeholder = self.im_start_token + self.unk_token * self.image_feature_size + self.im_end_token
|
| 293 |
+
use_image_id = self.use_image_id if use_image_id is None else bool(use_image_id)
|
| 294 |
+
if use_image_id:
|
| 295 |
+
final_placeholder = self.get_image_id_placeholder(image_idx) + image_placeholder
|
| 296 |
+
else:
|
| 297 |
+
final_placeholder = image_placeholder
|
| 298 |
+
|
| 299 |
+
if self.slice_mode:
|
| 300 |
+
final_placeholder = final_placeholder + self.get_grid_placeholder(grid=grid)
|
| 301 |
+
return final_placeholder
|
| 302 |
+
|
| 303 |
+
@staticmethod
|
| 304 |
+
def to_pil_image(image, rescale=None) -> Image.Image:
|
| 305 |
+
"""Converts `image` to a PIL Image. Optionally rescales it and puts the channel dimension back
|
| 306 |
+
as the last axis if needed.
|
| 307 |
+
|
| 308 |
+
Args:
|
| 309 |
+
image (`Image.Image` or `numpy.ndarray` or `torch.Tensor`):
|
| 310 |
+
The image to convert to the PIL Image format.
|
| 311 |
+
rescale (`bool`, *optional*):
|
| 312 |
+
whether to apply the scaling factor (to make pixel values integers between 0 and 255). Will
|
| 313 |
+
default to `True` if the image type is a floating type, `False` otherwise.
|
| 314 |
+
"""
|
| 315 |
+
if isinstance(image, Image.Image):
|
| 316 |
+
return image
|
| 317 |
+
if is_torch_tensor(image):
|
| 318 |
+
image = image.numpy()
|
| 319 |
+
|
| 320 |
+
if isinstance(image, np.ndarray):
|
| 321 |
+
if rescale is None:
|
| 322 |
+
# rescale default to the array being of floating type.
|
| 323 |
+
rescale = isinstance(image.flat[0], np.floating)
|
| 324 |
+
# If the channel as been moved to first dim, we put it back at the end.
|
| 325 |
+
if image.ndim == 3 and image.shape[0] in [1, 3]:
|
| 326 |
+
image = image.transpose(1, 2, 0)
|
| 327 |
+
if rescale:
|
| 328 |
+
image = image * 255
|
| 329 |
+
image = image.astype(np.uint8)
|
| 330 |
+
return Image.fromarray(image)
|
| 331 |
+
return image
|
| 332 |
+
|
| 333 |
+
def reshape_by_patch(self, image):
|
| 334 |
+
image = torch.from_numpy(image)
|
| 335 |
+
patch_size = self.patch_size
|
| 336 |
+
patches = torch.nn.functional.unfold(image, (patch_size, patch_size), stride=(patch_size, patch_size))
|
| 337 |
+
|
| 338 |
+
patches = patches.reshape(image.size(0), patch_size, patch_size, -1)
|
| 339 |
+
patches = patches.permute(0, 1, 3, 2).reshape(image.size(0), patch_size, -1)
|
| 340 |
+
return patches.numpy()
|
| 341 |
+
|
| 342 |
+
def preprocess(
|
| 343 |
+
self,
|
| 344 |
+
images: Union[Image.Image, List[Image.Image], List[List[Image.Image]]],
|
| 345 |
+
do_pad: Optional[bool] = True,
|
| 346 |
+
max_slice_nums: int = None,
|
| 347 |
+
return_tensors: Optional[Union[str, TensorType]] = None,
|
| 348 |
+
**kwargs,
|
| 349 |
+
) -> MiniCPMOBatchFeature:
|
| 350 |
+
if isinstance(images, Image.Image):
|
| 351 |
+
images_list = [[images]]
|
| 352 |
+
elif isinstance(images[0], Image.Image):
|
| 353 |
+
images_list = [images]
|
| 354 |
+
else:
|
| 355 |
+
images_list = images
|
| 356 |
+
|
| 357 |
+
new_images_list = []
|
| 358 |
+
image_sizes_list = []
|
| 359 |
+
tgt_sizes_list = []
|
| 360 |
+
|
| 361 |
+
for _images in images_list:
|
| 362 |
+
if _images is None or len(_images) == 0:
|
| 363 |
+
new_images_list.append([])
|
| 364 |
+
image_sizes_list.append([])
|
| 365 |
+
tgt_sizes_list.append([])
|
| 366 |
+
continue
|
| 367 |
+
if not valid_images(_images):
|
| 368 |
+
raise ValueError(
|
| 369 |
+
"Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, "
|
| 370 |
+
"torch.Tensor, tf.Tensor or jax.ndarray."
|
| 371 |
+
)
|
| 372 |
+
|
| 373 |
+
_images = [self.to_pil_image(image).convert("RGB") for image in _images]
|
| 374 |
+
input_data_format = infer_channel_dimension_format(np.array(_images[0]))
|
| 375 |
+
|
| 376 |
+
new_images = []
|
| 377 |
+
image_sizes = [image.size for image in _images]
|
| 378 |
+
tgt_sizes = []
|
| 379 |
+
for image in _images:
|
| 380 |
+
image_patches = self.get_sliced_images(image, max_slice_nums)
|
| 381 |
+
image_patches = [to_numpy_array(image).astype(np.float32) / 255 for image in image_patches]
|
| 382 |
+
image_patches = [
|
| 383 |
+
self.normalize(image=image, mean=self.mean, std=self.std, input_data_format=input_data_format)
|
| 384 |
+
for image in image_patches
|
| 385 |
+
]
|
| 386 |
+
image_patches = [
|
| 387 |
+
to_channel_dimension_format(image, ChannelDimension.FIRST, input_channel_dim=input_data_format)
|
| 388 |
+
for image in image_patches
|
| 389 |
+
]
|
| 390 |
+
for slice_image in image_patches:
|
| 391 |
+
new_images.append(self.reshape_by_patch(slice_image))
|
| 392 |
+
tgt_sizes.append(
|
| 393 |
+
np.array((slice_image.shape[1] // self.patch_size, slice_image.shape[2] // self.patch_size))
|
| 394 |
+
)
|
| 395 |
+
|
| 396 |
+
if tgt_sizes:
|
| 397 |
+
tgt_sizes = np.vstack(tgt_sizes)
|
| 398 |
+
|
| 399 |
+
new_images_list.append(new_images)
|
| 400 |
+
image_sizes_list.append(image_sizes)
|
| 401 |
+
tgt_sizes_list.append(tgt_sizes)
|
| 402 |
+
return MiniCPMOBatchFeature(
|
| 403 |
+
data={"pixel_values": new_images_list, "image_sizes": image_sizes_list, "tgt_sizes": tgt_sizes_list},
|
| 404 |
+
tensor_type=return_tensors,
|
| 405 |
+
)
|
| 406 |
+
|
| 407 |
+
|
| 408 |
+
AutoImageProcessor.register("MiniCPMVImageProcessor", MiniCPMVImageProcessor)
|
| 409 |
+
|
| 410 |
+
|
| 411 |
+
def chunk_audio(audio: np.ndarray, max_duration_seconds: int = 30, sample_rate: int = 16000) -> List[np.ndarray]:
|
| 412 |
+
"""split long audio into chunks
|
| 413 |
+
|
| 414 |
+
Args:
|
| 415 |
+
audio:
|
| 416 |
+
max_duration_seconds:
|
| 417 |
+
sample_rate:
|
| 418 |
+
|
| 419 |
+
Returns:
|
| 420 |
+
chunks
|
| 421 |
+
"""
|
| 422 |
+
max_len = int(max_duration_seconds * sample_rate)
|
| 423 |
+
|
| 424 |
+
if len(audio) <= max_len:
|
| 425 |
+
return [audio]
|
| 426 |
+
|
| 427 |
+
chunks = []
|
| 428 |
+
for i in range(0, len(audio), max_len):
|
| 429 |
+
chunk = audio[i : i + max_len]
|
| 430 |
+
chunks.append(chunk)
|
| 431 |
+
|
| 432 |
+
return chunks
|
| 433 |
+
|
| 434 |
+
|
| 435 |
+
def process_audio_batch(
|
| 436 |
+
audios: Union[np.ndarray, List[np.ndarray], List[List[np.ndarray]]],
|
| 437 |
+
feature_extractor,
|
| 438 |
+
sampling_rate: int = 16000,
|
| 439 |
+
max_duration_seconds: int = 30,
|
| 440 |
+
return_attention_mask: bool = True,
|
| 441 |
+
) -> Tuple[torch.Tensor, List[torch.Tensor]]:
|
| 442 |
+
"""extract audio mel features
|
| 443 |
+
|
| 444 |
+
Args:
|
| 445 |
+
audios:
|
| 446 |
+
feature_extractor: WhisperFeatureExtractor
|
| 447 |
+
sampling_rate:
|
| 448 |
+
max_duration_seconds:
|
| 449 |
+
return_attention_mask:
|
| 450 |
+
|
| 451 |
+
Returns:
|
| 452 |
+
(audio_features, audio_feature_lens)
|
| 453 |
+
audio_features: [batch_size, n_mels, max_frames]
|
| 454 |
+
audio_feature_lens:
|
| 455 |
+
"""
|
| 456 |
+
if isinstance(audios, np.ndarray):
|
| 457 |
+
audios_list = [[audios]]
|
| 458 |
+
elif len(audios) > 0 and isinstance(audios[0], np.ndarray):
|
| 459 |
+
audios_list = [audios]
|
| 460 |
+
else:
|
| 461 |
+
audios_list = audios
|
| 462 |
+
|
| 463 |
+
audio_features_all = []
|
| 464 |
+
audio_feature_lens_list = []
|
| 465 |
+
|
| 466 |
+
for batch_audios in audios_list:
|
| 467 |
+
batch_lens = []
|
| 468 |
+
|
| 469 |
+
for audio in batch_audios:
|
| 470 |
+
chunks = chunk_audio(audio, max_duration_seconds, sampling_rate)
|
| 471 |
+
|
| 472 |
+
for chunk in chunks:
|
| 473 |
+
audio_input = feature_extractor(
|
| 474 |
+
chunk,
|
| 475 |
+
sampling_rate=sampling_rate,
|
| 476 |
+
return_tensors="pt",
|
| 477 |
+
padding="max_length",
|
| 478 |
+
return_attention_mask=return_attention_mask,
|
| 479 |
+
)
|
| 480 |
+
|
| 481 |
+
audio_feature = audio_input["input_features"] # [1, 80, frames]
|
| 482 |
+
|
| 483 |
+
if return_attention_mask:
|
| 484 |
+
actual_len = audio_input["attention_mask"].sum(dim=1) # Tensor([frames])
|
| 485 |
+
audio_feature = audio_feature[:, :, : actual_len[0]]
|
| 486 |
+
batch_lens.append(actual_len[0])
|
| 487 |
+
else:
|
| 488 |
+
batch_lens.append(torch.tensor(audio_feature.shape[2]))
|
| 489 |
+
|
| 490 |
+
audio_features_all.append(audio_feature.squeeze(0)) # [80, frames]
|
| 491 |
+
|
| 492 |
+
if len(batch_lens) > 0:
|
| 493 |
+
audio_feature_lens_list.append(torch.hstack(batch_lens))
|
| 494 |
+
else:
|
| 495 |
+
audio_feature_lens_list.append(torch.tensor([]))
|
| 496 |
+
|
| 497 |
+
# pad to same length
|
| 498 |
+
if audio_features_all:
|
| 499 |
+
audio_features = torch.nn.utils.rnn.pad_sequence(
|
| 500 |
+
[feat.transpose(0, 1) for feat in audio_features_all], batch_first=True, padding_value=0.0
|
| 501 |
+
).transpose(
|
| 502 |
+
1, 2
|
| 503 |
+
) # [batch, 80, max_frames]
|
| 504 |
+
else:
|
| 505 |
+
audio_features = torch.tensor([])
|
| 506 |
+
|
| 507 |
+
return audio_features, audio_feature_lens_list
|
| 508 |
+
|
| 509 |
+
|
| 510 |
+
def regroup_audio_features(
|
| 511 |
+
audio_features: torch.Tensor, audio_feature_lens: List[torch.Tensor], regroup_seconds: int, fps: int = 100
|
| 512 |
+
) -> Tuple[torch.Tensor, List[torch.Tensor]]:
|
| 513 |
+
"""regroup audio features to fixed duration
|
| 514 |
+
|
| 515 |
+
Args:
|
| 516 |
+
audio_features: [batch, n_mels, frames]
|
| 517 |
+
audio_feature_lens: each batch's actual length
|
| 518 |
+
regroup_seconds: regroup duration (seconds)
|
| 519 |
+
fps: frames per second
|
| 520 |
+
|
| 521 |
+
Returns:
|
| 522 |
+
(regrouped_features, regrouped_lens)
|
| 523 |
+
"""
|
| 524 |
+
# flatten to continuous frames sequence
|
| 525 |
+
all_lens = []
|
| 526 |
+
for lens in audio_feature_lens:
|
| 527 |
+
if isinstance(lens, torch.Tensor):
|
| 528 |
+
all_lens.extend(lens.tolist())
|
| 529 |
+
elif isinstance(lens, list):
|
| 530 |
+
all_lens.extend([int(x) for x in lens])
|
| 531 |
+
|
| 532 |
+
if len(all_lens) == 0:
|
| 533 |
+
return torch.tensor([]), []
|
| 534 |
+
|
| 535 |
+
# concatenate all valid features
|
| 536 |
+
flat_slices = [audio_features[i, :, :L] for i, L in enumerate(all_lens)] # [n_mels, L]
|
| 537 |
+
|
| 538 |
+
if len(flat_slices) == 1:
|
| 539 |
+
full_feat = flat_slices[0]
|
| 540 |
+
else:
|
| 541 |
+
full_feat = torch.cat(flat_slices, dim=1) # [n_mels, total_frames]
|
| 542 |
+
|
| 543 |
+
# split to fixed frames
|
| 544 |
+
frames_per_seg = int(regroup_seconds * fps)
|
| 545 |
+
segments = []
|
| 546 |
+
|
| 547 |
+
for start in range(0, full_feat.size(1), frames_per_seg):
|
| 548 |
+
seg = full_feat[:, start : start + frames_per_seg]
|
| 549 |
+
if seg.size(1) > 0:
|
| 550 |
+
segments.append(seg)
|
| 551 |
+
|
| 552 |
+
if len(segments) == 0:
|
| 553 |
+
return torch.tensor([]), []
|
| 554 |
+
|
| 555 |
+
# pad and convert to batch
|
| 556 |
+
seg_lens = [s.size(1) for s in segments]
|
| 557 |
+
segs_transposed = [s.transpose(0, 1) for s in segments]
|
| 558 |
+
|
| 559 |
+
padded = torch.nn.utils.rnn.pad_sequence(segs_transposed, batch_first=True, padding_value=0.0) # [N, max_T, n_mels]
|
| 560 |
+
|
| 561 |
+
padded = padded.transpose(1, 2) # [N, n_mels, max_T]
|
| 562 |
+
lens_tensor = torch.tensor(seg_lens, dtype=torch.int32, device=padded.device)
|
| 563 |
+
|
| 564 |
+
return padded, [lens_tensor]
|
| 565 |
+
|
| 566 |
+
|
| 567 |
+
class MiniCPMAAudioProcessor(WhisperFeatureExtractor):
|
| 568 |
+
"""
|
| 569 |
+
On top of WhisperFeatureExtractor:
|
| 570 |
+
- support dynamic_log_norm (original max-8dB, adjustable dynamic_range_db)
|
| 571 |
+
- or fixed log_floor_db (e.g. -10dB)
|
| 572 |
+
- this is because we need to do streaming scheme, in which we can't do dynamic setting
|
| 573 |
+
- this can be modified in the middle, through set_dynamic_log_norm
|
| 574 |
+
Two paths (torch / numpy) keep consistent clipping and scaling order:
|
| 575 |
+
log10 -> (dynamic/fixed lower limit clipping) -> (+4)/4
|
| 576 |
+
"""
|
| 577 |
+
|
| 578 |
+
def __init__(
|
| 579 |
+
self,
|
| 580 |
+
*args,
|
| 581 |
+
dynamic_log_norm: bool = True,
|
| 582 |
+
dynamic_range_db: float = 8.0,
|
| 583 |
+
log_floor_db: float = -10.0,
|
| 584 |
+
**kwargs,
|
| 585 |
+
):
|
| 586 |
+
super().__init__(*args, **kwargs)
|
| 587 |
+
self.dynamic_log_norm = bool(dynamic_log_norm)
|
| 588 |
+
self.dynamic_range_db = float(dynamic_range_db)
|
| 589 |
+
self.log_floor_db = float(log_floor_db)
|
| 590 |
+
|
| 591 |
+
def set_spac_log_norm(
|
| 592 |
+
self,
|
| 593 |
+
dynamic_range_db: Optional[float] = None,
|
| 594 |
+
log_floor_db: Optional[float] = None,
|
| 595 |
+
*,
|
| 596 |
+
inplace: bool = True,
|
| 597 |
+
) -> "MiniCPMAAudioProcessor":
|
| 598 |
+
"""Hot update dynamic/fixed lower limit strategy.
|
| 599 |
+
|
| 600 |
+
Args:
|
| 601 |
+
enabled: True=use dynamic threshold (max - dynamic_range_db), False=use fixed lower limit log_floor_db.
|
| 602 |
+
None means keep unchanged.
|
| 603 |
+
dynamic_range_db: dynamic range (dB), only effective when enabled=True. None means keep unchanged.
|
| 604 |
+
log_floor_db: fixed log floor (dB, usually <= 0), only effective when enabled=False. None means keep unchanged.
|
| 605 |
+
inplace: True directly modify current instance; False return a shallow copy and modify on it.
|
| 606 |
+
|
| 607 |
+
Returns:
|
| 608 |
+
self or new instance (when inplace=False).
|
| 609 |
+
"""
|
| 610 |
+
|
| 611 |
+
target = self if inplace else copy.copy(self)
|
| 612 |
+
|
| 613 |
+
if dynamic_range_db is not None:
|
| 614 |
+
val = float(dynamic_range_db)
|
| 615 |
+
if val < 0:
|
| 616 |
+
raise ValueError("dynamic_range_db must be >= 0.")
|
| 617 |
+
target.dynamic_log_norm = True # explicitly set the value to dynamic mode
|
| 618 |
+
target.dynamic_range_db = val
|
| 619 |
+
|
| 620 |
+
if log_floor_db is not None:
|
| 621 |
+
val = float(log_floor_db)
|
| 622 |
+
# usually log10(mel) maximum is not more than ~0dB, floor should be <= 0; here do loose validation
|
| 623 |
+
if val > 0:
|
| 624 |
+
raise ValueError("log_floor_db should be <= 0 (log10 scale).")
|
| 625 |
+
target.dynamic_log_norm = False # explicitly set the value to fixed lower limit mode
|
| 626 |
+
target.log_floor_db = val
|
| 627 |
+
|
| 628 |
+
return target
|
| 629 |
+
|
| 630 |
+
def _np_extract_fbank_features(self, waveform_batch: np.ndarray, device: str) -> np.ndarray:
|
| 631 |
+
"""NumPy version consistent with upstream, but replace max-8dB with configurable dynamic/fixed lower limit clipping."""
|
| 632 |
+
if device != "cpu":
|
| 633 |
+
raise ValueError(
|
| 634 |
+
f"Got device `{device}` for feature extraction, but feature extraction on CUDA accelerator "
|
| 635 |
+
"devices requires torch. Set device='cpu' or install torch."
|
| 636 |
+
)
|
| 637 |
+
|
| 638 |
+
log_spec_batch: List[np.ndarray] = []
|
| 639 |
+
for waveform in waveform_batch:
|
| 640 |
+
# generate log10 Mel
|
| 641 |
+
log_spec = spectrogram(
|
| 642 |
+
waveform,
|
| 643 |
+
window_function(self.n_fft, "hann"),
|
| 644 |
+
frame_length=self.n_fft,
|
| 645 |
+
hop_length=self.hop_length,
|
| 646 |
+
power=2.0,
|
| 647 |
+
dither=self.dither,
|
| 648 |
+
mel_filters=self.mel_filters,
|
| 649 |
+
log_mel="log10",
|
| 650 |
+
)
|
| 651 |
+
# consistent with upstream: remove the last frame
|
| 652 |
+
log_spec = log_spec[:, :-1]
|
| 653 |
+
|
| 654 |
+
# dynamic/fixed clipping
|
| 655 |
+
if self.dynamic_log_norm:
|
| 656 |
+
threshold = log_spec.max() - self.dynamic_range_db
|
| 657 |
+
log_spec = np.maximum(log_spec, threshold)
|
| 658 |
+
else:
|
| 659 |
+
log_spec = np.maximum(log_spec, self.log_floor_db)
|
| 660 |
+
|
| 661 |
+
# consistent with Whisper linear scaling
|
| 662 |
+
log_spec = (log_spec + 4.0) / 4.0
|
| 663 |
+
|
| 664 |
+
log_spec_batch.append(log_spec)
|
| 665 |
+
|
| 666 |
+
return np.array(log_spec_batch)
|
| 667 |
+
|
| 668 |
+
def _torch_extract_fbank_features(self, waveform: np.ndarray, device: str = "cpu") -> np.ndarray:
|
| 669 |
+
if torch is None:
|
| 670 |
+
raise RuntimeError("PyTorch is not installed, cannot compute STFT on GPU.")
|
| 671 |
+
|
| 672 |
+
waveform = torch.from_numpy(waveform).to(device, torch.float32)
|
| 673 |
+
window = torch.hann_window(self.n_fft, device=device)
|
| 674 |
+
|
| 675 |
+
if self.dither != 0.0:
|
| 676 |
+
waveform = waveform + self.dither * torch.randn_like(waveform)
|
| 677 |
+
|
| 678 |
+
stft = torch.stft(waveform, n_fft=self.n_fft, hop_length=self.hop_length, window=window, return_complex=True)
|
| 679 |
+
magnitudes = stft[..., :-1].abs() ** 2
|
| 680 |
+
|
| 681 |
+
mel_filters = torch.from_numpy(self.mel_filters).to(device, torch.float32) # [n_mels, 1+n_fft//2]
|
| 682 |
+
mel_spec = mel_filters.T @ magnitudes # [..., n_mels, T]
|
| 683 |
+
|
| 684 |
+
log_spec = torch.clamp(mel_spec, min=1e-10).log10() # <= 0
|
| 685 |
+
|
| 686 |
+
if self.dynamic_log_norm:
|
| 687 |
+
if waveform.dim() == 2:
|
| 688 |
+
max_val_t = log_spec.max(dim=2, keepdim=True)[0] # over T
|
| 689 |
+
max_val_bt = max_val_t.max(dim=1, keepdim=True)[0] # over mel
|
| 690 |
+
threshold = max_val_bt - self.dynamic_range_db
|
| 691 |
+
log_spec = torch.maximum(log_spec, threshold)
|
| 692 |
+
else:
|
| 693 |
+
threshold = log_spec.max() - self.dynamic_range_db
|
| 694 |
+
log_spec = torch.maximum(log_spec, threshold)
|
| 695 |
+
else:
|
| 696 |
+
floor_tensor = torch.tensor(self.log_floor_db, dtype=log_spec.dtype, device=log_spec.device)
|
| 697 |
+
log_spec = torch.maximum(log_spec, floor_tensor)
|
| 698 |
+
|
| 699 |
+
log_spec = (log_spec + 4.0) / 4.0
|
| 700 |
+
|
| 701 |
+
if device != "cpu":
|
| 702 |
+
log_spec = log_spec.detach().cpu()
|
| 703 |
+
return log_spec.numpy()
|
| 704 |
+
|
| 705 |
+
def process(self, *args, **kwargs):
|
| 706 |
+
"""Alias of __call__ for convenience."""
|
| 707 |
+
return self.__call__(*args, **kwargs)
|
| 708 |
+
|
| 709 |
+
|
| 710 |
+
class StreamingMelProcessorExact:
|
| 711 |
+
"""Strictly offline equivalent streaming Mel processor.
|
| 712 |
+
|
| 713 |
+
- accumulate all historical audio into buffer; use the same feature_extractor to calculate the entire mel after each addition.
|
| 714 |
+
- only output "stable" frames: the frame center does not depend on future (right) context, i.e. center + n_fft//2 <= current buffer length.
|
| 715 |
+
- output the last batch of frames at the end (flush), ensuring complete consistency with offline full-calculation.
|
| 716 |
+
|
| 717 |
+
Cost: Each call performs feature extraction on the accumulated buffer (can be optimized to incremental if needed).
|
| 718 |
+
"""
|
| 719 |
+
|
| 720 |
+
def __init__(
|
| 721 |
+
self,
|
| 722 |
+
feature_extractor: MiniCPMAAudioProcessor,
|
| 723 |
+
chunk_ms: int = 100,
|
| 724 |
+
first_chunk_ms: Optional[int] = None,
|
| 725 |
+
sample_rate: int = 16000,
|
| 726 |
+
n_fft: int = 400,
|
| 727 |
+
hop_length: int = 160,
|
| 728 |
+
n_mels: int = 80,
|
| 729 |
+
cnn_redundancy_ms: int = 10, # (given in ms, usually 10ms=1 frame)
|
| 730 |
+
# sliding window parameters
|
| 731 |
+
enable_sliding_window: bool = False, # whether to enable sliding window
|
| 732 |
+
slide_trigger_seconds: float = 30.0, # trigger threshold for sliding window in seconds
|
| 733 |
+
slide_stride_seconds: float = 10.0, # stride for sliding window in seconds
|
| 734 |
+
):
|
| 735 |
+
self.feature_extractor = feature_extractor
|
| 736 |
+
self.chunk_ms = chunk_ms
|
| 737 |
+
self.first_chunk_ms = first_chunk_ms if first_chunk_ms is not None else chunk_ms
|
| 738 |
+
self.sample_rate = sample_rate
|
| 739 |
+
self.n_fft = n_fft
|
| 740 |
+
self.hop_length = hop_length
|
| 741 |
+
self.n_mels = n_mels
|
| 742 |
+
|
| 743 |
+
self.chunk_samples = int(round(chunk_ms * sample_rate / 1000))
|
| 744 |
+
self.chunk_frames = self.chunk_samples // hop_length
|
| 745 |
+
# align to hop_length to avoid frame boundary issues
|
| 746 |
+
hop = self.hop_length
|
| 747 |
+
raw_first_samples = int(round(self.first_chunk_ms * sample_rate / 1000))
|
| 748 |
+
aligned_first = max(hop, (raw_first_samples // hop) * hop)
|
| 749 |
+
self.first_chunk_samples = aligned_first
|
| 750 |
+
self.half_window = n_fft // 2 # required right context
|
| 751 |
+
|
| 752 |
+
# redundancy frames (in frames), <=1 frame: 10ms → 1 frame
|
| 753 |
+
self.cnn_redundancy_ms = cnn_redundancy_ms
|
| 754 |
+
self.cnn_redundancy_samples = int(cnn_redundancy_ms * sample_rate / 1000)
|
| 755 |
+
self.cnn_redundancy_frames = max(0, self.cnn_redundancy_samples // hop_length)
|
| 756 |
+
|
| 757 |
+
# sliding window configuration (Trigger mode)
|
| 758 |
+
self.enable_sliding_window = enable_sliding_window
|
| 759 |
+
self.trigger_seconds = slide_trigger_seconds
|
| 760 |
+
self.slide_seconds = slide_stride_seconds
|
| 761 |
+
|
| 762 |
+
# shift/base (global frame coordinates)
|
| 763 |
+
self.left_samples_dropped = 0 # samples dropped from the left
|
| 764 |
+
self.base_T = 0 # index of the "global frame" corresponding to mel_full[:, :, 0]
|
| 765 |
+
|
| 766 |
+
self.reset()
|
| 767 |
+
|
| 768 |
+
def reset(self):
|
| 769 |
+
self.buffer = np.zeros(0, dtype=np.float32)
|
| 770 |
+
self.last_emitted_T = 0
|
| 771 |
+
self.total_samples_processed = 0
|
| 772 |
+
self.chunk_count = 0
|
| 773 |
+
self.is_first = True
|
| 774 |
+
self.left_samples_dropped = 0
|
| 775 |
+
self.base_T = 0
|
| 776 |
+
|
| 777 |
+
def get_chunk_size(self) -> int:
|
| 778 |
+
return self.first_chunk_samples if self.is_first else self.chunk_samples
|
| 779 |
+
|
| 780 |
+
def get_expected_output_frames(self) -> int:
|
| 781 |
+
raise NotImplementedError("get_expected_output_frames is not implemented")
|
| 782 |
+
|
| 783 |
+
def _extract_full(self) -> torch.Tensor:
|
| 784 |
+
# when buffer length is less than n_fft, Whisper's internal STFT will raise an error in center=True and pad mode
|
| 785 |
+
# (pad is greater than input length). At this time, there is no stable frame to output, so return empty features directly.
|
| 786 |
+
if len(self.buffer) < self.n_fft:
|
| 787 |
+
raise ValueError(f"buffer length is shorter than n_fft {len(self.buffer)} < {self.n_fft}")
|
| 788 |
+
# if buffer length is less than 5s, use set_spac_log_norm(log_floor_db=-10) or the last cached result
|
| 789 |
+
if len(self.buffer) < 5 * self.sample_rate:
|
| 790 |
+
# TODO: here the best is to do some experiments to choose the best one, now this is selected through experience, can see MiniCPMAAudioProcessor's main implementation
|
| 791 |
+
self.feature_extractor.set_spac_log_norm(log_floor_db=-10)
|
| 792 |
+
# if buffer length is greater than 5s, use set_spac_log_norm(dynamic_range_db=8)
|
| 793 |
+
else:
|
| 794 |
+
self.feature_extractor.set_spac_log_norm(dynamic_range_db=8)
|
| 795 |
+
feats = self.feature_extractor(
|
| 796 |
+
self.buffer,
|
| 797 |
+
sampling_rate=self.sample_rate,
|
| 798 |
+
return_tensors="pt",
|
| 799 |
+
padding=False,
|
| 800 |
+
)
|
| 801 |
+
return feats.input_features # [1, 80, T]
|
| 802 |
+
|
| 803 |
+
def _stable_frames_count(self) -> int:
|
| 804 |
+
# number of stable frames = floor((len(buffer) - half_window) / hop) + 1, minimum is 0
|
| 805 |
+
L = int(self.buffer.shape[0])
|
| 806 |
+
if L <= 0:
|
| 807 |
+
return 0
|
| 808 |
+
if L < self.half_window:
|
| 809 |
+
return 0
|
| 810 |
+
return max(0, (L - self.half_window) // self.hop_length + 1)
|
| 811 |
+
|
| 812 |
+
def _maybe_slide_buffer(self):
|
| 813 |
+
"""Trigger mode sliding window: when the buffer reaches the trigger threshold, slide a fixed length window."""
|
| 814 |
+
if not self.enable_sliding_window:
|
| 815 |
+
return
|
| 816 |
+
|
| 817 |
+
sr = self.sample_rate
|
| 818 |
+
hop = self.hop_length
|
| 819 |
+
L = len(self.buffer)
|
| 820 |
+
|
| 821 |
+
# convert seconds to samples
|
| 822 |
+
trigger_samples = int(self.trigger_seconds * sr)
|
| 823 |
+
stride_samples = int(self.slide_seconds * sr)
|
| 824 |
+
|
| 825 |
+
# check if the trigger threshold is reached
|
| 826 |
+
if L < trigger_samples:
|
| 827 |
+
return
|
| 828 |
+
|
| 829 |
+
# calculate the number of samples to drop (fixed sliding stride_samples)
|
| 830 |
+
drop = stride_samples
|
| 831 |
+
|
| 832 |
+
# cannot drop the left context that is still needed for subsequent emission
|
| 833 |
+
# in trigger mode, we only need to protect the minimum necessary data
|
| 834 |
+
# i.e. ensure that we do not discard frames that may be needed in the future
|
| 835 |
+
last_emitted_local = self.last_emitted_T - self.base_T
|
| 836 |
+
|
| 837 |
+
# only protect necessary context (e.g. the most recent 1 second data)
|
| 838 |
+
min_keep_seconds = 1.0 # keep at least 1 second of data to ensure continuity
|
| 839 |
+
min_keep_samples = int(min_keep_seconds * sr)
|
| 840 |
+
|
| 841 |
+
# guard_samples are the minimum samples we must keep
|
| 842 |
+
guard_samples = min(min_keep_samples, L - drop)
|
| 843 |
+
|
| 844 |
+
# limit: do not exceed the safe boundary; and align hop
|
| 845 |
+
max_allowed_drop = max(0, L - guard_samples)
|
| 846 |
+
drop = min(drop, max_allowed_drop)
|
| 847 |
+
drop = (drop // hop) * hop
|
| 848 |
+
|
| 849 |
+
if drop <= 0:
|
| 850 |
+
return
|
| 851 |
+
|
| 852 |
+
# truly drop & update base
|
| 853 |
+
self.buffer = self.buffer[drop:]
|
| 854 |
+
self.left_samples_dropped += drop
|
| 855 |
+
self.base_T += drop // hop
|
| 856 |
+
|
| 857 |
+
def process(self, audio_chunk: np.ndarray, is_last_chunk: bool = False) -> Tuple[torch.Tensor, Dict]:
|
| 858 |
+
self.chunk_count += 1
|
| 859 |
+
# append to buffer
|
| 860 |
+
if len(self.buffer) == 0:
|
| 861 |
+
self.buffer = audio_chunk.astype(np.float32, copy=True)
|
| 862 |
+
else:
|
| 863 |
+
self.buffer = np.concatenate([self.buffer, audio_chunk.astype(np.float32, copy=True)])
|
| 864 |
+
|
| 865 |
+
# sliding window processing
|
| 866 |
+
self._maybe_slide_buffer()
|
| 867 |
+
|
| 868 |
+
# full extraction (for the current window)
|
| 869 |
+
mel_full = self._extract_full()
|
| 870 |
+
T_full = mel_full.shape[-1] # local frames in the current window
|
| 871 |
+
stable_T = min(T_full, self._stable_frames_count()) # local stable frames
|
| 872 |
+
stable_T_global = self.base_T + stable_T # map to global frame coordinates
|
| 873 |
+
|
| 874 |
+
# plan the core frames for the current emission (global coordinates)
|
| 875 |
+
core_start_g = self.last_emitted_T
|
| 876 |
+
core_end_g = core_start_g + self.chunk_frames
|
| 877 |
+
required_stable_g = core_end_g + self.cnn_redundancy_frames
|
| 878 |
+
|
| 879 |
+
if stable_T_global >= required_stable_g or is_last_chunk:
|
| 880 |
+
emit_start_g = max(0, core_start_g - self.cnn_redundancy_frames)
|
| 881 |
+
emit_end_g = core_end_g + self.cnn_redundancy_frames
|
| 882 |
+
|
| 883 |
+
# global -> local index
|
| 884 |
+
emit_start = max(0, emit_start_g - self.base_T)
|
| 885 |
+
emit_end = emit_end_g - self.base_T
|
| 886 |
+
emit_start = max(0, min(emit_start, T_full))
|
| 887 |
+
emit_end = max(emit_start, min(emit_end, T_full))
|
| 888 |
+
|
| 889 |
+
mel_output = mel_full[:, :, emit_start:emit_end]
|
| 890 |
+
self.last_emitted_T = core_end_g # only advance the core frame pointer (global)
|
| 891 |
+
else:
|
| 892 |
+
mel_output = mel_full[:, :, 0:0]
|
| 893 |
+
|
| 894 |
+
self.total_samples_processed += len(audio_chunk)
|
| 895 |
+
self.is_first = False
|
| 896 |
+
|
| 897 |
+
info = {
|
| 898 |
+
"type": "exact_chunk",
|
| 899 |
+
"chunk_number": self.chunk_count,
|
| 900 |
+
"emitted_frames": mel_output.shape[-1],
|
| 901 |
+
"stable_T": stable_T,
|
| 902 |
+
"T_full": T_full,
|
| 903 |
+
"base_T": self.base_T,
|
| 904 |
+
"stable_T_global": stable_T_global,
|
| 905 |
+
"buffer_len_samples": int(self.buffer.shape[0]),
|
| 906 |
+
"left_samples_dropped": self.left_samples_dropped,
|
| 907 |
+
"core_start": core_start_g, # if keep the original field name, use the global value here
|
| 908 |
+
"core_end": core_end_g, # same as above
|
| 909 |
+
}
|
| 910 |
+
return mel_output, info
|
| 911 |
+
|
| 912 |
+
def flush(self) -> torch.Tensor:
|
| 913 |
+
"""Called when the stream ends, output the remaining unemitted frames, ensuring consistency with offline (calculated by global coordinates)."""
|
| 914 |
+
if len(self.buffer) == 0:
|
| 915 |
+
return torch.zeros(1, 80, 0)
|
| 916 |
+
|
| 917 |
+
mel_full = self._extract_full()
|
| 918 |
+
T_local = mel_full.shape[-1]
|
| 919 |
+
T_global = self.base_T + T_local
|
| 920 |
+
|
| 921 |
+
if self.last_emitted_T < T_global:
|
| 922 |
+
start_l = max(0, self.last_emitted_T - self.base_T)
|
| 923 |
+
tail = mel_full[:, :, start_l:]
|
| 924 |
+
self.last_emitted_T = T_global
|
| 925 |
+
return tail
|
| 926 |
+
return mel_full[:, :, 0:0]
|
| 927 |
+
|
| 928 |
+
def get_config(self) -> Dict:
|
| 929 |
+
return {
|
| 930 |
+
"chunk_ms": self.chunk_ms,
|
| 931 |
+
"first_chunk_ms": self.first_chunk_ms,
|
| 932 |
+
"effective_first_chunk_ms": self.first_chunk_samples / self.sample_rate * 1000.0,
|
| 933 |
+
"sample_rate": self.sample_rate,
|
| 934 |
+
"n_fft": self.n_fft,
|
| 935 |
+
"hop_length": self.hop_length,
|
| 936 |
+
"cnn_redundancy_ms": self.cnn_redundancy_ms,
|
| 937 |
+
"cnn_redundancy_frames": self.cnn_redundancy_frames,
|
| 938 |
+
"enable_sliding_window": self.enable_sliding_window,
|
| 939 |
+
"trigger_seconds": self.trigger_seconds,
|
| 940 |
+
"slide_seconds": self.slide_seconds,
|
| 941 |
+
}
|
| 942 |
+
|
| 943 |
+
def get_state(self) -> Dict:
|
| 944 |
+
return {
|
| 945 |
+
"chunk_count": self.chunk_count,
|
| 946 |
+
"last_emitted_T": self.last_emitted_T,
|
| 947 |
+
"total_samples_processed": self.total_samples_processed,
|
| 948 |
+
"buffer_len": int(self.buffer.shape[0]),
|
| 949 |
+
"base_T": self.base_T,
|
| 950 |
+
"left_samples_dropped": self.left_samples_dropped,
|
| 951 |
+
}
|
| 952 |
+
|
| 953 |
+
def get_snapshot(self) -> Dict:
|
| 954 |
+
"""Get a complete state snapshot (including buffer), used for recovery from a fast start.
|
| 955 |
+
|
| 956 |
+
Returns:
|
| 957 |
+
A dictionary containing the complete state, which can be used to restore the snapshot
|
| 958 |
+
"""
|
| 959 |
+
buffer_copy = self.buffer.copy()
|
| 960 |
+
snapshot = {
|
| 961 |
+
"chunk_count": self.chunk_count,
|
| 962 |
+
"last_emitted_T": self.last_emitted_T,
|
| 963 |
+
"total_samples_processed": self.total_samples_processed,
|
| 964 |
+
"buffer": buffer_copy,
|
| 965 |
+
"base_T": self.base_T,
|
| 966 |
+
"left_samples_dropped": self.left_samples_dropped,
|
| 967 |
+
"is_first": self.is_first,
|
| 968 |
+
# save the state of the feature_extractor (key: ensure determinism of mel feature extraction)
|
| 969 |
+
"fe_dynamic_log_norm": getattr(self.feature_extractor, "dynamic_log_norm", None),
|
| 970 |
+
"fe_dynamic_range_db": getattr(self.feature_extractor, "dynamic_range_db", None),
|
| 971 |
+
"fe_log_floor_db": getattr(self.feature_extractor, "log_floor_db", None),
|
| 972 |
+
}
|
| 973 |
+
|
| 974 |
+
return snapshot
|
| 975 |
+
|
| 976 |
+
def restore_snapshot(self, snapshot: Dict) -> None:
|
| 977 |
+
"""Restore state from a snapshot
|
| 978 |
+
|
| 979 |
+
Args:
|
| 980 |
+
snapshot: the snapshot dictionary returned by get_snapshot
|
| 981 |
+
"""
|
| 982 |
+
# record the state before restoration
|
| 983 |
+
prev_state = {
|
| 984 |
+
"chunk_count": self.chunk_count,
|
| 985 |
+
"last_emitted_T": self.last_emitted_T,
|
| 986 |
+
"buffer_len": len(self.buffer),
|
| 987 |
+
}
|
| 988 |
+
|
| 989 |
+
# restore state
|
| 990 |
+
self.chunk_count = snapshot["chunk_count"]
|
| 991 |
+
self.last_emitted_T = snapshot["last_emitted_T"]
|
| 992 |
+
self.total_samples_processed = snapshot["total_samples_processed"]
|
| 993 |
+
self.buffer = snapshot["buffer"].copy() # copy buffer
|
| 994 |
+
self.base_T = snapshot["base_T"]
|
| 995 |
+
self.left_samples_dropped = snapshot["left_samples_dropped"]
|
| 996 |
+
self.is_first = snapshot["is_first"]
|
| 997 |
+
|
| 998 |
+
# restore the state of the feature_extractor (key: ensure determinism of mel feature extraction)
|
| 999 |
+
if snapshot.get("fe_dynamic_log_norm") is not None:
|
| 1000 |
+
self.feature_extractor.dynamic_log_norm = snapshot["fe_dynamic_log_norm"]
|
| 1001 |
+
if snapshot.get("fe_dynamic_range_db") is not None:
|
| 1002 |
+
self.feature_extractor.dynamic_range_db = snapshot["fe_dynamic_range_db"]
|
| 1003 |
+
if snapshot.get("fe_log_floor_db") is not None:
|
| 1004 |
+
self.feature_extractor.log_floor_db = snapshot["fe_log_floor_db"]
|
| 1005 |
+
|
| 1006 |
+
|
| 1007 |
+
class MiniCPMOProcessor(ProcessorMixin):
|
| 1008 |
+
attributes = ["image_processor", "audio_processor", "tokenizer"]
|
| 1009 |
+
audio_processor_class = "AutoFeatureExtractor"
|
| 1010 |
+
image_processor_class = "AutoImageProcessor"
|
| 1011 |
+
tokenizer_class = "AutoTokenizer"
|
| 1012 |
+
|
| 1013 |
+
def __init__(self, image_processor=None, audio_processor=None, tokenizer=None, **kwargs):
|
| 1014 |
+
super().__init__(image_processor, audio_processor, tokenizer)
|
| 1015 |
+
|
| 1016 |
+
self.version = image_processor.version if image_processor else None
|
| 1017 |
+
# audio feature pooling step, needs to be consistent with config.audio_pool_step
|
| 1018 |
+
self.pool_step = kwargs.get("audio_pool_step", 5)
|
| 1019 |
+
|
| 1020 |
+
# initialize the streaming audio processor
|
| 1021 |
+
self._streaming_mel_processor = None
|
| 1022 |
+
if audio_processor is not None:
|
| 1023 |
+
self._init_streaming_processor()
|
| 1024 |
+
|
| 1025 |
+
def get_audio_placeholder(
|
| 1026 |
+
self,
|
| 1027 |
+
audio_lens: int,
|
| 1028 |
+
chunk_input: bool = True,
|
| 1029 |
+
chunk_length: int = 1,
|
| 1030 |
+
) -> str:
|
| 1031 |
+
"""
|
| 1032 |
+
Public method to get audio placeholder string for vLLM integration.
|
| 1033 |
+
|
| 1034 |
+
Args:
|
| 1035 |
+
audio_lens: Length of audio in samples
|
| 1036 |
+
chunk_input: Whether to use chunked processing
|
| 1037 |
+
chunk_length: Chunk length in seconds
|
| 1038 |
+
|
| 1039 |
+
Returns:
|
| 1040 |
+
Audio placeholder string
|
| 1041 |
+
"""
|
| 1042 |
+
pool_step = self.pool_step
|
| 1043 |
+
feature_lens = math.ceil(audio_lens / self.audio_processor.hop_length)
|
| 1044 |
+
|
| 1045 |
+
feature_lens = (feature_lens - 1) // 2 + 1
|
| 1046 |
+
output_lens = (feature_lens - pool_step) // pool_step + 1
|
| 1047 |
+
|
| 1048 |
+
if chunk_input:
|
| 1049 |
+
fbank_feat_in_chunk = int(chunk_length * 100)
|
| 1050 |
+
cnn_feat_in_chunk = (fbank_feat_in_chunk - 1) // 2 + 1
|
| 1051 |
+
audio_embeds_in_chunk = (cnn_feat_in_chunk - pool_step) // pool_step + 1
|
| 1052 |
+
num_audio_chunks = (output_lens + audio_embeds_in_chunk - 1) // audio_embeds_in_chunk
|
| 1053 |
+
|
| 1054 |
+
place_holders = ""
|
| 1055 |
+
total_unk_len = 0
|
| 1056 |
+
for _ in range(num_audio_chunks):
|
| 1057 |
+
unk_len = min(audio_embeds_in_chunk, output_lens - total_unk_len)
|
| 1058 |
+
place_holders += self.tokenizer.audio_start + "<unk>" * unk_len + self.tokenizer.audio_end
|
| 1059 |
+
total_unk_len += unk_len
|
| 1060 |
+
audio_placeholder = place_holders
|
| 1061 |
+
else:
|
| 1062 |
+
audio_placeholder = self.tokenizer.audio_start + "<unk>" * output_lens + self.tokenizer.audio_end
|
| 1063 |
+
|
| 1064 |
+
return audio_placeholder
|
| 1065 |
+
|
| 1066 |
+
def _init_streaming_processor(
|
| 1067 |
+
self,
|
| 1068 |
+
chunk_ms: int = 100,
|
| 1069 |
+
cnn_redundancy_ms: int = 0,
|
| 1070 |
+
*,
|
| 1071 |
+
mode: str = "exact",
|
| 1072 |
+
first_chunk_ms: Optional[int] = None,
|
| 1073 |
+
enable_sliding_window: bool = False,
|
| 1074 |
+
slide_trigger_seconds: float = 30.0,
|
| 1075 |
+
slide_stride_seconds: float = 10.0,
|
| 1076 |
+
):
|
| 1077 |
+
"""Initialize the streaming processor
|
| 1078 |
+
|
| 1079 |
+
Args:
|
| 1080 |
+
chunk_ms: Chunk size in milliseconds, also the sliding step.
|
| 1081 |
+
cnn_redundancy_ms: CNN boundary redundancy in milliseconds (before and after), 0 means standard mode.
|
| 1082 |
+
mode: streaming processing mode, currently only supports "exact"
|
| 1083 |
+
first_chunk_ms: the size of the first chunk (milliseconds), if not specified, it is the same as chunk_ms
|
| 1084 |
+
enable_sliding_window: whether to enable sliding window (trigger mode)
|
| 1085 |
+
slide_trigger_seconds: trigger threshold for sliding window in seconds
|
| 1086 |
+
slide_stride_seconds: stride for sliding window in seconds
|
| 1087 |
+
"""
|
| 1088 |
+
if mode == "exact":
|
| 1089 |
+
self._streaming_mel_processor = StreamingMelProcessorExact(
|
| 1090 |
+
feature_extractor=self.audio_processor,
|
| 1091 |
+
chunk_ms=chunk_ms,
|
| 1092 |
+
first_chunk_ms=first_chunk_ms,
|
| 1093 |
+
sample_rate=16000,
|
| 1094 |
+
cnn_redundancy_ms=cnn_redundancy_ms,
|
| 1095 |
+
enable_sliding_window=enable_sliding_window,
|
| 1096 |
+
slide_trigger_seconds=slide_trigger_seconds,
|
| 1097 |
+
slide_stride_seconds=slide_stride_seconds,
|
| 1098 |
+
)
|
| 1099 |
+
else:
|
| 1100 |
+
raise ValueError(f"Unsupported mode: {mode}, only 'exact' is supported")
|
| 1101 |
+
self._streaming_mode = mode if mode in ["exact"] else ("exact")
|
| 1102 |
+
|
| 1103 |
+
def set_streaming_mode(
|
| 1104 |
+
self,
|
| 1105 |
+
mode: str = "exact",
|
| 1106 |
+
chunk_ms: int = 100,
|
| 1107 |
+
cnn_redundancy_ms: int = 0,
|
| 1108 |
+
*,
|
| 1109 |
+
first_chunk_ms: Optional[int] = None,
|
| 1110 |
+
enable_sliding_window: bool = False,
|
| 1111 |
+
slide_trigger_seconds: float = 30.0,
|
| 1112 |
+
slide_stride_seconds: float = 10.0,
|
| 1113 |
+
):
|
| 1114 |
+
"""Set streaming processing mode
|
| 1115 |
+
|
| 1116 |
+
Args:
|
| 1117 |
+
mode: streaming processing mode, currently only supports "exact"
|
| 1118 |
+
chunk_ms: chunk size in milliseconds, also the sliding step.
|
| 1119 |
+
cnn_redundancy_ms: CNN boundary redundancy in milliseconds (before and after), 0 means standard mode.
|
| 1120 |
+
first_chunk_ms: the size of the first chunk (milliseconds), if not specified, it is the same as chunk_ms
|
| 1121 |
+
enable_sliding_window: whether to enable sliding window (trigger mode)
|
| 1122 |
+
slide_trigger_seconds: trigger threshold for sliding window in seconds
|
| 1123 |
+
slide_stride_seconds: stride for sliding window in seconds
|
| 1124 |
+
"""
|
| 1125 |
+
if self.audio_processor is None:
|
| 1126 |
+
raise ValueError("audio_processor is not set, cannot initialize the streaming processor")
|
| 1127 |
+
self._init_streaming_processor(
|
| 1128 |
+
chunk_ms=chunk_ms,
|
| 1129 |
+
cnn_redundancy_ms=cnn_redundancy_ms,
|
| 1130 |
+
mode=mode,
|
| 1131 |
+
first_chunk_ms=first_chunk_ms,
|
| 1132 |
+
enable_sliding_window=enable_sliding_window,
|
| 1133 |
+
slide_trigger_seconds=slide_trigger_seconds,
|
| 1134 |
+
slide_stride_seconds=slide_stride_seconds,
|
| 1135 |
+
)
|
| 1136 |
+
|
| 1137 |
+
def process_image(
|
| 1138 |
+
self,
|
| 1139 |
+
images: Optional[ImageInput] = None,
|
| 1140 |
+
do_pad: bool = True,
|
| 1141 |
+
max_slice_nums: int = 1,
|
| 1142 |
+
return_tensors: str = "pt",
|
| 1143 |
+
) -> MiniCPMOBatchFeature:
|
| 1144 |
+
"""Process image data
|
| 1145 |
+
|
| 1146 |
+
Args:
|
| 1147 |
+
images: input images
|
| 1148 |
+
do_pad: whether to pad
|
| 1149 |
+
max_slice_nums: maximum number of slices
|
| 1150 |
+
return_tensors: return tensor type
|
| 1151 |
+
Returns:
|
| 1152 |
+
MiniCPMOBatchFeature object
|
| 1153 |
+
"""
|
| 1154 |
+
if images is None:
|
| 1155 |
+
return MiniCPMOBatchFeature(data={"pixel_values": [[]], "image_sizes": [[]], "tgt_sizes": [[]]})
|
| 1156 |
+
|
| 1157 |
+
result = self.image_processor(
|
| 1158 |
+
images, do_pad=do_pad, max_slice_nums=max_slice_nums, return_tensors=return_tensors
|
| 1159 |
+
)
|
| 1160 |
+
|
| 1161 |
+
model_inputs = {
|
| 1162 |
+
"pixel_values": result.get("pixel_values", [[]]),
|
| 1163 |
+
"image_sizes": result.get("image_sizes", [[]]),
|
| 1164 |
+
"tgt_sizes": result.get("tgt_sizes", [[]]),
|
| 1165 |
+
}
|
| 1166 |
+
|
| 1167 |
+
return MiniCPMOBatchFeature(data=model_inputs)
|
| 1168 |
+
|
| 1169 |
+
def process_audio(
|
| 1170 |
+
self,
|
| 1171 |
+
audios: Optional[Union[np.ndarray, List[np.ndarray]]] = None,
|
| 1172 |
+
sampling_rate: int = 16000,
|
| 1173 |
+
regroup_to_seconds: Optional[int] = None,
|
| 1174 |
+
fps: int = 100,
|
| 1175 |
+
) -> MiniCPMOBatchFeature:
|
| 1176 |
+
"""Process audio data in batch
|
| 1177 |
+
|
| 1178 |
+
Args:
|
| 1179 |
+
audios: audio data
|
| 1180 |
+
sampling_rate: sampling rate
|
| 1181 |
+
regroup_to_seconds: regroup duration in seconds
|
| 1182 |
+
fps: frames per second
|
| 1183 |
+
Returns:
|
| 1184 |
+
MiniCPMOBatchFeature object
|
| 1185 |
+
"""
|
| 1186 |
+
if audios is None:
|
| 1187 |
+
return MiniCPMOBatchFeature(data={"audio_features": [], "audio_feature_lens": []})
|
| 1188 |
+
|
| 1189 |
+
audio_features, audio_feature_lens = process_audio_batch(
|
| 1190 |
+
audios=audios,
|
| 1191 |
+
feature_extractor=self.audio_processor,
|
| 1192 |
+
sampling_rate=sampling_rate,
|
| 1193 |
+
max_duration_seconds=30,
|
| 1194 |
+
return_attention_mask=True,
|
| 1195 |
+
)
|
| 1196 |
+
|
| 1197 |
+
if regroup_to_seconds is not None and len(audio_features) > 0:
|
| 1198 |
+
audio_features, audio_feature_lens = regroup_audio_features(
|
| 1199 |
+
audio_features=audio_features,
|
| 1200 |
+
audio_feature_lens=audio_feature_lens,
|
| 1201 |
+
regroup_seconds=regroup_to_seconds,
|
| 1202 |
+
fps=fps,
|
| 1203 |
+
)
|
| 1204 |
+
|
| 1205 |
+
model_inputs = {"audio_features": audio_features, "audio_feature_lens": audio_feature_lens}
|
| 1206 |
+
|
| 1207 |
+
return MiniCPMOBatchFeature(data=model_inputs)
|
| 1208 |
+
|
| 1209 |
+
def process_audio_streaming(
|
| 1210 |
+
self,
|
| 1211 |
+
audio_chunk: np.ndarray,
|
| 1212 |
+
reset: bool = False,
|
| 1213 |
+
return_batch_feature: bool = False,
|
| 1214 |
+
is_last_chunk: bool = False,
|
| 1215 |
+
) -> Union[Tuple[torch.Tensor, dict], MiniCPMOBatchFeature]:
|
| 1216 |
+
"""Process audio chunk in streaming
|
| 1217 |
+
|
| 1218 |
+
Args:
|
| 1219 |
+
audio_chunk: audio data chunk (any audio, e.g. first process 125ms, then process 100ms)
|
| 1220 |
+
reset: whether to reset the processor state
|
| 1221 |
+
return_batch_feature: whether to return MiniCPMOBatchFeature format (consistent with process_audio)
|
| 1222 |
+
Returns:
|
| 1223 |
+
If return_batch_feature=False:
|
| 1224 |
+
(audio_features, info)
|
| 1225 |
+
- audio_features: [1, 80, n_frames] mel features
|
| 1226 |
+
- info: processing information dictionary
|
| 1227 |
+
If return_batch_feature=True:
|
| 1228 |
+
MiniCPMOBatchFeature object, containing:
|
| 1229 |
+
- audio_features: [1, 80, n_frames] mel features
|
| 1230 |
+
- audio_feature_lens: [tensor([n_frames])]
|
| 1231 |
+
- info: processing information (as an extra attribute)
|
| 1232 |
+
"""
|
| 1233 |
+
if self._streaming_mel_processor is None:
|
| 1234 |
+
raise ValueError("Streaming processor not initialized, please ensure audio_processor is set")
|
| 1235 |
+
|
| 1236 |
+
if reset:
|
| 1237 |
+
self._streaming_mel_processor.reset()
|
| 1238 |
+
|
| 1239 |
+
# process chunk
|
| 1240 |
+
mel_features, info = self._streaming_mel_processor.process(audio_chunk, is_last_chunk=is_last_chunk)
|
| 1241 |
+
|
| 1242 |
+
# determine the return format based on the parameters
|
| 1243 |
+
if return_batch_feature:
|
| 1244 |
+
# return the format consistent with process_audio
|
| 1245 |
+
# note: info returns emitted_frames, which represents the actual output frames
|
| 1246 |
+
n_frames = info.get("emitted_frames", mel_features.shape[-1])
|
| 1247 |
+
model_inputs = {
|
| 1248 |
+
"audio_features": mel_features,
|
| 1249 |
+
"audio_feature_lens": [torch.tensor([n_frames])],
|
| 1250 |
+
"streaming_info": info, # add streaming processing information
|
| 1251 |
+
}
|
| 1252 |
+
return MiniCPMOBatchFeature(data=model_inputs)
|
| 1253 |
+
else:
|
| 1254 |
+
return mel_features, info
|
| 1255 |
+
|
| 1256 |
+
def reset_streaming(self):
|
| 1257 |
+
if self._streaming_mel_processor is not None:
|
| 1258 |
+
self._streaming_mel_processor.reset()
|
| 1259 |
+
|
| 1260 |
+
def get_streaming_chunk_size(self) -> int:
|
| 1261 |
+
if self._streaming_mel_processor is None:
|
| 1262 |
+
raise ValueError("Streaming processor not initialized")
|
| 1263 |
+
return self._streaming_mel_processor.get_chunk_size()
|
| 1264 |
+
|
| 1265 |
+
def configure_streaming(
|
| 1266 |
+
self,
|
| 1267 |
+
chunk_ms: int = 100,
|
| 1268 |
+
enable_sliding_window: bool = False,
|
| 1269 |
+
slide_trigger_seconds: float = 30.0,
|
| 1270 |
+
slide_stride_seconds: float = 10.0,
|
| 1271 |
+
):
|
| 1272 |
+
"""Configure streaming processor parameters
|
| 1273 |
+
|
| 1274 |
+
Args:
|
| 1275 |
+
chunk_ms: chunk size in milliseconds
|
| 1276 |
+
enable_sliding_window: whether to enable sliding window (trigger mode)
|
| 1277 |
+
slide_trigger_seconds: trigger threshold for sliding window in seconds
|
| 1278 |
+
slide_stride_seconds: stride for sliding window in seconds
|
| 1279 |
+
"""
|
| 1280 |
+
if self.audio_processor is None:
|
| 1281 |
+
raise ValueError("audio_processor is not set")
|
| 1282 |
+
|
| 1283 |
+
self._init_streaming_processor(
|
| 1284 |
+
chunk_ms=chunk_ms,
|
| 1285 |
+
enable_sliding_window=enable_sliding_window,
|
| 1286 |
+
slide_trigger_seconds=slide_trigger_seconds,
|
| 1287 |
+
slide_stride_seconds=slide_stride_seconds,
|
| 1288 |
+
)
|
| 1289 |
+
|
| 1290 |
+
def get_streaming_config(self) -> dict:
|
| 1291 |
+
if self._streaming_mel_processor is None:
|
| 1292 |
+
return {}
|
| 1293 |
+
return self._streaming_mel_processor.get_config()
|
| 1294 |
+
|
| 1295 |
+
def get_streaming_state(self) -> dict:
|
| 1296 |
+
if self._streaming_mel_processor is None:
|
| 1297 |
+
return {}
|
| 1298 |
+
return self._streaming_mel_processor.get_state()
|
| 1299 |
+
|
| 1300 |
+
def get_streaming_snapshot(self) -> dict:
|
| 1301 |
+
if self._streaming_mel_processor is None:
|
| 1302 |
+
return {}
|
| 1303 |
+
return self._streaming_mel_processor.get_snapshot()
|
| 1304 |
+
|
| 1305 |
+
def restore_streaming_snapshot(self, snapshot: dict) -> None:
|
| 1306 |
+
if self._streaming_mel_processor is None:
|
| 1307 |
+
return
|
| 1308 |
+
if not snapshot:
|
| 1309 |
+
return
|
| 1310 |
+
self._streaming_mel_processor.restore_snapshot(snapshot)
|
| 1311 |
+
|
| 1312 |
+
def __call__(
|
| 1313 |
+
self,
|
| 1314 |
+
text: Union[TextInput, PreTokenizedInput, List[TextInput], List[PreTokenizedInput]],
|
| 1315 |
+
images: ImageInput = None,
|
| 1316 |
+
audios: Union[np.ndarray, List[np.ndarray], List[List[np.ndarray]]] = None,
|
| 1317 |
+
audio_parts: Optional[list] = None,
|
| 1318 |
+
max_length: Optional[int] = None,
|
| 1319 |
+
do_pad: Optional[bool] = True,
|
| 1320 |
+
max_slice_nums: int = None,
|
| 1321 |
+
use_image_id: bool = True,
|
| 1322 |
+
stream_input: bool = False,
|
| 1323 |
+
return_tensors: Optional[Union[str, TensorType]] = TensorType.PYTORCH,
|
| 1324 |
+
sampling_rate: Optional[int] = 16000,
|
| 1325 |
+
online_streaming: bool = False,
|
| 1326 |
+
audio_chunk_idx: int = 0,
|
| 1327 |
+
is_last_chunk: bool = False,
|
| 1328 |
+
**kwargs,
|
| 1329 |
+
) -> MiniCPMOBatchFeature:
|
| 1330 |
+
if images is not None:
|
| 1331 |
+
image_inputs = self.process_image(
|
| 1332 |
+
images=images, do_pad=do_pad, max_slice_nums=max_slice_nums, return_tensors=return_tensors
|
| 1333 |
+
)
|
| 1334 |
+
else:
|
| 1335 |
+
image_inputs = None
|
| 1336 |
+
|
| 1337 |
+
audio_features, audio_feature_lens, audio_phs = self.audio_feature_extract(
|
| 1338 |
+
audios,
|
| 1339 |
+
audio_parts,
|
| 1340 |
+
stream_input,
|
| 1341 |
+
sampling_rate,
|
| 1342 |
+
online_streaming=online_streaming,
|
| 1343 |
+
is_last_chunk=is_last_chunk,
|
| 1344 |
+
)
|
| 1345 |
+
|
| 1346 |
+
model_inputs = self._convert_omni_to_inputs(
|
| 1347 |
+
image_inputs,
|
| 1348 |
+
audio_phs,
|
| 1349 |
+
text,
|
| 1350 |
+
max_slice_nums=max_slice_nums,
|
| 1351 |
+
use_image_id=use_image_id,
|
| 1352 |
+
max_length=max_length,
|
| 1353 |
+
**kwargs,
|
| 1354 |
+
)
|
| 1355 |
+
|
| 1356 |
+
model_inputs["audio_features"] = audio_features
|
| 1357 |
+
model_inputs["audio_feature_lens"] = audio_feature_lens
|
| 1358 |
+
|
| 1359 |
+
result = MiniCPMOBatchFeature(data={**model_inputs})
|
| 1360 |
+
|
| 1361 |
+
if online_streaming:
|
| 1362 |
+
result.use_extra_context = True
|
| 1363 |
+
result.prefix_extra_frames = 0 if audio_chunk_idx == 0 else 2
|
| 1364 |
+
result.suffix_extra_frames = 2
|
| 1365 |
+
result.chunk_idx = audio_chunk_idx
|
| 1366 |
+
|
| 1367 |
+
return result
|
| 1368 |
+
|
| 1369 |
+
def audio_feature_extract(
|
| 1370 |
+
self,
|
| 1371 |
+
audios: Union[np.ndarray, List[np.ndarray], List[List[np.ndarray]], None] = None,
|
| 1372 |
+
audio_parts: Optional[list] = None,
|
| 1373 |
+
stream_input: Optional[bool] = False,
|
| 1374 |
+
sampling_rate: Optional[int] = None,
|
| 1375 |
+
chunk_length: Optional[int] = 1,
|
| 1376 |
+
online_streaming: bool = False,
|
| 1377 |
+
is_last_chunk: bool = False,
|
| 1378 |
+
**kwargs,
|
| 1379 |
+
):
|
| 1380 |
+
if audios is None:
|
| 1381 |
+
return [], [], []
|
| 1382 |
+
|
| 1383 |
+
if isinstance(audios, np.ndarray):
|
| 1384 |
+
audios_list = [[audios]]
|
| 1385 |
+
elif isinstance(audios[0], np.ndarray):
|
| 1386 |
+
audios_list = [audios]
|
| 1387 |
+
else:
|
| 1388 |
+
audios_list = audios
|
| 1389 |
+
|
| 1390 |
+
if audio_parts is not None:
|
| 1391 |
+
assert len(audio_parts) == len(audios_list)
|
| 1392 |
+
for parts, audios in zip(audio_parts, audios_list):
|
| 1393 |
+
assert len(parts) == len(audios)
|
| 1394 |
+
|
| 1395 |
+
audio_feature_lens_list = []
|
| 1396 |
+
audio_ph_list = []
|
| 1397 |
+
audio_features_all = []
|
| 1398 |
+
|
| 1399 |
+
# audio placeholder not dependent on audio_parts
|
| 1400 |
+
for audios in audios_list:
|
| 1401 |
+
if audios:
|
| 1402 |
+
audio_ph_list.append(
|
| 1403 |
+
[
|
| 1404 |
+
self.get_audio_placeholder(len(a), chunk_input=stream_input, chunk_length=chunk_length)
|
| 1405 |
+
for a in audios
|
| 1406 |
+
]
|
| 1407 |
+
)
|
| 1408 |
+
else:
|
| 1409 |
+
audio_ph_list.append([])
|
| 1410 |
+
|
| 1411 |
+
for idx, audios in enumerate(audios_list):
|
| 1412 |
+
if audio_parts is not None:
|
| 1413 |
+
# same audio part merge
|
| 1414 |
+
audio_part = audio_parts[idx]
|
| 1415 |
+
merge_audio = []
|
| 1416 |
+
cur_audio = []
|
| 1417 |
+
for aid, (part, audio) in enumerate(zip(audio_part, audios)):
|
| 1418 |
+
if aid == 0 or audio_part[aid] == audio_part[aid - 1]:
|
| 1419 |
+
cur_audio.append(audio)
|
| 1420 |
+
else:
|
| 1421 |
+
merge_audio.append(np.hstack(cur_audio))
|
| 1422 |
+
cur_audio = [audio]
|
| 1423 |
+
if cur_audio:
|
| 1424 |
+
merge_audio.append(np.hstack(cur_audio))
|
| 1425 |
+
else:
|
| 1426 |
+
merge_audio = audios
|
| 1427 |
+
|
| 1428 |
+
# If the audio exceeds 30 seconds, split it into chunks every 30 seconds.
|
| 1429 |
+
final_merge_audio = []
|
| 1430 |
+
max_audio_inp_len = 30 * sampling_rate
|
| 1431 |
+
for audio in merge_audio:
|
| 1432 |
+
if len(audio) <= max_audio_inp_len:
|
| 1433 |
+
final_merge_audio.append(audio)
|
| 1434 |
+
else:
|
| 1435 |
+
for i in range(math.ceil(len(audio) / max_audio_inp_len)):
|
| 1436 |
+
final_merge_audio.append(audio[i * max_audio_inp_len : (i + 1) * max_audio_inp_len])
|
| 1437 |
+
|
| 1438 |
+
audio_feature_lens = []
|
| 1439 |
+
|
| 1440 |
+
if audios:
|
| 1441 |
+
if online_streaming:
|
| 1442 |
+
# online streaming: only support single audio, directly use process_audio_streaming return format
|
| 1443 |
+
assert (
|
| 1444 |
+
len(final_merge_audio) == 1
|
| 1445 |
+
), f"online streaming mode only supports single audio, currently there are {len(final_merge_audio)}"
|
| 1446 |
+
audio = final_merge_audio[0]
|
| 1447 |
+
result = self.process_audio_streaming(
|
| 1448 |
+
audio, reset=False, return_batch_feature=True, is_last_chunk=is_last_chunk
|
| 1449 |
+
)
|
| 1450 |
+
audio_features_all.append(
|
| 1451 |
+
result["audio_features"].squeeze(0)
|
| 1452 |
+
) # [1, 80, T] -> [80, T], keep consistent with batch processing
|
| 1453 |
+
audio_feature_lens_list.append(result["audio_feature_lens"][0])
|
| 1454 |
+
else:
|
| 1455 |
+
# batch processing
|
| 1456 |
+
audio_inputs = self.audio_processor(
|
| 1457 |
+
final_merge_audio,
|
| 1458 |
+
sampling_rate=sampling_rate,
|
| 1459 |
+
return_attention_mask=True,
|
| 1460 |
+
padding="max_length",
|
| 1461 |
+
return_tensors="pt",
|
| 1462 |
+
**kwargs,
|
| 1463 |
+
)
|
| 1464 |
+
audio_feature = audio_inputs["input_features"]
|
| 1465 |
+
actual_lens = audio_inputs["attention_mask"].sum(dim=1)
|
| 1466 |
+
|
| 1467 |
+
for feat, lens in zip(audio_feature, actual_lens):
|
| 1468 |
+
audio_features_all.append(feat[:, :lens])
|
| 1469 |
+
audio_feature_lens.append(lens)
|
| 1470 |
+
|
| 1471 |
+
audio_feature_lens = torch.hstack(audio_feature_lens)
|
| 1472 |
+
audio_feature_lens_list.append(audio_feature_lens)
|
| 1473 |
+
else:
|
| 1474 |
+
audio_feature_lens_list.append([])
|
| 1475 |
+
|
| 1476 |
+
if audio_features_all:
|
| 1477 |
+
audio_features = [i.permute(1, 0) for i in audio_features_all]
|
| 1478 |
+
audio_features = torch.nn.utils.rnn.pad_sequence(
|
| 1479 |
+
audio_features, batch_first=True, padding_value=0.0
|
| 1480 |
+
).permute(0, 2, 1)
|
| 1481 |
+
else:
|
| 1482 |
+
audio_features = []
|
| 1483 |
+
|
| 1484 |
+
return audio_features, audio_feature_lens_list, audio_ph_list
|
| 1485 |
+
|
| 1486 |
+
def _convert(self, input_str, max_inp_length: Optional[int] = None):
|
| 1487 |
+
old_input_ids = self.tokenizer.encode(input_str)
|
| 1488 |
+
|
| 1489 |
+
listen_token_id = self.tokenizer.convert_tokens_to_ids("<|listen|>")
|
| 1490 |
+
input_ids = []
|
| 1491 |
+
for token in old_input_ids:
|
| 1492 |
+
if token != listen_token_id:
|
| 1493 |
+
input_ids.append(token)
|
| 1494 |
+
|
| 1495 |
+
if max_inp_length is not None:
|
| 1496 |
+
input_ids = input_ids[:max_inp_length]
|
| 1497 |
+
input_ids = torch.tensor(input_ids, dtype=torch.int32)
|
| 1498 |
+
|
| 1499 |
+
## image bound
|
| 1500 |
+
start_cond = (input_ids == self.tokenizer.im_start_id) | (input_ids == self.tokenizer.slice_start_id)
|
| 1501 |
+
end_cond = (input_ids == self.tokenizer.im_end_id) | (input_ids == self.tokenizer.slice_end_id)
|
| 1502 |
+
|
| 1503 |
+
image_start_idx = torch.where(start_cond)[0]
|
| 1504 |
+
image_start_idx += 1
|
| 1505 |
+
image_end_idx = torch.where(end_cond)[0]
|
| 1506 |
+
|
| 1507 |
+
valid_image_nums = max(len(image_start_idx), len(image_end_idx))
|
| 1508 |
+
|
| 1509 |
+
image_bounds = torch.hstack(
|
| 1510 |
+
[
|
| 1511 |
+
image_start_idx[:valid_image_nums].unsqueeze(-1),
|
| 1512 |
+
image_end_idx[:valid_image_nums].unsqueeze(-1),
|
| 1513 |
+
]
|
| 1514 |
+
)
|
| 1515 |
+
|
| 1516 |
+
## audio bound
|
| 1517 |
+
audio_start_idx = torch.where(input_ids == self.tokenizer.audio_start_id)[0]
|
| 1518 |
+
audio_end_idx = torch.where(input_ids == self.tokenizer.audio_end_id)[0]
|
| 1519 |
+
assert len(audio_start_idx) == len(audio_end_idx)
|
| 1520 |
+
audio_bounds = torch.hstack([(audio_start_idx + 1).unsqueeze(-1), audio_end_idx.unsqueeze(-1)])
|
| 1521 |
+
|
| 1522 |
+
spk_start_idx = torch.where(input_ids == self.tokenizer.spk_start_id)[0]
|
| 1523 |
+
spk_end_idx = torch.where(input_ids == self.tokenizer.spk_end_id)[0]
|
| 1524 |
+
assert len(spk_start_idx) == len(spk_end_idx)
|
| 1525 |
+
spk_bounds = torch.hstack([(spk_start_idx + 1).unsqueeze(-1), spk_end_idx.unsqueeze(-1)])
|
| 1526 |
+
|
| 1527 |
+
return input_ids, image_bounds, audio_bounds, spk_bounds
|
| 1528 |
+
|
| 1529 |
+
def _convert_omni_to_inputs(
|
| 1530 |
+
self,
|
| 1531 |
+
images,
|
| 1532 |
+
audio_phs,
|
| 1533 |
+
texts: Union[str, List[str]],
|
| 1534 |
+
truncation=None,
|
| 1535 |
+
max_length=None,
|
| 1536 |
+
max_slice_nums=None,
|
| 1537 |
+
use_image_id=None,
|
| 1538 |
+
return_tensors=None,
|
| 1539 |
+
**kwargs,
|
| 1540 |
+
):
|
| 1541 |
+
if images is None and audio_phs is None:
|
| 1542 |
+
model_inputs = self.tokenizer(
|
| 1543 |
+
texts, return_tensors=return_tensors, truncation=truncation, max_length=max_length, **kwargs
|
| 1544 |
+
)
|
| 1545 |
+
return MiniCPMOBatchFeature(data={**model_inputs})
|
| 1546 |
+
|
| 1547 |
+
image_pattern = "<image>./</image>"
|
| 1548 |
+
audio_pattern = "<audio>./</audio>"
|
| 1549 |
+
split_pattern = f"({image_pattern}|{audio_pattern})"
|
| 1550 |
+
|
| 1551 |
+
if isinstance(texts, str):
|
| 1552 |
+
texts = [texts]
|
| 1553 |
+
|
| 1554 |
+
bs = len(texts)
|
| 1555 |
+
if images is not None:
|
| 1556 |
+
images, image_sizes, tgt_sizes = images["pixel_values"], images["image_sizes"], images["tgt_sizes"]
|
| 1557 |
+
else:
|
| 1558 |
+
images, image_sizes, tgt_sizes = [[]] * bs, [[]] * bs, [[]] * bs
|
| 1559 |
+
|
| 1560 |
+
input_ids_list = []
|
| 1561 |
+
image_bounds_list = []
|
| 1562 |
+
audio_bounds_list = []
|
| 1563 |
+
spk_bounds_list = []
|
| 1564 |
+
|
| 1565 |
+
for index, text in enumerate(texts):
|
| 1566 |
+
text_chunks = re.split(split_pattern, text)
|
| 1567 |
+
|
| 1568 |
+
image_tags = re.findall(image_pattern, text)
|
| 1569 |
+
audio_tags = re.findall(audio_pattern, text)
|
| 1570 |
+
|
| 1571 |
+
if image_tags:
|
| 1572 |
+
assert images is not None
|
| 1573 |
+
assert len(image_tags) == len(image_sizes[index])
|
| 1574 |
+
if audio_tags:
|
| 1575 |
+
assert audio_phs is not None
|
| 1576 |
+
assert len(audio_tags) == len(audio_phs[index])
|
| 1577 |
+
|
| 1578 |
+
image_id = 0
|
| 1579 |
+
audio_id = 0
|
| 1580 |
+
for i, chunk in enumerate(text_chunks):
|
| 1581 |
+
if chunk == image_pattern:
|
| 1582 |
+
image_placeholder = self.image_processor.get_slice_image_placeholder(
|
| 1583 |
+
image_sizes[index][image_id], image_id, max_slice_nums, use_image_id
|
| 1584 |
+
)
|
| 1585 |
+
image_id += 1
|
| 1586 |
+
text_chunks[i] = image_placeholder
|
| 1587 |
+
elif chunk == audio_pattern:
|
| 1588 |
+
audio_placeholder = audio_phs[index][audio_id]
|
| 1589 |
+
audio_id += 1
|
| 1590 |
+
text_chunks[i] = audio_placeholder
|
| 1591 |
+
|
| 1592 |
+
final_text = "".join(text_chunks)
|
| 1593 |
+
input_ids, image_bounds, audio_bounds, spk_bounds = self._convert(final_text, max_length)
|
| 1594 |
+
|
| 1595 |
+
input_ids_list.append(input_ids)
|
| 1596 |
+
image_bounds_list.append(image_bounds)
|
| 1597 |
+
audio_bounds_list.append(audio_bounds)
|
| 1598 |
+
spk_bounds_list.append(spk_bounds)
|
| 1599 |
+
|
| 1600 |
+
padded_input_ids, padding_lengths = self.pad(input_ids_list, padding_side="left")
|
| 1601 |
+
attention_mask = torch.ones_like(padded_input_ids, dtype=torch.bool)
|
| 1602 |
+
for i, length in enumerate(padding_lengths):
|
| 1603 |
+
image_bounds_list[i] = image_bounds_list[i] + length
|
| 1604 |
+
audio_bounds_list[i] = audio_bounds_list[i] + length
|
| 1605 |
+
spk_bounds_list[i] = spk_bounds_list[i] + length
|
| 1606 |
+
attention_mask[i, :length] = False
|
| 1607 |
+
|
| 1608 |
+
data = {
|
| 1609 |
+
"input_ids": padded_input_ids,
|
| 1610 |
+
"attention_mask": attention_mask,
|
| 1611 |
+
"pixel_values": images,
|
| 1612 |
+
"image_sizes": image_sizes,
|
| 1613 |
+
"image_bound": image_bounds_list,
|
| 1614 |
+
"tgt_sizes": tgt_sizes,
|
| 1615 |
+
"audio_bounds": audio_bounds_list,
|
| 1616 |
+
"spk_bounds": spk_bounds_list,
|
| 1617 |
+
}
|
| 1618 |
+
|
| 1619 |
+
return data
|
| 1620 |
+
|
| 1621 |
+
def pad(self, inputs, max_length=None, padding_value=0, padding_side="left"):
|
| 1622 |
+
items = []
|
| 1623 |
+
if isinstance(inputs[0], list):
|
| 1624 |
+
assert isinstance(inputs[0][0], torch.Tensor)
|
| 1625 |
+
for it in inputs:
|
| 1626 |
+
for tr in it:
|
| 1627 |
+
items.append(tr)
|
| 1628 |
+
else:
|
| 1629 |
+
assert isinstance(inputs[0], torch.Tensor)
|
| 1630 |
+
items = inputs
|
| 1631 |
+
|
| 1632 |
+
batch_size = len(items)
|
| 1633 |
+
shape = items[0].shape
|
| 1634 |
+
dim = len(shape)
|
| 1635 |
+
assert dim <= 2
|
| 1636 |
+
if max_length is None:
|
| 1637 |
+
max_length = 0
|
| 1638 |
+
max_length = max(max_length, max(item.shape[-1] for item in items))
|
| 1639 |
+
min_length = min(item.shape[-1] for item in items)
|
| 1640 |
+
dtype = items[0].dtype
|
| 1641 |
+
|
| 1642 |
+
if dim == 0:
|
| 1643 |
+
return torch.stack([item for item in items], dim=0), [0]
|
| 1644 |
+
elif dim == 1:
|
| 1645 |
+
if max_length == min_length:
|
| 1646 |
+
return torch.stack([item for item in items], dim=0), [0] * batch_size
|
| 1647 |
+
tensor = torch.zeros((batch_size, max_length), dtype=dtype) + padding_value
|
| 1648 |
+
else:
|
| 1649 |
+
tensor = torch.zeros((batch_size, max_length, shape[-1]), dtype=dtype) + padding_value
|
| 1650 |
+
|
| 1651 |
+
padding_length = []
|
| 1652 |
+
for i, item in enumerate(items):
|
| 1653 |
+
if dim == 1:
|
| 1654 |
+
if padding_side == "left":
|
| 1655 |
+
tensor[i, -len(item) :] = item.clone()
|
| 1656 |
+
else:
|
| 1657 |
+
tensor[i, : len(item)] = item.clone()
|
| 1658 |
+
elif dim == 2:
|
| 1659 |
+
if padding_side == "left":
|
| 1660 |
+
tensor[i, -len(item) :, :] = item.clone()
|
| 1661 |
+
else:
|
| 1662 |
+
tensor[i, : len(item), :] = item.clone()
|
| 1663 |
+
padding_length.append(tensor.shape[-1] - len(item))
|
| 1664 |
+
|
| 1665 |
+
return tensor, padding_length
|
processor_config.json
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"audio_processor": {
|
| 3 |
+
"audio_pool_step": 5,
|
| 4 |
+
"auto_map": {
|
| 5 |
+
"AutoFeatureExtractor": "processing_minicpmo.MiniCPMAAudioProcessor",
|
| 6 |
+
"AutoImageProcessor": "processing_minicpmo.MiniCPMVImageProcessor",
|
| 7 |
+
"AutoProcessor": "processing_minicpmo.MiniCPMOProcessor"
|
| 8 |
+
},
|
| 9 |
+
"chunk_length": 30,
|
| 10 |
+
"dither": 0.0,
|
| 11 |
+
"feature_extractor_type": "WhisperFeatureExtractor",
|
| 12 |
+
"feature_size": 80,
|
| 13 |
+
"hop_length": 160,
|
| 14 |
+
"im_end": "</image>",
|
| 15 |
+
"im_id_end": "</image_id>",
|
| 16 |
+
"im_id_start": "<image_id>",
|
| 17 |
+
"im_start": "<image>",
|
| 18 |
+
"image_feature_size": 64,
|
| 19 |
+
"image_processor_type": "MiniCPMVImageProcessor",
|
| 20 |
+
"max_slice_nums": 9,
|
| 21 |
+
"n_fft": 400,
|
| 22 |
+
"n_samples": 480000,
|
| 23 |
+
"nb_max_frames": 3000,
|
| 24 |
+
"norm_mean": [
|
| 25 |
+
0.5,
|
| 26 |
+
0.5,
|
| 27 |
+
0.5
|
| 28 |
+
],
|
| 29 |
+
"norm_std": [
|
| 30 |
+
0.5,
|
| 31 |
+
0.5,
|
| 32 |
+
0.5
|
| 33 |
+
],
|
| 34 |
+
"padding_side": "right",
|
| 35 |
+
"padding_value": 0.0,
|
| 36 |
+
"patch_size": 14,
|
| 37 |
+
"return_attention_mask": false,
|
| 38 |
+
"sampling_rate": 16000,
|
| 39 |
+
"scale_resolution": 448,
|
| 40 |
+
"slice_end": "</slice>",
|
| 41 |
+
"slice_mode": true,
|
| 42 |
+
"slice_start": "<slice>",
|
| 43 |
+
"unk": "<unk>",
|
| 44 |
+
"use_image_id": true,
|
| 45 |
+
"version": 4.5
|
| 46 |
+
},
|
| 47 |
+
"image_processor": {
|
| 48 |
+
"audio_pool_step": 5,
|
| 49 |
+
"auto_map": {
|
| 50 |
+
"AutoFeatureExtractor": "processing_minicpmo.MiniCPMAAudioProcessor",
|
| 51 |
+
"AutoImageProcessor": "processing_minicpmo.MiniCPMVImageProcessor",
|
| 52 |
+
"AutoProcessor": "processing_minicpmo.MiniCPMOProcessor"
|
| 53 |
+
},
|
| 54 |
+
"im_end": "</image>",
|
| 55 |
+
"im_id_end": "</image_id>",
|
| 56 |
+
"im_id_start": "<image_id>",
|
| 57 |
+
"im_start": "<image>",
|
| 58 |
+
"image_feature_size": 64,
|
| 59 |
+
"image_processor_type": "MiniCPMOImageProcessor",
|
| 60 |
+
"max_slice_nums": 9,
|
| 61 |
+
"mean": [
|
| 62 |
+
[
|
| 63 |
+
[
|
| 64 |
+
0.5,
|
| 65 |
+
0.5,
|
| 66 |
+
0.5
|
| 67 |
+
]
|
| 68 |
+
]
|
| 69 |
+
],
|
| 70 |
+
"patch_size": 14,
|
| 71 |
+
"scale_resolution": 448,
|
| 72 |
+
"slice_end": "</slice>",
|
| 73 |
+
"slice_mode": true,
|
| 74 |
+
"slice_start": "<slice>",
|
| 75 |
+
"std": [
|
| 76 |
+
[
|
| 77 |
+
[
|
| 78 |
+
0.5,
|
| 79 |
+
0.5,
|
| 80 |
+
0.5
|
| 81 |
+
]
|
| 82 |
+
]
|
| 83 |
+
],
|
| 84 |
+
"unk": "<unk>",
|
| 85 |
+
"use_image_id": true,
|
| 86 |
+
"version": 4.5
|
| 87 |
+
},
|
| 88 |
+
"processor_class": "MiniCPMOProcessor"
|
| 89 |
+
}
|
special_tokens_map.json
ADDED
|
@@ -0,0 +1,580 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"additional_special_tokens": [
|
| 3 |
+
{
|
| 4 |
+
"content": "<unk>",
|
| 5 |
+
"lstrip": false,
|
| 6 |
+
"normalized": false,
|
| 7 |
+
"rstrip": false,
|
| 8 |
+
"single_word": false
|
| 9 |
+
},
|
| 10 |
+
{
|
| 11 |
+
"content": "<image>",
|
| 12 |
+
"lstrip": false,
|
| 13 |
+
"normalized": false,
|
| 14 |
+
"rstrip": false,
|
| 15 |
+
"single_word": false
|
| 16 |
+
},
|
| 17 |
+
{
|
| 18 |
+
"content": "</image>",
|
| 19 |
+
"lstrip": false,
|
| 20 |
+
"normalized": false,
|
| 21 |
+
"rstrip": false,
|
| 22 |
+
"single_word": false
|
| 23 |
+
},
|
| 24 |
+
{
|
| 25 |
+
"content": "<ref>",
|
| 26 |
+
"lstrip": false,
|
| 27 |
+
"normalized": false,
|
| 28 |
+
"rstrip": false,
|
| 29 |
+
"single_word": false
|
| 30 |
+
},
|
| 31 |
+
{
|
| 32 |
+
"content": "</ref>",
|
| 33 |
+
"lstrip": false,
|
| 34 |
+
"normalized": false,
|
| 35 |
+
"rstrip": false,
|
| 36 |
+
"single_word": false
|
| 37 |
+
},
|
| 38 |
+
{
|
| 39 |
+
"content": "<box>",
|
| 40 |
+
"lstrip": false,
|
| 41 |
+
"normalized": false,
|
| 42 |
+
"rstrip": false,
|
| 43 |
+
"single_word": false
|
| 44 |
+
},
|
| 45 |
+
{
|
| 46 |
+
"content": "</box>",
|
| 47 |
+
"lstrip": false,
|
| 48 |
+
"normalized": false,
|
| 49 |
+
"rstrip": false,
|
| 50 |
+
"single_word": false
|
| 51 |
+
},
|
| 52 |
+
{
|
| 53 |
+
"content": "<quad>",
|
| 54 |
+
"lstrip": false,
|
| 55 |
+
"normalized": false,
|
| 56 |
+
"rstrip": false,
|
| 57 |
+
"single_word": false
|
| 58 |
+
},
|
| 59 |
+
{
|
| 60 |
+
"content": "</quad>",
|
| 61 |
+
"lstrip": false,
|
| 62 |
+
"normalized": false,
|
| 63 |
+
"rstrip": false,
|
| 64 |
+
"single_word": false
|
| 65 |
+
},
|
| 66 |
+
{
|
| 67 |
+
"content": "<point>",
|
| 68 |
+
"lstrip": false,
|
| 69 |
+
"normalized": false,
|
| 70 |
+
"rstrip": false,
|
| 71 |
+
"single_word": false
|
| 72 |
+
},
|
| 73 |
+
{
|
| 74 |
+
"content": "</point>",
|
| 75 |
+
"lstrip": false,
|
| 76 |
+
"normalized": false,
|
| 77 |
+
"rstrip": false,
|
| 78 |
+
"single_word": false
|
| 79 |
+
},
|
| 80 |
+
{
|
| 81 |
+
"content": "<slice>",
|
| 82 |
+
"lstrip": false,
|
| 83 |
+
"normalized": false,
|
| 84 |
+
"rstrip": false,
|
| 85 |
+
"single_word": false
|
| 86 |
+
},
|
| 87 |
+
{
|
| 88 |
+
"content": "</slice>",
|
| 89 |
+
"lstrip": false,
|
| 90 |
+
"normalized": false,
|
| 91 |
+
"rstrip": false,
|
| 92 |
+
"single_word": false
|
| 93 |
+
},
|
| 94 |
+
{
|
| 95 |
+
"content": "<image_id>",
|
| 96 |
+
"lstrip": false,
|
| 97 |
+
"normalized": false,
|
| 98 |
+
"rstrip": false,
|
| 99 |
+
"single_word": false
|
| 100 |
+
},
|
| 101 |
+
{
|
| 102 |
+
"content": "</image_id>",
|
| 103 |
+
"lstrip": false,
|
| 104 |
+
"normalized": false,
|
| 105 |
+
"rstrip": false,
|
| 106 |
+
"single_word": false
|
| 107 |
+
},
|
| 108 |
+
{
|
| 109 |
+
"content": "<unit>",
|
| 110 |
+
"lstrip": false,
|
| 111 |
+
"normalized": false,
|
| 112 |
+
"rstrip": false,
|
| 113 |
+
"single_word": false
|
| 114 |
+
},
|
| 115 |
+
{
|
| 116 |
+
"content": "</unit>",
|
| 117 |
+
"lstrip": false,
|
| 118 |
+
"normalized": false,
|
| 119 |
+
"rstrip": false,
|
| 120 |
+
"single_word": false
|
| 121 |
+
},
|
| 122 |
+
{
|
| 123 |
+
"content": "<answer>",
|
| 124 |
+
"lstrip": false,
|
| 125 |
+
"normalized": false,
|
| 126 |
+
"rstrip": false,
|
| 127 |
+
"single_word": false
|
| 128 |
+
},
|
| 129 |
+
{
|
| 130 |
+
"content": "</answer>",
|
| 131 |
+
"lstrip": false,
|
| 132 |
+
"normalized": false,
|
| 133 |
+
"rstrip": false,
|
| 134 |
+
"single_word": false
|
| 135 |
+
},
|
| 136 |
+
{
|
| 137 |
+
"content": "<focus>",
|
| 138 |
+
"lstrip": false,
|
| 139 |
+
"normalized": false,
|
| 140 |
+
"rstrip": false,
|
| 141 |
+
"single_word": false
|
| 142 |
+
},
|
| 143 |
+
{
|
| 144 |
+
"content": "</focus>",
|
| 145 |
+
"lstrip": false,
|
| 146 |
+
"normalized": false,
|
| 147 |
+
"rstrip": false,
|
| 148 |
+
"single_word": false
|
| 149 |
+
},
|
| 150 |
+
{
|
| 151 |
+
"content": "<line>",
|
| 152 |
+
"lstrip": false,
|
| 153 |
+
"normalized": false,
|
| 154 |
+
"rstrip": false,
|
| 155 |
+
"single_word": false
|
| 156 |
+
},
|
| 157 |
+
{
|
| 158 |
+
"content": "</line>",
|
| 159 |
+
"lstrip": false,
|
| 160 |
+
"normalized": false,
|
| 161 |
+
"rstrip": false,
|
| 162 |
+
"single_word": false
|
| 163 |
+
},
|
| 164 |
+
{
|
| 165 |
+
"content": "<perception>",
|
| 166 |
+
"lstrip": false,
|
| 167 |
+
"normalized": false,
|
| 168 |
+
"rstrip": false,
|
| 169 |
+
"single_word": false
|
| 170 |
+
},
|
| 171 |
+
{
|
| 172 |
+
"content": "</perception>",
|
| 173 |
+
"lstrip": false,
|
| 174 |
+
"normalized": false,
|
| 175 |
+
"rstrip": false,
|
| 176 |
+
"single_word": false
|
| 177 |
+
},
|
| 178 |
+
{
|
| 179 |
+
"content": "<source_image>",
|
| 180 |
+
"lstrip": false,
|
| 181 |
+
"normalized": false,
|
| 182 |
+
"rstrip": false,
|
| 183 |
+
"single_word": false
|
| 184 |
+
},
|
| 185 |
+
{
|
| 186 |
+
"content": "</source_image>",
|
| 187 |
+
"lstrip": false,
|
| 188 |
+
"normalized": false,
|
| 189 |
+
"rstrip": false,
|
| 190 |
+
"single_word": false
|
| 191 |
+
},
|
| 192 |
+
{
|
| 193 |
+
"content": "<image_save_to>",
|
| 194 |
+
"lstrip": false,
|
| 195 |
+
"normalized": false,
|
| 196 |
+
"rstrip": false,
|
| 197 |
+
"single_word": false
|
| 198 |
+
},
|
| 199 |
+
{
|
| 200 |
+
"content": "</image_save_to>",
|
| 201 |
+
"lstrip": false,
|
| 202 |
+
"normalized": false,
|
| 203 |
+
"rstrip": false,
|
| 204 |
+
"single_word": false
|
| 205 |
+
},
|
| 206 |
+
{
|
| 207 |
+
"content": "<|audio_start|>",
|
| 208 |
+
"lstrip": false,
|
| 209 |
+
"normalized": false,
|
| 210 |
+
"rstrip": false,
|
| 211 |
+
"single_word": false
|
| 212 |
+
},
|
| 213 |
+
{
|
| 214 |
+
"content": "<|audio|>",
|
| 215 |
+
"lstrip": false,
|
| 216 |
+
"normalized": false,
|
| 217 |
+
"rstrip": false,
|
| 218 |
+
"single_word": false
|
| 219 |
+
},
|
| 220 |
+
{
|
| 221 |
+
"content": "<|audio_end|>",
|
| 222 |
+
"lstrip": false,
|
| 223 |
+
"normalized": false,
|
| 224 |
+
"rstrip": false,
|
| 225 |
+
"single_word": false
|
| 226 |
+
},
|
| 227 |
+
{
|
| 228 |
+
"content": "<|spk_bos|>",
|
| 229 |
+
"lstrip": false,
|
| 230 |
+
"normalized": false,
|
| 231 |
+
"rstrip": false,
|
| 232 |
+
"single_word": false
|
| 233 |
+
},
|
| 234 |
+
{
|
| 235 |
+
"content": "<|spk|>",
|
| 236 |
+
"lstrip": false,
|
| 237 |
+
"normalized": false,
|
| 238 |
+
"rstrip": false,
|
| 239 |
+
"single_word": false
|
| 240 |
+
},
|
| 241 |
+
{
|
| 242 |
+
"content": "<|spk_eos|>",
|
| 243 |
+
"lstrip": false,
|
| 244 |
+
"normalized": false,
|
| 245 |
+
"rstrip": false,
|
| 246 |
+
"single_word": false
|
| 247 |
+
},
|
| 248 |
+
{
|
| 249 |
+
"content": "<|tts_bos|>",
|
| 250 |
+
"lstrip": false,
|
| 251 |
+
"normalized": false,
|
| 252 |
+
"rstrip": false,
|
| 253 |
+
"single_word": false
|
| 254 |
+
},
|
| 255 |
+
{
|
| 256 |
+
"content": "<|tts_eos|>",
|
| 257 |
+
"lstrip": false,
|
| 258 |
+
"normalized": false,
|
| 259 |
+
"rstrip": false,
|
| 260 |
+
"single_word": false
|
| 261 |
+
},
|
| 262 |
+
{
|
| 263 |
+
"content": "<|listen|>",
|
| 264 |
+
"lstrip": false,
|
| 265 |
+
"normalized": false,
|
| 266 |
+
"rstrip": false,
|
| 267 |
+
"single_word": false
|
| 268 |
+
},
|
| 269 |
+
{
|
| 270 |
+
"content": "<|speak|>",
|
| 271 |
+
"lstrip": false,
|
| 272 |
+
"normalized": false,
|
| 273 |
+
"rstrip": false,
|
| 274 |
+
"single_word": false
|
| 275 |
+
},
|
| 276 |
+
{
|
| 277 |
+
"content": "<|interrupt|>",
|
| 278 |
+
"lstrip": false,
|
| 279 |
+
"normalized": false,
|
| 280 |
+
"rstrip": false,
|
| 281 |
+
"single_word": false
|
| 282 |
+
},
|
| 283 |
+
{
|
| 284 |
+
"content": "<|vad_start|>",
|
| 285 |
+
"lstrip": false,
|
| 286 |
+
"normalized": false,
|
| 287 |
+
"rstrip": false,
|
| 288 |
+
"single_word": false
|
| 289 |
+
},
|
| 290 |
+
{
|
| 291 |
+
"content": "<|vad_end|>",
|
| 292 |
+
"lstrip": false,
|
| 293 |
+
"normalized": false,
|
| 294 |
+
"rstrip": false,
|
| 295 |
+
"single_word": false
|
| 296 |
+
},
|
| 297 |
+
{
|
| 298 |
+
"content": "<|emotion_start|>",
|
| 299 |
+
"lstrip": false,
|
| 300 |
+
"normalized": false,
|
| 301 |
+
"rstrip": false,
|
| 302 |
+
"single_word": false
|
| 303 |
+
},
|
| 304 |
+
{
|
| 305 |
+
"content": "<|emotion_end|>",
|
| 306 |
+
"lstrip": false,
|
| 307 |
+
"normalized": false,
|
| 308 |
+
"rstrip": false,
|
| 309 |
+
"single_word": false
|
| 310 |
+
},
|
| 311 |
+
{
|
| 312 |
+
"content": "<|speed_start|>",
|
| 313 |
+
"lstrip": false,
|
| 314 |
+
"normalized": false,
|
| 315 |
+
"rstrip": false,
|
| 316 |
+
"single_word": false
|
| 317 |
+
},
|
| 318 |
+
{
|
| 319 |
+
"content": "<|speed_end|>",
|
| 320 |
+
"lstrip": false,
|
| 321 |
+
"normalized": false,
|
| 322 |
+
"rstrip": false,
|
| 323 |
+
"single_word": false
|
| 324 |
+
},
|
| 325 |
+
{
|
| 326 |
+
"content": "<|pitch_start|>",
|
| 327 |
+
"lstrip": false,
|
| 328 |
+
"normalized": false,
|
| 329 |
+
"rstrip": false,
|
| 330 |
+
"single_word": false
|
| 331 |
+
},
|
| 332 |
+
{
|
| 333 |
+
"content": "<|pitch_end|>",
|
| 334 |
+
"lstrip": false,
|
| 335 |
+
"normalized": false,
|
| 336 |
+
"rstrip": false,
|
| 337 |
+
"single_word": false
|
| 338 |
+
},
|
| 339 |
+
{
|
| 340 |
+
"content": "<|turn_bos|>",
|
| 341 |
+
"lstrip": false,
|
| 342 |
+
"normalized": false,
|
| 343 |
+
"rstrip": false,
|
| 344 |
+
"single_word": false
|
| 345 |
+
},
|
| 346 |
+
{
|
| 347 |
+
"content": "<|turn_eos|>",
|
| 348 |
+
"lstrip": false,
|
| 349 |
+
"normalized": false,
|
| 350 |
+
"rstrip": false,
|
| 351 |
+
"single_word": false
|
| 352 |
+
},
|
| 353 |
+
{
|
| 354 |
+
"content": "<|chunk_eos|>",
|
| 355 |
+
"lstrip": false,
|
| 356 |
+
"normalized": false,
|
| 357 |
+
"rstrip": false,
|
| 358 |
+
"single_word": false
|
| 359 |
+
},
|
| 360 |
+
{
|
| 361 |
+
"content": "<|chunk_bos|>",
|
| 362 |
+
"lstrip": false,
|
| 363 |
+
"normalized": false,
|
| 364 |
+
"rstrip": false,
|
| 365 |
+
"single_word": false
|
| 366 |
+
},
|
| 367 |
+
{
|
| 368 |
+
"content": "<|chunk_tts_bos|>",
|
| 369 |
+
"lstrip": false,
|
| 370 |
+
"normalized": false,
|
| 371 |
+
"rstrip": false,
|
| 372 |
+
"single_word": false
|
| 373 |
+
},
|
| 374 |
+
{
|
| 375 |
+
"content": "<|chunk_tts_eos|>",
|
| 376 |
+
"lstrip": false,
|
| 377 |
+
"normalized": false,
|
| 378 |
+
"rstrip": false,
|
| 379 |
+
"single_word": false
|
| 380 |
+
},
|
| 381 |
+
{
|
| 382 |
+
"content": "<|tts_pad|>",
|
| 383 |
+
"lstrip": false,
|
| 384 |
+
"normalized": false,
|
| 385 |
+
"rstrip": false,
|
| 386 |
+
"single_word": false
|
| 387 |
+
},
|
| 388 |
+
{
|
| 389 |
+
"content": "<|timbre_7|>",
|
| 390 |
+
"lstrip": false,
|
| 391 |
+
"normalized": false,
|
| 392 |
+
"rstrip": false,
|
| 393 |
+
"single_word": false
|
| 394 |
+
},
|
| 395 |
+
{
|
| 396 |
+
"content": "<|timbre_8|>",
|
| 397 |
+
"lstrip": false,
|
| 398 |
+
"normalized": false,
|
| 399 |
+
"rstrip": false,
|
| 400 |
+
"single_word": false
|
| 401 |
+
},
|
| 402 |
+
{
|
| 403 |
+
"content": "<|timbre_9|>",
|
| 404 |
+
"lstrip": false,
|
| 405 |
+
"normalized": false,
|
| 406 |
+
"rstrip": false,
|
| 407 |
+
"single_word": false
|
| 408 |
+
},
|
| 409 |
+
{
|
| 410 |
+
"content": "<|timbre_10|>",
|
| 411 |
+
"lstrip": false,
|
| 412 |
+
"normalized": false,
|
| 413 |
+
"rstrip": false,
|
| 414 |
+
"single_word": false
|
| 415 |
+
},
|
| 416 |
+
{
|
| 417 |
+
"content": "<|timbre_11|>",
|
| 418 |
+
"lstrip": false,
|
| 419 |
+
"normalized": false,
|
| 420 |
+
"rstrip": false,
|
| 421 |
+
"single_word": false
|
| 422 |
+
},
|
| 423 |
+
{
|
| 424 |
+
"content": "<|timbre_12|>",
|
| 425 |
+
"lstrip": false,
|
| 426 |
+
"normalized": false,
|
| 427 |
+
"rstrip": false,
|
| 428 |
+
"single_word": false
|
| 429 |
+
},
|
| 430 |
+
{
|
| 431 |
+
"content": "<|timbre_13|>",
|
| 432 |
+
"lstrip": false,
|
| 433 |
+
"normalized": false,
|
| 434 |
+
"rstrip": false,
|
| 435 |
+
"single_word": false
|
| 436 |
+
},
|
| 437 |
+
{
|
| 438 |
+
"content": "<|timbre_14|>",
|
| 439 |
+
"lstrip": false,
|
| 440 |
+
"normalized": false,
|
| 441 |
+
"rstrip": false,
|
| 442 |
+
"single_word": false
|
| 443 |
+
},
|
| 444 |
+
{
|
| 445 |
+
"content": "<|timbre_15|>",
|
| 446 |
+
"lstrip": false,
|
| 447 |
+
"normalized": false,
|
| 448 |
+
"rstrip": false,
|
| 449 |
+
"single_word": false
|
| 450 |
+
},
|
| 451 |
+
{
|
| 452 |
+
"content": "<|timbre_16|>",
|
| 453 |
+
"lstrip": false,
|
| 454 |
+
"normalized": false,
|
| 455 |
+
"rstrip": false,
|
| 456 |
+
"single_word": false
|
| 457 |
+
},
|
| 458 |
+
{
|
| 459 |
+
"content": "<|timbre_17|>",
|
| 460 |
+
"lstrip": false,
|
| 461 |
+
"normalized": false,
|
| 462 |
+
"rstrip": false,
|
| 463 |
+
"single_word": false
|
| 464 |
+
},
|
| 465 |
+
{
|
| 466 |
+
"content": "<|timbre_18|>",
|
| 467 |
+
"lstrip": false,
|
| 468 |
+
"normalized": false,
|
| 469 |
+
"rstrip": false,
|
| 470 |
+
"single_word": false
|
| 471 |
+
},
|
| 472 |
+
{
|
| 473 |
+
"content": "<|timbre_19|>",
|
| 474 |
+
"lstrip": false,
|
| 475 |
+
"normalized": false,
|
| 476 |
+
"rstrip": false,
|
| 477 |
+
"single_word": false
|
| 478 |
+
},
|
| 479 |
+
{
|
| 480 |
+
"content": "<|timbre_20|>",
|
| 481 |
+
"lstrip": false,
|
| 482 |
+
"normalized": false,
|
| 483 |
+
"rstrip": false,
|
| 484 |
+
"single_word": false
|
| 485 |
+
},
|
| 486 |
+
{
|
| 487 |
+
"content": "<|timbre_21|>",
|
| 488 |
+
"lstrip": false,
|
| 489 |
+
"normalized": false,
|
| 490 |
+
"rstrip": false,
|
| 491 |
+
"single_word": false
|
| 492 |
+
},
|
| 493 |
+
{
|
| 494 |
+
"content": "<|timbre_22|>",
|
| 495 |
+
"lstrip": false,
|
| 496 |
+
"normalized": false,
|
| 497 |
+
"rstrip": false,
|
| 498 |
+
"single_word": false
|
| 499 |
+
},
|
| 500 |
+
{
|
| 501 |
+
"content": "<|timbre_23|>",
|
| 502 |
+
"lstrip": false,
|
| 503 |
+
"normalized": false,
|
| 504 |
+
"rstrip": false,
|
| 505 |
+
"single_word": false
|
| 506 |
+
},
|
| 507 |
+
{
|
| 508 |
+
"content": "<|timbre_24|>",
|
| 509 |
+
"lstrip": false,
|
| 510 |
+
"normalized": false,
|
| 511 |
+
"rstrip": false,
|
| 512 |
+
"single_word": false
|
| 513 |
+
},
|
| 514 |
+
{
|
| 515 |
+
"content": "<|timbre_25|>",
|
| 516 |
+
"lstrip": false,
|
| 517 |
+
"normalized": false,
|
| 518 |
+
"rstrip": false,
|
| 519 |
+
"single_word": false
|
| 520 |
+
},
|
| 521 |
+
{
|
| 522 |
+
"content": "<|timbre_26|>",
|
| 523 |
+
"lstrip": false,
|
| 524 |
+
"normalized": false,
|
| 525 |
+
"rstrip": false,
|
| 526 |
+
"single_word": false
|
| 527 |
+
},
|
| 528 |
+
{
|
| 529 |
+
"content": "<|timbre_27|>",
|
| 530 |
+
"lstrip": false,
|
| 531 |
+
"normalized": false,
|
| 532 |
+
"rstrip": false,
|
| 533 |
+
"single_word": false
|
| 534 |
+
},
|
| 535 |
+
{
|
| 536 |
+
"content": "<|timbre_28|>",
|
| 537 |
+
"lstrip": false,
|
| 538 |
+
"normalized": false,
|
| 539 |
+
"rstrip": false,
|
| 540 |
+
"single_word": false
|
| 541 |
+
},
|
| 542 |
+
{
|
| 543 |
+
"content": "<|timbre_29|>",
|
| 544 |
+
"lstrip": false,
|
| 545 |
+
"normalized": false,
|
| 546 |
+
"rstrip": false,
|
| 547 |
+
"single_word": false
|
| 548 |
+
},
|
| 549 |
+
{
|
| 550 |
+
"content": "<|timbre_30|>",
|
| 551 |
+
"lstrip": false,
|
| 552 |
+
"normalized": false,
|
| 553 |
+
"rstrip": false,
|
| 554 |
+
"single_word": false
|
| 555 |
+
},
|
| 556 |
+
{
|
| 557 |
+
"content": "<|timbre_31|>",
|
| 558 |
+
"lstrip": false,
|
| 559 |
+
"normalized": false,
|
| 560 |
+
"rstrip": false,
|
| 561 |
+
"single_word": false
|
| 562 |
+
}
|
| 563 |
+
],
|
| 564 |
+
"bos_token": "<|im_start|>",
|
| 565 |
+
"eos_token": {
|
| 566 |
+
"content": "<|im_end|>",
|
| 567 |
+
"lstrip": false,
|
| 568 |
+
"normalized": false,
|
| 569 |
+
"rstrip": false,
|
| 570 |
+
"single_word": false
|
| 571 |
+
},
|
| 572 |
+
"pad_token": {
|
| 573 |
+
"content": "<|endoftext|>",
|
| 574 |
+
"lstrip": false,
|
| 575 |
+
"normalized": false,
|
| 576 |
+
"rstrip": false,
|
| 577 |
+
"single_word": false
|
| 578 |
+
},
|
| 579 |
+
"unk_token": "<unk>"
|
| 580 |
+
}
|
tokenization_minicpmo_fast.py
ADDED
|
@@ -0,0 +1,120 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python
|
| 2 |
+
# -*- coding: utf-8 -*-
|
| 3 |
+
# Copyright 2026 The OpenBMB Team. All rights reserved.
|
| 4 |
+
#
|
| 5 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 6 |
+
# you may not use this file except in compliance with the License.
|
| 7 |
+
# You may obtain a copy of the License at
|
| 8 |
+
#
|
| 9 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 10 |
+
#
|
| 11 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 12 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 13 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 14 |
+
# See the License for the specific language governing permissions and
|
| 15 |
+
# limitations under the License.
|
| 16 |
+
|
| 17 |
+
from typing import List
|
| 18 |
+
|
| 19 |
+
from transformers import Qwen2TokenizerFast
|
| 20 |
+
|
| 21 |
+
|
| 22 |
+
class MiniCPMOTokenizerFast(Qwen2TokenizerFast):
|
| 23 |
+
def __init__(self, **kwargs):
|
| 24 |
+
self._bad_token_ids = kwargs.pop("bad_token_ids", [])
|
| 25 |
+
|
| 26 |
+
super().__init__(**kwargs)
|
| 27 |
+
|
| 28 |
+
# image
|
| 29 |
+
self.im_start = "<image>"
|
| 30 |
+
self.im_end = "</image>"
|
| 31 |
+
self.ref_start = "<ref>"
|
| 32 |
+
self.ref_end = "</ref>"
|
| 33 |
+
self.box_start = "<box>"
|
| 34 |
+
self.box_end = "</box>"
|
| 35 |
+
self.quad_start = "<quad>"
|
| 36 |
+
self.quad_end = "</quad>"
|
| 37 |
+
self.slice_start = "<slice>"
|
| 38 |
+
self.slice_end = "</slice>"
|
| 39 |
+
self.im_id_start = "<image_id>"
|
| 40 |
+
self.im_id_end = "</image_id>"
|
| 41 |
+
|
| 42 |
+
# audio
|
| 43 |
+
self.audio_start = "<|audio_start|>"
|
| 44 |
+
self.audio_end = "<|audio_end|>"
|
| 45 |
+
self.spk_start = "<|spk_bos|>"
|
| 46 |
+
self.spk_end = "<|spk_eos|>"
|
| 47 |
+
self.tts_start = "<|tts_bos|>"
|
| 48 |
+
self.tts_end = "<|tts_eos|>"
|
| 49 |
+
|
| 50 |
+
@property
|
| 51 |
+
def eos_id(self):
|
| 52 |
+
return self.eos_token_id
|
| 53 |
+
|
| 54 |
+
@property
|
| 55 |
+
def bos_id(self):
|
| 56 |
+
return self.bos_token_id
|
| 57 |
+
|
| 58 |
+
@property
|
| 59 |
+
def unk_id(self):
|
| 60 |
+
return self.unk_token_id
|
| 61 |
+
|
| 62 |
+
@property
|
| 63 |
+
def im_start_id(self):
|
| 64 |
+
return self.convert_tokens_to_ids(self.im_start)
|
| 65 |
+
|
| 66 |
+
@property
|
| 67 |
+
def im_end_id(self):
|
| 68 |
+
return self.convert_tokens_to_ids(self.im_end)
|
| 69 |
+
|
| 70 |
+
@property
|
| 71 |
+
def slice_start_id(self):
|
| 72 |
+
return self.convert_tokens_to_ids(self.slice_start)
|
| 73 |
+
|
| 74 |
+
@property
|
| 75 |
+
def slice_end_id(self):
|
| 76 |
+
return self.convert_tokens_to_ids(self.slice_end)
|
| 77 |
+
|
| 78 |
+
@property
|
| 79 |
+
def im_id_start_id(self):
|
| 80 |
+
return self.convert_tokens_to_ids(self.im_id_start)
|
| 81 |
+
|
| 82 |
+
@property
|
| 83 |
+
def im_id_end_id(self):
|
| 84 |
+
return self.convert_tokens_to_ids(self.im_id_end)
|
| 85 |
+
|
| 86 |
+
@property
|
| 87 |
+
def audio_start_id(self):
|
| 88 |
+
return self.convert_tokens_to_ids(self.audio_start)
|
| 89 |
+
|
| 90 |
+
@property
|
| 91 |
+
def audio_end_id(self):
|
| 92 |
+
return self.convert_tokens_to_ids(self.audio_end)
|
| 93 |
+
|
| 94 |
+
@property
|
| 95 |
+
def spk_start_id(self):
|
| 96 |
+
return self.convert_tokens_to_ids(self.spk_start)
|
| 97 |
+
|
| 98 |
+
@property
|
| 99 |
+
def spk_end_id(self):
|
| 100 |
+
return self.convert_tokens_to_ids(self.spk_end)
|
| 101 |
+
|
| 102 |
+
@property
|
| 103 |
+
def tts_start_id(self):
|
| 104 |
+
return self.convert_tokens_to_ids(self.tts_start)
|
| 105 |
+
|
| 106 |
+
@property
|
| 107 |
+
def tts_end_id(self):
|
| 108 |
+
return self.convert_tokens_to_ids(self.tts_end)
|
| 109 |
+
|
| 110 |
+
@staticmethod
|
| 111 |
+
def escape(text: str) -> str:
|
| 112 |
+
return text
|
| 113 |
+
|
| 114 |
+
@staticmethod
|
| 115 |
+
def unescape(text: str) -> str:
|
| 116 |
+
return text
|
| 117 |
+
|
| 118 |
+
@property
|
| 119 |
+
def bad_token_ids(self) -> List[int]:
|
| 120 |
+
return self._bad_token_ids
|
tokenizer.json
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:66664f87759d9e829e7ef0ded96976727374dcd7ca6f3ae9bfe89bbda541e5af
|
| 3 |
+
size 11437708
|
tokenizer_config.json
ADDED
|
@@ -0,0 +1,6989 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"add_prefix_space": false,
|
| 3 |
+
"auto_map": {
|
| 4 |
+
"AutoTokenizer": [
|
| 5 |
+
"tokenization_minicpmo_fast.MiniCPMOTokenizerFast",
|
| 6 |
+
null
|
| 7 |
+
]
|
| 8 |
+
},
|
| 9 |
+
"backend": "tokenizers",
|
| 10 |
+
"bad_token_ids": [
|
| 11 |
+
7,
|
| 12 |
+
8,
|
| 13 |
+
94,
|
| 14 |
+
95,
|
| 15 |
+
96,
|
| 16 |
+
97,
|
| 17 |
+
98,
|
| 18 |
+
99,
|
| 19 |
+
100,
|
| 20 |
+
101,
|
| 21 |
+
102,
|
| 22 |
+
103,
|
| 23 |
+
104,
|
| 24 |
+
105,
|
| 25 |
+
106,
|
| 26 |
+
107,
|
| 27 |
+
108,
|
| 28 |
+
109,
|
| 29 |
+
110,
|
| 30 |
+
111,
|
| 31 |
+
112,
|
| 32 |
+
113,
|
| 33 |
+
114,
|
| 34 |
+
115,
|
| 35 |
+
116,
|
| 36 |
+
117,
|
| 37 |
+
118,
|
| 38 |
+
119,
|
| 39 |
+
120,
|
| 40 |
+
121,
|
| 41 |
+
122,
|
| 42 |
+
123,
|
| 43 |
+
124,
|
| 44 |
+
125,
|
| 45 |
+
126,
|
| 46 |
+
127,
|
| 47 |
+
128,
|
| 48 |
+
129,
|
| 49 |
+
130,
|
| 50 |
+
131,
|
| 51 |
+
132,
|
| 52 |
+
133,
|
| 53 |
+
134,
|
| 54 |
+
135,
|
| 55 |
+
136,
|
| 56 |
+
137,
|
| 57 |
+
138,
|
| 58 |
+
139,
|
| 59 |
+
140,
|
| 60 |
+
141,
|
| 61 |
+
142,
|
| 62 |
+
143,
|
| 63 |
+
144,
|
| 64 |
+
145,
|
| 65 |
+
146,
|
| 66 |
+
147,
|
| 67 |
+
148,
|
| 68 |
+
149,
|
| 69 |
+
150,
|
| 70 |
+
151,
|
| 71 |
+
152,
|
| 72 |
+
153,
|
| 73 |
+
154,
|
| 74 |
+
155,
|
| 75 |
+
156,
|
| 76 |
+
157,
|
| 77 |
+
158,
|
| 78 |
+
159,
|
| 79 |
+
160,
|
| 80 |
+
161,
|
| 81 |
+
162,
|
| 82 |
+
163,
|
| 83 |
+
164,
|
| 84 |
+
165,
|
| 85 |
+
166,
|
| 86 |
+
167,
|
| 87 |
+
168,
|
| 88 |
+
169,
|
| 89 |
+
170,
|
| 90 |
+
171,
|
| 91 |
+
172,
|
| 92 |
+
173,
|
| 93 |
+
174,
|
| 94 |
+
175,
|
| 95 |
+
176,
|
| 96 |
+
177,
|
| 97 |
+
178,
|
| 98 |
+
179,
|
| 99 |
+
180,
|
| 100 |
+
181,
|
| 101 |
+
182,
|
| 102 |
+
183,
|
| 103 |
+
184,
|
| 104 |
+
185,
|
| 105 |
+
186,
|
| 106 |
+
187,
|
| 107 |
+
198,
|
| 108 |
+
201,
|
| 109 |
+
222,
|
| 110 |
+
223,
|
| 111 |
+
224,
|
| 112 |
+
225,
|
| 113 |
+
226,
|
| 114 |
+
227,
|
| 115 |
+
228,
|
| 116 |
+
229,
|
| 117 |
+
230,
|
| 118 |
+
231,
|
| 119 |
+
232,
|
| 120 |
+
233,
|
| 121 |
+
234,
|
| 122 |
+
235,
|
| 123 |
+
236,
|
| 124 |
+
237,
|
| 125 |
+
238,
|
| 126 |
+
239,
|
| 127 |
+
240,
|
| 128 |
+
241,
|
| 129 |
+
242,
|
| 130 |
+
243,
|
| 131 |
+
244,
|
| 132 |
+
245,
|
| 133 |
+
246,
|
| 134 |
+
247,
|
| 135 |
+
248,
|
| 136 |
+
249,
|
| 137 |
+
250,
|
| 138 |
+
251,
|
| 139 |
+
252,
|
| 140 |
+
253,
|
| 141 |
+
254,
|
| 142 |
+
255,
|
| 143 |
+
271,
|
| 144 |
+
280,
|
| 145 |
+
317,
|
| 146 |
+
319,
|
| 147 |
+
320,
|
| 148 |
+
340,
|
| 149 |
+
341,
|
| 150 |
+
345,
|
| 151 |
+
368,
|
| 152 |
+
378,
|
| 153 |
+
382,
|
| 154 |
+
397,
|
| 155 |
+
401,
|
| 156 |
+
445,
|
| 157 |
+
456,
|
| 158 |
+
463,
|
| 159 |
+
492,
|
| 160 |
+
510,
|
| 161 |
+
515,
|
| 162 |
+
532,
|
| 163 |
+
543,
|
| 164 |
+
555,
|
| 165 |
+
568,
|
| 166 |
+
593,
|
| 167 |
+
624,
|
| 168 |
+
626,
|
| 169 |
+
630,
|
| 170 |
+
636,
|
| 171 |
+
692,
|
| 172 |
+
698,
|
| 173 |
+
699,
|
| 174 |
+
701,
|
| 175 |
+
715,
|
| 176 |
+
735,
|
| 177 |
+
736,
|
| 178 |
+
741,
|
| 179 |
+
751,
|
| 180 |
+
756,
|
| 181 |
+
797,
|
| 182 |
+
863,
|
| 183 |
+
871,
|
| 184 |
+
873,
|
| 185 |
+
876,
|
| 186 |
+
881,
|
| 187 |
+
899,
|
| 188 |
+
921,
|
| 189 |
+
935,
|
| 190 |
+
955,
|
| 191 |
+
972,
|
| 192 |
+
982,
|
| 193 |
+
1005,
|
| 194 |
+
1006,
|
| 195 |
+
1010,
|
| 196 |
+
1019,
|
| 197 |
+
1022,
|
| 198 |
+
1066,
|
| 199 |
+
1106,
|
| 200 |
+
1138,
|
| 201 |
+
1141,
|
| 202 |
+
1153,
|
| 203 |
+
1155,
|
| 204 |
+
1157,
|
| 205 |
+
1171,
|
| 206 |
+
1188,
|
| 207 |
+
1193,
|
| 208 |
+
1213,
|
| 209 |
+
1215,
|
| 210 |
+
1218,
|
| 211 |
+
1248,
|
| 212 |
+
1255,
|
| 213 |
+
1259,
|
| 214 |
+
1264,
|
| 215 |
+
1277,
|
| 216 |
+
1278,
|
| 217 |
+
1295,
|
| 218 |
+
1305,
|
| 219 |
+
1326,
|
| 220 |
+
1337,
|
| 221 |
+
1339,
|
| 222 |
+
1394,
|
| 223 |
+
1406,
|
| 224 |
+
1423,
|
| 225 |
+
1428,
|
| 226 |
+
1433,
|
| 227 |
+
1439,
|
| 228 |
+
1445,
|
| 229 |
+
1447,
|
| 230 |
+
1476,
|
| 231 |
+
1500,
|
| 232 |
+
1505,
|
| 233 |
+
1507,
|
| 234 |
+
1540,
|
| 235 |
+
1548,
|
| 236 |
+
1554,
|
| 237 |
+
1572,
|
| 238 |
+
1583,
|
| 239 |
+
1625,
|
| 240 |
+
1647,
|
| 241 |
+
1648,
|
| 242 |
+
1666,
|
| 243 |
+
1683,
|
| 244 |
+
1686,
|
| 245 |
+
1711,
|
| 246 |
+
1719,
|
| 247 |
+
1727,
|
| 248 |
+
1747,
|
| 249 |
+
1755,
|
| 250 |
+
1771,
|
| 251 |
+
1781,
|
| 252 |
+
1789,
|
| 253 |
+
1823,
|
| 254 |
+
1827,
|
| 255 |
+
1837,
|
| 256 |
+
1871,
|
| 257 |
+
1883,
|
| 258 |
+
1926,
|
| 259 |
+
1939,
|
| 260 |
+
1956,
|
| 261 |
+
2012,
|
| 262 |
+
2026,
|
| 263 |
+
2075,
|
| 264 |
+
2099,
|
| 265 |
+
2129,
|
| 266 |
+
2139,
|
| 267 |
+
2140,
|
| 268 |
+
2146,
|
| 269 |
+
2194,
|
| 270 |
+
2217,
|
| 271 |
+
2219,
|
| 272 |
+
2226,
|
| 273 |
+
2235,
|
| 274 |
+
2242,
|
| 275 |
+
2262,
|
| 276 |
+
2278,
|
| 277 |
+
2289,
|
| 278 |
+
2303,
|
| 279 |
+
2306,
|
| 280 |
+
2315,
|
| 281 |
+
2333,
|
| 282 |
+
2357,
|
| 283 |
+
2376,
|
| 284 |
+
2394,
|
| 285 |
+
2398,
|
| 286 |
+
2399,
|
| 287 |
+
2440,
|
| 288 |
+
2457,
|
| 289 |
+
2467,
|
| 290 |
+
2490,
|
| 291 |
+
2529,
|
| 292 |
+
2533,
|
| 293 |
+
2546,
|
| 294 |
+
2553,
|
| 295 |
+
2558,
|
| 296 |
+
2561,
|
| 297 |
+
2570,
|
| 298 |
+
2586,
|
| 299 |
+
2592,
|
| 300 |
+
2597,
|
| 301 |
+
2601,
|
| 302 |
+
2605,
|
| 303 |
+
2741,
|
| 304 |
+
2751,
|
| 305 |
+
2759,
|
| 306 |
+
2761,
|
| 307 |
+
2775,
|
| 308 |
+
2785,
|
| 309 |
+
2791,
|
| 310 |
+
2815,
|
| 311 |
+
2822,
|
| 312 |
+
2834,
|
| 313 |
+
2837,
|
| 314 |
+
2858,
|
| 315 |
+
2877,
|
| 316 |
+
2879,
|
| 317 |
+
2920,
|
| 318 |
+
2960,
|
| 319 |
+
3011,
|
| 320 |
+
3023,
|
| 321 |
+
3025,
|
| 322 |
+
3032,
|
| 323 |
+
3044,
|
| 324 |
+
3071,
|
| 325 |
+
3079,
|
| 326 |
+
3148,
|
| 327 |
+
3153,
|
| 328 |
+
3189,
|
| 329 |
+
3190,
|
| 330 |
+
3203,
|
| 331 |
+
3211,
|
| 332 |
+
3219,
|
| 333 |
+
3224,
|
| 334 |
+
3237,
|
| 335 |
+
3268,
|
| 336 |
+
3269,
|
| 337 |
+
3276,
|
| 338 |
+
3284,
|
| 339 |
+
3299,
|
| 340 |
+
3302,
|
| 341 |
+
3315,
|
| 342 |
+
3325,
|
| 343 |
+
3374,
|
| 344 |
+
3396,
|
| 345 |
+
3402,
|
| 346 |
+
3407,
|
| 347 |
+
3456,
|
| 348 |
+
3471,
|
| 349 |
+
3475,
|
| 350 |
+
3485,
|
| 351 |
+
3489,
|
| 352 |
+
3490,
|
| 353 |
+
3507,
|
| 354 |
+
3515,
|
| 355 |
+
3518,
|
| 356 |
+
3534,
|
| 357 |
+
3554,
|
| 358 |
+
3568,
|
| 359 |
+
3576,
|
| 360 |
+
3584,
|
| 361 |
+
3593,
|
| 362 |
+
3609,
|
| 363 |
+
3610,
|
| 364 |
+
3622,
|
| 365 |
+
3623,
|
| 366 |
+
3634,
|
| 367 |
+
3646,
|
| 368 |
+
3648,
|
| 369 |
+
3659,
|
| 370 |
+
3679,
|
| 371 |
+
3715,
|
| 372 |
+
3724,
|
| 373 |
+
3733,
|
| 374 |
+
3747,
|
| 375 |
+
3755,
|
| 376 |
+
3759,
|
| 377 |
+
3764,
|
| 378 |
+
3789,
|
| 379 |
+
3804,
|
| 380 |
+
3860,
|
| 381 |
+
3870,
|
| 382 |
+
3876,
|
| 383 |
+
3879,
|
| 384 |
+
3913,
|
| 385 |
+
3932,
|
| 386 |
+
3964,
|
| 387 |
+
3975,
|
| 388 |
+
3989,
|
| 389 |
+
3997,
|
| 390 |
+
4010,
|
| 391 |
+
4015,
|
| 392 |
+
4035,
|
| 393 |
+
4071,
|
| 394 |
+
4080,
|
| 395 |
+
4140,
|
| 396 |
+
4167,
|
| 397 |
+
4175,
|
| 398 |
+
4192,
|
| 399 |
+
4199,
|
| 400 |
+
4257,
|
| 401 |
+
4277,
|
| 402 |
+
4283,
|
| 403 |
+
4291,
|
| 404 |
+
4292,
|
| 405 |
+
4319,
|
| 406 |
+
4333,
|
| 407 |
+
4346,
|
| 408 |
+
4380,
|
| 409 |
+
4386,
|
| 410 |
+
4390,
|
| 411 |
+
4397,
|
| 412 |
+
4424,
|
| 413 |
+
4430,
|
| 414 |
+
4432,
|
| 415 |
+
4455,
|
| 416 |
+
4456,
|
| 417 |
+
4461,
|
| 418 |
+
4474,
|
| 419 |
+
4539,
|
| 420 |
+
4546,
|
| 421 |
+
4555,
|
| 422 |
+
4557,
|
| 423 |
+
4567,
|
| 424 |
+
4579,
|
| 425 |
+
4590,
|
| 426 |
+
4609,
|
| 427 |
+
4610,
|
| 428 |
+
4639,
|
| 429 |
+
4660,
|
| 430 |
+
4667,
|
| 431 |
+
4710,
|
| 432 |
+
4723,
|
| 433 |
+
4806,
|
| 434 |
+
4811,
|
| 435 |
+
4821,
|
| 436 |
+
4857,
|
| 437 |
+
4860,
|
| 438 |
+
4866,
|
| 439 |
+
4875,
|
| 440 |
+
4877,
|
| 441 |
+
4891,
|
| 442 |
+
4894,
|
| 443 |
+
4919,
|
| 444 |
+
4921,
|
| 445 |
+
4930,
|
| 446 |
+
4945,
|
| 447 |
+
4956,
|
| 448 |
+
4957,
|
| 449 |
+
4967,
|
| 450 |
+
4973,
|
| 451 |
+
5031,
|
| 452 |
+
5038,
|
| 453 |
+
5065,
|
| 454 |
+
5078,
|
| 455 |
+
5125,
|
| 456 |
+
5130,
|
| 457 |
+
5133,
|
| 458 |
+
5134,
|
| 459 |
+
5140,
|
| 460 |
+
5194,
|
| 461 |
+
5210,
|
| 462 |
+
5231,
|
| 463 |
+
5267,
|
| 464 |
+
5304,
|
| 465 |
+
5349,
|
| 466 |
+
5378,
|
| 467 |
+
5384,
|
| 468 |
+
5393,
|
| 469 |
+
5410,
|
| 470 |
+
5422,
|
| 471 |
+
5432,
|
| 472 |
+
5433,
|
| 473 |
+
5434,
|
| 474 |
+
5438,
|
| 475 |
+
5453,
|
| 476 |
+
5455,
|
| 477 |
+
5463,
|
| 478 |
+
5468,
|
| 479 |
+
5484,
|
| 480 |
+
5502,
|
| 481 |
+
5513,
|
| 482 |
+
5550,
|
| 483 |
+
5563,
|
| 484 |
+
5564,
|
| 485 |
+
5581,
|
| 486 |
+
5613,
|
| 487 |
+
5618,
|
| 488 |
+
5620,
|
| 489 |
+
5661,
|
| 490 |
+
5680,
|
| 491 |
+
5684,
|
| 492 |
+
5691,
|
| 493 |
+
5731,
|
| 494 |
+
5758,
|
| 495 |
+
5783,
|
| 496 |
+
5784,
|
| 497 |
+
5801,
|
| 498 |
+
5808,
|
| 499 |
+
5809,
|
| 500 |
+
5860,
|
| 501 |
+
5872,
|
| 502 |
+
5894,
|
| 503 |
+
5895,
|
| 504 |
+
5900,
|
| 505 |
+
5902,
|
| 506 |
+
5905,
|
| 507 |
+
5907,
|
| 508 |
+
5928,
|
| 509 |
+
5929,
|
| 510 |
+
5945,
|
| 511 |
+
5953,
|
| 512 |
+
5957,
|
| 513 |
+
5959,
|
| 514 |
+
5960,
|
| 515 |
+
5966,
|
| 516 |
+
5969,
|
| 517 |
+
5993,
|
| 518 |
+
6011,
|
| 519 |
+
6060,
|
| 520 |
+
6098,
|
| 521 |
+
6107,
|
| 522 |
+
6110,
|
| 523 |
+
6114,
|
| 524 |
+
6138,
|
| 525 |
+
6142,
|
| 526 |
+
6163,
|
| 527 |
+
6201,
|
| 528 |
+
6204,
|
| 529 |
+
6211,
|
| 530 |
+
6228,
|
| 531 |
+
6235,
|
| 532 |
+
6253,
|
| 533 |
+
6260,
|
| 534 |
+
6274,
|
| 535 |
+
6320,
|
| 536 |
+
6332,
|
| 537 |
+
6336,
|
| 538 |
+
6360,
|
| 539 |
+
6390,
|
| 540 |
+
6413,
|
| 541 |
+
6416,
|
| 542 |
+
6421,
|
| 543 |
+
6425,
|
| 544 |
+
6475,
|
| 545 |
+
6518,
|
| 546 |
+
6522,
|
| 547 |
+
6557,
|
| 548 |
+
6561,
|
| 549 |
+
6564,
|
| 550 |
+
6567,
|
| 551 |
+
6571,
|
| 552 |
+
6599,
|
| 553 |
+
6606,
|
| 554 |
+
6620,
|
| 555 |
+
6636,
|
| 556 |
+
6684,
|
| 557 |
+
6699,
|
| 558 |
+
6734,
|
| 559 |
+
6762,
|
| 560 |
+
6779,
|
| 561 |
+
6796,
|
| 562 |
+
6856,
|
| 563 |
+
6870,
|
| 564 |
+
6881,
|
| 565 |
+
6882,
|
| 566 |
+
6901,
|
| 567 |
+
6903,
|
| 568 |
+
6913,
|
| 569 |
+
6926,
|
| 570 |
+
6933,
|
| 571 |
+
6958,
|
| 572 |
+
6965,
|
| 573 |
+
6987,
|
| 574 |
+
7021,
|
| 575 |
+
7026,
|
| 576 |
+
7045,
|
| 577 |
+
7088,
|
| 578 |
+
7115,
|
| 579 |
+
7129,
|
| 580 |
+
7144,
|
| 581 |
+
7158,
|
| 582 |
+
7165,
|
| 583 |
+
7195,
|
| 584 |
+
7213,
|
| 585 |
+
7229,
|
| 586 |
+
7235,
|
| 587 |
+
7252,
|
| 588 |
+
7257,
|
| 589 |
+
7287,
|
| 590 |
+
7307,
|
| 591 |
+
7311,
|
| 592 |
+
7317,
|
| 593 |
+
7318,
|
| 594 |
+
7320,
|
| 595 |
+
7331,
|
| 596 |
+
7333,
|
| 597 |
+
7356,
|
| 598 |
+
7360,
|
| 599 |
+
7367,
|
| 600 |
+
7368,
|
| 601 |
+
7392,
|
| 602 |
+
7457,
|
| 603 |
+
7492,
|
| 604 |
+
7502,
|
| 605 |
+
7511,
|
| 606 |
+
7520,
|
| 607 |
+
7534,
|
| 608 |
+
7536,
|
| 609 |
+
7537,
|
| 610 |
+
7547,
|
| 611 |
+
7552,
|
| 612 |
+
7569,
|
| 613 |
+
7588,
|
| 614 |
+
7613,
|
| 615 |
+
7620,
|
| 616 |
+
7624,
|
| 617 |
+
7631,
|
| 618 |
+
7635,
|
| 619 |
+
7644,
|
| 620 |
+
7694,
|
| 621 |
+
7705,
|
| 622 |
+
7723,
|
| 623 |
+
7731,
|
| 624 |
+
7805,
|
| 625 |
+
7832,
|
| 626 |
+
7835,
|
| 627 |
+
7851,
|
| 628 |
+
7885,
|
| 629 |
+
7908,
|
| 630 |
+
8006,
|
| 631 |
+
8013,
|
| 632 |
+
8022,
|
| 633 |
+
8032,
|
| 634 |
+
8068,
|
| 635 |
+
8079,
|
| 636 |
+
8096,
|
| 637 |
+
8097,
|
| 638 |
+
8119,
|
| 639 |
+
8132,
|
| 640 |
+
8154,
|
| 641 |
+
8158,
|
| 642 |
+
8204,
|
| 643 |
+
8244,
|
| 644 |
+
8268,
|
| 645 |
+
8283,
|
| 646 |
+
8306,
|
| 647 |
+
8324,
|
| 648 |
+
8361,
|
| 649 |
+
8389,
|
| 650 |
+
8390,
|
| 651 |
+
8401,
|
| 652 |
+
8488,
|
| 653 |
+
8508,
|
| 654 |
+
8519,
|
| 655 |
+
8525,
|
| 656 |
+
8533,
|
| 657 |
+
8563,
|
| 658 |
+
8588,
|
| 659 |
+
8616,
|
| 660 |
+
8620,
|
| 661 |
+
8623,
|
| 662 |
+
8637,
|
| 663 |
+
8680,
|
| 664 |
+
8739,
|
| 665 |
+
8754,
|
| 666 |
+
8762,
|
| 667 |
+
8797,
|
| 668 |
+
8803,
|
| 669 |
+
8805,
|
| 670 |
+
8824,
|
| 671 |
+
8839,
|
| 672 |
+
8843,
|
| 673 |
+
8902,
|
| 674 |
+
8908,
|
| 675 |
+
8917,
|
| 676 |
+
8945,
|
| 677 |
+
8956,
|
| 678 |
+
8972,
|
| 679 |
+
8997,
|
| 680 |
+
8998,
|
| 681 |
+
9035,
|
| 682 |
+
9049,
|
| 683 |
+
9098,
|
| 684 |
+
9139,
|
| 685 |
+
9147,
|
| 686 |
+
9206,
|
| 687 |
+
9231,
|
| 688 |
+
9248,
|
| 689 |
+
9260,
|
| 690 |
+
9272,
|
| 691 |
+
9284,
|
| 692 |
+
9304,
|
| 693 |
+
9321,
|
| 694 |
+
9338,
|
| 695 |
+
9340,
|
| 696 |
+
9365,
|
| 697 |
+
9401,
|
| 698 |
+
9404,
|
| 699 |
+
9469,
|
| 700 |
+
9470,
|
| 701 |
+
9531,
|
| 702 |
+
9533,
|
| 703 |
+
9541,
|
| 704 |
+
9563,
|
| 705 |
+
9568,
|
| 706 |
+
9577,
|
| 707 |
+
9604,
|
| 708 |
+
9607,
|
| 709 |
+
9623,
|
| 710 |
+
9638,
|
| 711 |
+
9639,
|
| 712 |
+
9640,
|
| 713 |
+
9697,
|
| 714 |
+
9719,
|
| 715 |
+
9722,
|
| 716 |
+
9730,
|
| 717 |
+
9739,
|
| 718 |
+
9743,
|
| 719 |
+
9747,
|
| 720 |
+
9758,
|
| 721 |
+
9764,
|
| 722 |
+
9791,
|
| 723 |
+
9828,
|
| 724 |
+
9843,
|
| 725 |
+
9849,
|
| 726 |
+
9879,
|
| 727 |
+
9900,
|
| 728 |
+
9909,
|
| 729 |
+
9912,
|
| 730 |
+
9921,
|
| 731 |
+
9940,
|
| 732 |
+
9957,
|
| 733 |
+
9973,
|
| 734 |
+
9992,
|
| 735 |
+
10040,
|
| 736 |
+
10075,
|
| 737 |
+
10079,
|
| 738 |
+
10081,
|
| 739 |
+
10086,
|
| 740 |
+
10108,
|
| 741 |
+
10116,
|
| 742 |
+
10131,
|
| 743 |
+
10133,
|
| 744 |
+
10149,
|
| 745 |
+
10170,
|
| 746 |
+
10171,
|
| 747 |
+
10203,
|
| 748 |
+
10236,
|
| 749 |
+
10239,
|
| 750 |
+
10278,
|
| 751 |
+
10293,
|
| 752 |
+
10297,
|
| 753 |
+
10340,
|
| 754 |
+
10343,
|
| 755 |
+
10346,
|
| 756 |
+
10368,
|
| 757 |
+
10370,
|
| 758 |
+
10384,
|
| 759 |
+
10389,
|
| 760 |
+
10407,
|
| 761 |
+
10417,
|
| 762 |
+
10419,
|
| 763 |
+
10444,
|
| 764 |
+
10448,
|
| 765 |
+
10452,
|
| 766 |
+
10478,
|
| 767 |
+
10483,
|
| 768 |
+
10556,
|
| 769 |
+
10569,
|
| 770 |
+
10583,
|
| 771 |
+
10595,
|
| 772 |
+
10624,
|
| 773 |
+
10639,
|
| 774 |
+
10662,
|
| 775 |
+
10663,
|
| 776 |
+
10683,
|
| 777 |
+
10697,
|
| 778 |
+
10699,
|
| 779 |
+
10722,
|
| 780 |
+
10727,
|
| 781 |
+
10731,
|
| 782 |
+
10741,
|
| 783 |
+
10764,
|
| 784 |
+
10768,
|
| 785 |
+
10874,
|
| 786 |
+
10896,
|
| 787 |
+
10907,
|
| 788 |
+
10937,
|
| 789 |
+
10939,
|
| 790 |
+
10941,
|
| 791 |
+
10947,
|
| 792 |
+
10952,
|
| 793 |
+
10959,
|
| 794 |
+
10961,
|
| 795 |
+
10977,
|
| 796 |
+
10996,
|
| 797 |
+
11014,
|
| 798 |
+
11022,
|
| 799 |
+
11024,
|
| 800 |
+
11043,
|
| 801 |
+
11057,
|
| 802 |
+
11120,
|
| 803 |
+
11125,
|
| 804 |
+
11132,
|
| 805 |
+
11142,
|
| 806 |
+
11146,
|
| 807 |
+
11162,
|
| 808 |
+
11166,
|
| 809 |
+
11173,
|
| 810 |
+
11195,
|
| 811 |
+
11248,
|
| 812 |
+
11322,
|
| 813 |
+
11328,
|
| 814 |
+
11334,
|
| 815 |
+
11336,
|
| 816 |
+
11378,
|
| 817 |
+
11384,
|
| 818 |
+
11436,
|
| 819 |
+
11462,
|
| 820 |
+
11481,
|
| 821 |
+
11484,
|
| 822 |
+
11488,
|
| 823 |
+
11512,
|
| 824 |
+
11520,
|
| 825 |
+
11534,
|
| 826 |
+
11557,
|
| 827 |
+
11559,
|
| 828 |
+
11583,
|
| 829 |
+
11600,
|
| 830 |
+
11614,
|
| 831 |
+
11620,
|
| 832 |
+
11621,
|
| 833 |
+
11648,
|
| 834 |
+
11688,
|
| 835 |
+
11700,
|
| 836 |
+
11730,
|
| 837 |
+
11743,
|
| 838 |
+
11776,
|
| 839 |
+
11781,
|
| 840 |
+
11801,
|
| 841 |
+
11805,
|
| 842 |
+
11843,
|
| 843 |
+
11858,
|
| 844 |
+
11884,
|
| 845 |
+
11895,
|
| 846 |
+
11970,
|
| 847 |
+
11973,
|
| 848 |
+
11974,
|
| 849 |
+
11985,
|
| 850 |
+
11993,
|
| 851 |
+
11995,
|
| 852 |
+
12006,
|
| 853 |
+
12022,
|
| 854 |
+
12024,
|
| 855 |
+
12047,
|
| 856 |
+
12078,
|
| 857 |
+
12084,
|
| 858 |
+
12113,
|
| 859 |
+
12130,
|
| 860 |
+
12143,
|
| 861 |
+
12145,
|
| 862 |
+
12148,
|
| 863 |
+
12186,
|
| 864 |
+
12236,
|
| 865 |
+
12259,
|
| 866 |
+
12266,
|
| 867 |
+
12274,
|
| 868 |
+
12279,
|
| 869 |
+
12286,
|
| 870 |
+
12298,
|
| 871 |
+
12306,
|
| 872 |
+
12310,
|
| 873 |
+
12317,
|
| 874 |
+
12367,
|
| 875 |
+
12381,
|
| 876 |
+
12397,
|
| 877 |
+
12410,
|
| 878 |
+
12431,
|
| 879 |
+
12437,
|
| 880 |
+
12470,
|
| 881 |
+
12489,
|
| 882 |
+
12491,
|
| 883 |
+
12504,
|
| 884 |
+
12512,
|
| 885 |
+
12520,
|
| 886 |
+
12526,
|
| 887 |
+
12530,
|
| 888 |
+
12531,
|
| 889 |
+
12533,
|
| 890 |
+
12573,
|
| 891 |
+
12584,
|
| 892 |
+
12585,
|
| 893 |
+
12587,
|
| 894 |
+
12602,
|
| 895 |
+
12619,
|
| 896 |
+
12628,
|
| 897 |
+
12663,
|
| 898 |
+
12668,
|
| 899 |
+
12706,
|
| 900 |
+
12760,
|
| 901 |
+
12787,
|
| 902 |
+
12797,
|
| 903 |
+
12798,
|
| 904 |
+
12805,
|
| 905 |
+
12806,
|
| 906 |
+
12832,
|
| 907 |
+
12860,
|
| 908 |
+
12861,
|
| 909 |
+
12892,
|
| 910 |
+
12918,
|
| 911 |
+
12924,
|
| 912 |
+
12950,
|
| 913 |
+
12951,
|
| 914 |
+
12954,
|
| 915 |
+
13003,
|
| 916 |
+
13005,
|
| 917 |
+
13053,
|
| 918 |
+
13056,
|
| 919 |
+
13058,
|
| 920 |
+
13087,
|
| 921 |
+
13092,
|
| 922 |
+
13106,
|
| 923 |
+
13116,
|
| 924 |
+
13135,
|
| 925 |
+
13148,
|
| 926 |
+
13165,
|
| 927 |
+
13174,
|
| 928 |
+
13201,
|
| 929 |
+
13204,
|
| 930 |
+
13211,
|
| 931 |
+
13246,
|
| 932 |
+
13268,
|
| 933 |
+
13274,
|
| 934 |
+
13285,
|
| 935 |
+
13287,
|
| 936 |
+
13321,
|
| 937 |
+
13338,
|
| 938 |
+
13344,
|
| 939 |
+
13345,
|
| 940 |
+
13362,
|
| 941 |
+
13426,
|
| 942 |
+
13441,
|
| 943 |
+
13453,
|
| 944 |
+
13456,
|
| 945 |
+
13465,
|
| 946 |
+
13493,
|
| 947 |
+
13512,
|
| 948 |
+
13519,
|
| 949 |
+
13531,
|
| 950 |
+
13555,
|
| 951 |
+
13558,
|
| 952 |
+
13567,
|
| 953 |
+
13645,
|
| 954 |
+
13698,
|
| 955 |
+
13744,
|
| 956 |
+
13749,
|
| 957 |
+
13836,
|
| 958 |
+
13838,
|
| 959 |
+
13846,
|
| 960 |
+
13861,
|
| 961 |
+
13869,
|
| 962 |
+
13887,
|
| 963 |
+
13913,
|
| 964 |
+
13921,
|
| 965 |
+
13941,
|
| 966 |
+
13949,
|
| 967 |
+
13976,
|
| 968 |
+
13982,
|
| 969 |
+
13988,
|
| 970 |
+
14001,
|
| 971 |
+
14013,
|
| 972 |
+
14015,
|
| 973 |
+
14031,
|
| 974 |
+
14088,
|
| 975 |
+
14090,
|
| 976 |
+
14094,
|
| 977 |
+
14108,
|
| 978 |
+
14146,
|
| 979 |
+
14160,
|
| 980 |
+
14161,
|
| 981 |
+
14167,
|
| 982 |
+
14171,
|
| 983 |
+
14208,
|
| 984 |
+
14217,
|
| 985 |
+
14223,
|
| 986 |
+
14273,
|
| 987 |
+
14280,
|
| 988 |
+
14288,
|
| 989 |
+
14326,
|
| 990 |
+
14328,
|
| 991 |
+
14333,
|
| 992 |
+
14362,
|
| 993 |
+
14368,
|
| 994 |
+
14382,
|
| 995 |
+
14414,
|
| 996 |
+
14426,
|
| 997 |
+
14437,
|
| 998 |
+
14442,
|
| 999 |
+
14451,
|
| 1000 |
+
14467,
|
| 1001 |
+
14498,
|
| 1002 |
+
14512,
|
| 1003 |
+
14520,
|
| 1004 |
+
14546,
|
| 1005 |
+
14559,
|
| 1006 |
+
14573,
|
| 1007 |
+
14599,
|
| 1008 |
+
14618,
|
| 1009 |
+
14621,
|
| 1010 |
+
14654,
|
| 1011 |
+
14669,
|
| 1012 |
+
14675,
|
| 1013 |
+
14676,
|
| 1014 |
+
14687,
|
| 1015 |
+
14702,
|
| 1016 |
+
14705,
|
| 1017 |
+
14711,
|
| 1018 |
+
14731,
|
| 1019 |
+
14750,
|
| 1020 |
+
14808,
|
| 1021 |
+
14818,
|
| 1022 |
+
14922,
|
| 1023 |
+
14925,
|
| 1024 |
+
14929,
|
| 1025 |
+
14936,
|
| 1026 |
+
14942,
|
| 1027 |
+
14959,
|
| 1028 |
+
14979,
|
| 1029 |
+
14998,
|
| 1030 |
+
15005,
|
| 1031 |
+
15014,
|
| 1032 |
+
15028,
|
| 1033 |
+
15046,
|
| 1034 |
+
15047,
|
| 1035 |
+
15049,
|
| 1036 |
+
15063,
|
| 1037 |
+
15075,
|
| 1038 |
+
15076,
|
| 1039 |
+
15078,
|
| 1040 |
+
15084,
|
| 1041 |
+
15087,
|
| 1042 |
+
15096,
|
| 1043 |
+
15127,
|
| 1044 |
+
15143,
|
| 1045 |
+
15146,
|
| 1046 |
+
15157,
|
| 1047 |
+
15197,
|
| 1048 |
+
15213,
|
| 1049 |
+
15224,
|
| 1050 |
+
15225,
|
| 1051 |
+
15238,
|
| 1052 |
+
15240,
|
| 1053 |
+
15253,
|
| 1054 |
+
15290,
|
| 1055 |
+
15297,
|
| 1056 |
+
15299,
|
| 1057 |
+
15306,
|
| 1058 |
+
15329,
|
| 1059 |
+
15348,
|
| 1060 |
+
15362,
|
| 1061 |
+
15374,
|
| 1062 |
+
15393,
|
| 1063 |
+
15397,
|
| 1064 |
+
15414,
|
| 1065 |
+
15424,
|
| 1066 |
+
15434,
|
| 1067 |
+
15436,
|
| 1068 |
+
15441,
|
| 1069 |
+
15452,
|
| 1070 |
+
15483,
|
| 1071 |
+
15514,
|
| 1072 |
+
15538,
|
| 1073 |
+
15573,
|
| 1074 |
+
15600,
|
| 1075 |
+
15617,
|
| 1076 |
+
15620,
|
| 1077 |
+
15639,
|
| 1078 |
+
15674,
|
| 1079 |
+
15675,
|
| 1080 |
+
15677,
|
| 1081 |
+
15694,
|
| 1082 |
+
15716,
|
| 1083 |
+
15746,
|
| 1084 |
+
15752,
|
| 1085 |
+
15761,
|
| 1086 |
+
15766,
|
| 1087 |
+
15785,
|
| 1088 |
+
15793,
|
| 1089 |
+
15798,
|
| 1090 |
+
15799,
|
| 1091 |
+
15827,
|
| 1092 |
+
15842,
|
| 1093 |
+
15852,
|
| 1094 |
+
15861,
|
| 1095 |
+
15865,
|
| 1096 |
+
15896,
|
| 1097 |
+
15899,
|
| 1098 |
+
15902,
|
| 1099 |
+
15906,
|
| 1100 |
+
15912,
|
| 1101 |
+
15921,
|
| 1102 |
+
15927,
|
| 1103 |
+
15956,
|
| 1104 |
+
15979,
|
| 1105 |
+
15984,
|
| 1106 |
+
15989,
|
| 1107 |
+
16018,
|
| 1108 |
+
16043,
|
| 1109 |
+
16057,
|
| 1110 |
+
16060,
|
| 1111 |
+
16075,
|
| 1112 |
+
16094,
|
| 1113 |
+
16117,
|
| 1114 |
+
16159,
|
| 1115 |
+
16160,
|
| 1116 |
+
16179,
|
| 1117 |
+
16218,
|
| 1118 |
+
16235,
|
| 1119 |
+
16240,
|
| 1120 |
+
16264,
|
| 1121 |
+
16315,
|
| 1122 |
+
16324,
|
| 1123 |
+
16360,
|
| 1124 |
+
16361,
|
| 1125 |
+
16368,
|
| 1126 |
+
16418,
|
| 1127 |
+
16425,
|
| 1128 |
+
16448,
|
| 1129 |
+
16466,
|
| 1130 |
+
16499,
|
| 1131 |
+
16511,
|
| 1132 |
+
16512,
|
| 1133 |
+
16518,
|
| 1134 |
+
16630,
|
| 1135 |
+
16633,
|
| 1136 |
+
16640,
|
| 1137 |
+
16667,
|
| 1138 |
+
16707,
|
| 1139 |
+
16738,
|
| 1140 |
+
16747,
|
| 1141 |
+
16751,
|
| 1142 |
+
16760,
|
| 1143 |
+
16778,
|
| 1144 |
+
16813,
|
| 1145 |
+
16817,
|
| 1146 |
+
16825,
|
| 1147 |
+
16860,
|
| 1148 |
+
16863,
|
| 1149 |
+
16864,
|
| 1150 |
+
16885,
|
| 1151 |
+
16909,
|
| 1152 |
+
16913,
|
| 1153 |
+
16921,
|
| 1154 |
+
16930,
|
| 1155 |
+
16968,
|
| 1156 |
+
16975,
|
| 1157 |
+
16978,
|
| 1158 |
+
16980,
|
| 1159 |
+
17008,
|
| 1160 |
+
17016,
|
| 1161 |
+
17027,
|
| 1162 |
+
17036,
|
| 1163 |
+
17049,
|
| 1164 |
+
17055,
|
| 1165 |
+
17057,
|
| 1166 |
+
17084,
|
| 1167 |
+
17094,
|
| 1168 |
+
17096,
|
| 1169 |
+
17118,
|
| 1170 |
+
17135,
|
| 1171 |
+
17140,
|
| 1172 |
+
17156,
|
| 1173 |
+
17158,
|
| 1174 |
+
17185,
|
| 1175 |
+
17199,
|
| 1176 |
+
17223,
|
| 1177 |
+
17255,
|
| 1178 |
+
17260,
|
| 1179 |
+
17262,
|
| 1180 |
+
17277,
|
| 1181 |
+
17284,
|
| 1182 |
+
17351,
|
| 1183 |
+
17383,
|
| 1184 |
+
17400,
|
| 1185 |
+
17401,
|
| 1186 |
+
17409,
|
| 1187 |
+
17419,
|
| 1188 |
+
17429,
|
| 1189 |
+
17435,
|
| 1190 |
+
17462,
|
| 1191 |
+
17467,
|
| 1192 |
+
17476,
|
| 1193 |
+
17477,
|
| 1194 |
+
17483,
|
| 1195 |
+
17525,
|
| 1196 |
+
17550,
|
| 1197 |
+
17554,
|
| 1198 |
+
17560,
|
| 1199 |
+
17566,
|
| 1200 |
+
17587,
|
| 1201 |
+
17591,
|
| 1202 |
+
17607,
|
| 1203 |
+
17609,
|
| 1204 |
+
17621,
|
| 1205 |
+
17622,
|
| 1206 |
+
17634,
|
| 1207 |
+
17641,
|
| 1208 |
+
17642,
|
| 1209 |
+
17643,
|
| 1210 |
+
17671,
|
| 1211 |
+
17690,
|
| 1212 |
+
17701,
|
| 1213 |
+
17705,
|
| 1214 |
+
17706,
|
| 1215 |
+
17729,
|
| 1216 |
+
17730,
|
| 1217 |
+
17745,
|
| 1218 |
+
17767,
|
| 1219 |
+
17783,
|
| 1220 |
+
17794,
|
| 1221 |
+
17815,
|
| 1222 |
+
17825,
|
| 1223 |
+
17826,
|
| 1224 |
+
17830,
|
| 1225 |
+
17844,
|
| 1226 |
+
17848,
|
| 1227 |
+
17868,
|
| 1228 |
+
17894,
|
| 1229 |
+
17918,
|
| 1230 |
+
17928,
|
| 1231 |
+
17935,
|
| 1232 |
+
17973,
|
| 1233 |
+
17981,
|
| 1234 |
+
17989,
|
| 1235 |
+
18005,
|
| 1236 |
+
18059,
|
| 1237 |
+
18082,
|
| 1238 |
+
18113,
|
| 1239 |
+
18137,
|
| 1240 |
+
18140,
|
| 1241 |
+
18205,
|
| 1242 |
+
18208,
|
| 1243 |
+
18221,
|
| 1244 |
+
18236,
|
| 1245 |
+
18238,
|
| 1246 |
+
18259,
|
| 1247 |
+
18268,
|
| 1248 |
+
18285,
|
| 1249 |
+
18292,
|
| 1250 |
+
18334,
|
| 1251 |
+
18363,
|
| 1252 |
+
18364,
|
| 1253 |
+
18381,
|
| 1254 |
+
18390,
|
| 1255 |
+
18396,
|
| 1256 |
+
18421,
|
| 1257 |
+
18459,
|
| 1258 |
+
18505,
|
| 1259 |
+
18507,
|
| 1260 |
+
18535,
|
| 1261 |
+
18543,
|
| 1262 |
+
18544,
|
| 1263 |
+
18552,
|
| 1264 |
+
18556,
|
| 1265 |
+
18574,
|
| 1266 |
+
18584,
|
| 1267 |
+
18585,
|
| 1268 |
+
18591,
|
| 1269 |
+
18611,
|
| 1270 |
+
18639,
|
| 1271 |
+
18682,
|
| 1272 |
+
18722,
|
| 1273 |
+
18733,
|
| 1274 |
+
18742,
|
| 1275 |
+
18751,
|
| 1276 |
+
18754,
|
| 1277 |
+
18769,
|
| 1278 |
+
18772,
|
| 1279 |
+
18797,
|
| 1280 |
+
18811,
|
| 1281 |
+
18850,
|
| 1282 |
+
18893,
|
| 1283 |
+
18913,
|
| 1284 |
+
18914,
|
| 1285 |
+
18949,
|
| 1286 |
+
18959,
|
| 1287 |
+
18978,
|
| 1288 |
+
19011,
|
| 1289 |
+
19065,
|
| 1290 |
+
19066,
|
| 1291 |
+
19088,
|
| 1292 |
+
19107,
|
| 1293 |
+
19113,
|
| 1294 |
+
19123,
|
| 1295 |
+
19129,
|
| 1296 |
+
19134,
|
| 1297 |
+
19141,
|
| 1298 |
+
19144,
|
| 1299 |
+
19153,
|
| 1300 |
+
19184,
|
| 1301 |
+
19235,
|
| 1302 |
+
19238,
|
| 1303 |
+
19239,
|
| 1304 |
+
19245,
|
| 1305 |
+
19261,
|
| 1306 |
+
19306,
|
| 1307 |
+
19324,
|
| 1308 |
+
19328,
|
| 1309 |
+
19343,
|
| 1310 |
+
19347,
|
| 1311 |
+
19356,
|
| 1312 |
+
19376,
|
| 1313 |
+
19377,
|
| 1314 |
+
19385,
|
| 1315 |
+
19421,
|
| 1316 |
+
19457,
|
| 1317 |
+
19468,
|
| 1318 |
+
19475,
|
| 1319 |
+
19494,
|
| 1320 |
+
19506,
|
| 1321 |
+
19513,
|
| 1322 |
+
19514,
|
| 1323 |
+
19536,
|
| 1324 |
+
19546,
|
| 1325 |
+
19549,
|
| 1326 |
+
19564,
|
| 1327 |
+
19587,
|
| 1328 |
+
19595,
|
| 1329 |
+
19611,
|
| 1330 |
+
19630,
|
| 1331 |
+
19676,
|
| 1332 |
+
19687,
|
| 1333 |
+
19704,
|
| 1334 |
+
19707,
|
| 1335 |
+
19713,
|
| 1336 |
+
19738,
|
| 1337 |
+
19741,
|
| 1338 |
+
19778,
|
| 1339 |
+
19788,
|
| 1340 |
+
19799,
|
| 1341 |
+
19814,
|
| 1342 |
+
19821,
|
| 1343 |
+
19886,
|
| 1344 |
+
19896,
|
| 1345 |
+
19901,
|
| 1346 |
+
19916,
|
| 1347 |
+
19930,
|
| 1348 |
+
19946,
|
| 1349 |
+
19956,
|
| 1350 |
+
19973,
|
| 1351 |
+
19987,
|
| 1352 |
+
20024,
|
| 1353 |
+
20026,
|
| 1354 |
+
20047,
|
| 1355 |
+
20078,
|
| 1356 |
+
20098,
|
| 1357 |
+
20103,
|
| 1358 |
+
20136,
|
| 1359 |
+
20206,
|
| 1360 |
+
20225,
|
| 1361 |
+
20232,
|
| 1362 |
+
20235,
|
| 1363 |
+
20258,
|
| 1364 |
+
20267,
|
| 1365 |
+
20281,
|
| 1366 |
+
20289,
|
| 1367 |
+
20305,
|
| 1368 |
+
20307,
|
| 1369 |
+
20318,
|
| 1370 |
+
20320,
|
| 1371 |
+
20338,
|
| 1372 |
+
20354,
|
| 1373 |
+
20356,
|
| 1374 |
+
20375,
|
| 1375 |
+
20382,
|
| 1376 |
+
20386,
|
| 1377 |
+
20388,
|
| 1378 |
+
20390,
|
| 1379 |
+
20398,
|
| 1380 |
+
20418,
|
| 1381 |
+
20447,
|
| 1382 |
+
20472,
|
| 1383 |
+
20484,
|
| 1384 |
+
20571,
|
| 1385 |
+
20574,
|
| 1386 |
+
20582,
|
| 1387 |
+
20591,
|
| 1388 |
+
20625,
|
| 1389 |
+
20635,
|
| 1390 |
+
20698,
|
| 1391 |
+
20707,
|
| 1392 |
+
20709,
|
| 1393 |
+
20711,
|
| 1394 |
+
20741,
|
| 1395 |
+
20747,
|
| 1396 |
+
20749,
|
| 1397 |
+
20758,
|
| 1398 |
+
20770,
|
| 1399 |
+
20778,
|
| 1400 |
+
20779,
|
| 1401 |
+
20833,
|
| 1402 |
+
20862,
|
| 1403 |
+
20867,
|
| 1404 |
+
20879,
|
| 1405 |
+
20885,
|
| 1406 |
+
20912,
|
| 1407 |
+
20919,
|
| 1408 |
+
20941,
|
| 1409 |
+
20996,
|
| 1410 |
+
21005,
|
| 1411 |
+
21012,
|
| 1412 |
+
21035,
|
| 1413 |
+
21054,
|
| 1414 |
+
21082,
|
| 1415 |
+
21096,
|
| 1416 |
+
21103,
|
| 1417 |
+
21128,
|
| 1418 |
+
21135,
|
| 1419 |
+
21168,
|
| 1420 |
+
21174,
|
| 1421 |
+
21182,
|
| 1422 |
+
21200,
|
| 1423 |
+
21205,
|
| 1424 |
+
21227,
|
| 1425 |
+
21228,
|
| 1426 |
+
21230,
|
| 1427 |
+
21238,
|
| 1428 |
+
21246,
|
| 1429 |
+
21253,
|
| 1430 |
+
21280,
|
| 1431 |
+
21293,
|
| 1432 |
+
21298,
|
| 1433 |
+
21358,
|
| 1434 |
+
21370,
|
| 1435 |
+
21406,
|
| 1436 |
+
21421,
|
| 1437 |
+
21457,
|
| 1438 |
+
21518,
|
| 1439 |
+
21530,
|
| 1440 |
+
21549,
|
| 1441 |
+
21560,
|
| 1442 |
+
21562,
|
| 1443 |
+
21579,
|
| 1444 |
+
21613,
|
| 1445 |
+
21620,
|
| 1446 |
+
21636,
|
| 1447 |
+
21650,
|
| 1448 |
+
21654,
|
| 1449 |
+
21656,
|
| 1450 |
+
21668,
|
| 1451 |
+
21672,
|
| 1452 |
+
21675,
|
| 1453 |
+
21680,
|
| 1454 |
+
21686,
|
| 1455 |
+
21689,
|
| 1456 |
+
21696,
|
| 1457 |
+
21702,
|
| 1458 |
+
21704,
|
| 1459 |
+
21731,
|
| 1460 |
+
21783,
|
| 1461 |
+
21796,
|
| 1462 |
+
21798,
|
| 1463 |
+
21849,
|
| 1464 |
+
21865,
|
| 1465 |
+
21905,
|
| 1466 |
+
21906,
|
| 1467 |
+
21929,
|
| 1468 |
+
21949,
|
| 1469 |
+
21956,
|
| 1470 |
+
21972,
|
| 1471 |
+
21974,
|
| 1472 |
+
21987,
|
| 1473 |
+
22009,
|
| 1474 |
+
22022,
|
| 1475 |
+
22025,
|
| 1476 |
+
22042,
|
| 1477 |
+
22050,
|
| 1478 |
+
22071,
|
| 1479 |
+
22074,
|
| 1480 |
+
22078,
|
| 1481 |
+
22084,
|
| 1482 |
+
22085,
|
| 1483 |
+
22116,
|
| 1484 |
+
22129,
|
| 1485 |
+
22158,
|
| 1486 |
+
22165,
|
| 1487 |
+
22224,
|
| 1488 |
+
22225,
|
| 1489 |
+
22247,
|
| 1490 |
+
22297,
|
| 1491 |
+
22312,
|
| 1492 |
+
22322,
|
| 1493 |
+
22336,
|
| 1494 |
+
22337,
|
| 1495 |
+
22343,
|
| 1496 |
+
22345,
|
| 1497 |
+
22367,
|
| 1498 |
+
22370,
|
| 1499 |
+
22428,
|
| 1500 |
+
22438,
|
| 1501 |
+
22460,
|
| 1502 |
+
22498,
|
| 1503 |
+
22525,
|
| 1504 |
+
22558,
|
| 1505 |
+
22580,
|
| 1506 |
+
22597,
|
| 1507 |
+
22607,
|
| 1508 |
+
22612,
|
| 1509 |
+
22614,
|
| 1510 |
+
22649,
|
| 1511 |
+
22663,
|
| 1512 |
+
22677,
|
| 1513 |
+
22689,
|
| 1514 |
+
22701,
|
| 1515 |
+
22712,
|
| 1516 |
+
22726,
|
| 1517 |
+
22746,
|
| 1518 |
+
22754,
|
| 1519 |
+
22762,
|
| 1520 |
+
22768,
|
| 1521 |
+
22788,
|
| 1522 |
+
22796,
|
| 1523 |
+
22842,
|
| 1524 |
+
22857,
|
| 1525 |
+
22859,
|
| 1526 |
+
22861,
|
| 1527 |
+
22886,
|
| 1528 |
+
22895,
|
| 1529 |
+
22940,
|
| 1530 |
+
22956,
|
| 1531 |
+
22983,
|
| 1532 |
+
22987,
|
| 1533 |
+
22988,
|
| 1534 |
+
22991,
|
| 1535 |
+
23014,
|
| 1536 |
+
23032,
|
| 1537 |
+
23052,
|
| 1538 |
+
23053,
|
| 1539 |
+
23083,
|
| 1540 |
+
23093,
|
| 1541 |
+
23135,
|
| 1542 |
+
23147,
|
| 1543 |
+
23158,
|
| 1544 |
+
23174,
|
| 1545 |
+
23231,
|
| 1546 |
+
23254,
|
| 1547 |
+
23272,
|
| 1548 |
+
23315,
|
| 1549 |
+
23341,
|
| 1550 |
+
23351,
|
| 1551 |
+
23359,
|
| 1552 |
+
23369,
|
| 1553 |
+
23373,
|
| 1554 |
+
23398,
|
| 1555 |
+
23421,
|
| 1556 |
+
23426,
|
| 1557 |
+
23431,
|
| 1558 |
+
23433,
|
| 1559 |
+
23439,
|
| 1560 |
+
23443,
|
| 1561 |
+
23444,
|
| 1562 |
+
23459,
|
| 1563 |
+
23474,
|
| 1564 |
+
23478,
|
| 1565 |
+
23479,
|
| 1566 |
+
23482,
|
| 1567 |
+
23509,
|
| 1568 |
+
23515,
|
| 1569 |
+
23530,
|
| 1570 |
+
23547,
|
| 1571 |
+
23569,
|
| 1572 |
+
23571,
|
| 1573 |
+
23585,
|
| 1574 |
+
23599,
|
| 1575 |
+
23600,
|
| 1576 |
+
23625,
|
| 1577 |
+
23637,
|
| 1578 |
+
23669,
|
| 1579 |
+
23687,
|
| 1580 |
+
23754,
|
| 1581 |
+
23758,
|
| 1582 |
+
23781,
|
| 1583 |
+
23794,
|
| 1584 |
+
23866,
|
| 1585 |
+
23872,
|
| 1586 |
+
23884,
|
| 1587 |
+
23891,
|
| 1588 |
+
23894,
|
| 1589 |
+
23912,
|
| 1590 |
+
23934,
|
| 1591 |
+
24008,
|
| 1592 |
+
24011,
|
| 1593 |
+
24021,
|
| 1594 |
+
24023,
|
| 1595 |
+
24032,
|
| 1596 |
+
24041,
|
| 1597 |
+
24045,
|
| 1598 |
+
24071,
|
| 1599 |
+
24076,
|
| 1600 |
+
24077,
|
| 1601 |
+
24097,
|
| 1602 |
+
24123,
|
| 1603 |
+
24135,
|
| 1604 |
+
24144,
|
| 1605 |
+
24147,
|
| 1606 |
+
24148,
|
| 1607 |
+
24159,
|
| 1608 |
+
24183,
|
| 1609 |
+
24197,
|
| 1610 |
+
24212,
|
| 1611 |
+
24216,
|
| 1612 |
+
24226,
|
| 1613 |
+
24254,
|
| 1614 |
+
24265,
|
| 1615 |
+
24305,
|
| 1616 |
+
24312,
|
| 1617 |
+
24316,
|
| 1618 |
+
24320,
|
| 1619 |
+
24333,
|
| 1620 |
+
24337,
|
| 1621 |
+
24338,
|
| 1622 |
+
24345,
|
| 1623 |
+
24352,
|
| 1624 |
+
24365,
|
| 1625 |
+
24375,
|
| 1626 |
+
24377,
|
| 1627 |
+
24389,
|
| 1628 |
+
24391,
|
| 1629 |
+
24429,
|
| 1630 |
+
24437,
|
| 1631 |
+
24447,
|
| 1632 |
+
24460,
|
| 1633 |
+
24476,
|
| 1634 |
+
24485,
|
| 1635 |
+
24497,
|
| 1636 |
+
24520,
|
| 1637 |
+
24539,
|
| 1638 |
+
24616,
|
| 1639 |
+
24697,
|
| 1640 |
+
24727,
|
| 1641 |
+
24734,
|
| 1642 |
+
24735,
|
| 1643 |
+
24749,
|
| 1644 |
+
24750,
|
| 1645 |
+
24772,
|
| 1646 |
+
24796,
|
| 1647 |
+
24816,
|
| 1648 |
+
24817,
|
| 1649 |
+
24825,
|
| 1650 |
+
24827,
|
| 1651 |
+
24831,
|
| 1652 |
+
24840,
|
| 1653 |
+
24850,
|
| 1654 |
+
24853,
|
| 1655 |
+
24864,
|
| 1656 |
+
24881,
|
| 1657 |
+
24948,
|
| 1658 |
+
24974,
|
| 1659 |
+
24978,
|
| 1660 |
+
24985,
|
| 1661 |
+
25010,
|
| 1662 |
+
25011,
|
| 1663 |
+
25035,
|
| 1664 |
+
25046,
|
| 1665 |
+
25049,
|
| 1666 |
+
25089,
|
| 1667 |
+
25107,
|
| 1668 |
+
25110,
|
| 1669 |
+
25125,
|
| 1670 |
+
25138,
|
| 1671 |
+
25145,
|
| 1672 |
+
25162,
|
| 1673 |
+
25190,
|
| 1674 |
+
25209,
|
| 1675 |
+
25249,
|
| 1676 |
+
25289,
|
| 1677 |
+
25315,
|
| 1678 |
+
25319,
|
| 1679 |
+
25321,
|
| 1680 |
+
25340,
|
| 1681 |
+
25346,
|
| 1682 |
+
25389,
|
| 1683 |
+
25401,
|
| 1684 |
+
25409,
|
| 1685 |
+
25435,
|
| 1686 |
+
25447,
|
| 1687 |
+
25452,
|
| 1688 |
+
25464,
|
| 1689 |
+
25467,
|
| 1690 |
+
25468,
|
| 1691 |
+
25490,
|
| 1692 |
+
25495,
|
| 1693 |
+
25501,
|
| 1694 |
+
25521,
|
| 1695 |
+
25526,
|
| 1696 |
+
25534,
|
| 1697 |
+
25547,
|
| 1698 |
+
25556,
|
| 1699 |
+
25571,
|
| 1700 |
+
25589,
|
| 1701 |
+
25592,
|
| 1702 |
+
25624,
|
| 1703 |
+
25639,
|
| 1704 |
+
25644,
|
| 1705 |
+
25703,
|
| 1706 |
+
25731,
|
| 1707 |
+
25733,
|
| 1708 |
+
25746,
|
| 1709 |
+
25759,
|
| 1710 |
+
25772,
|
| 1711 |
+
25781,
|
| 1712 |
+
25786,
|
| 1713 |
+
25797,
|
| 1714 |
+
25805,
|
| 1715 |
+
25821,
|
| 1716 |
+
25829,
|
| 1717 |
+
25865,
|
| 1718 |
+
25870,
|
| 1719 |
+
25885,
|
| 1720 |
+
25890,
|
| 1721 |
+
25897,
|
| 1722 |
+
25906,
|
| 1723 |
+
25910,
|
| 1724 |
+
25912,
|
| 1725 |
+
25917,
|
| 1726 |
+
25923,
|
| 1727 |
+
25928,
|
| 1728 |
+
25931,
|
| 1729 |
+
25933,
|
| 1730 |
+
25956,
|
| 1731 |
+
25974,
|
| 1732 |
+
26027,
|
| 1733 |
+
26043,
|
| 1734 |
+
26072,
|
| 1735 |
+
26074,
|
| 1736 |
+
26082,
|
| 1737 |
+
26087,
|
| 1738 |
+
26097,
|
| 1739 |
+
26126,
|
| 1740 |
+
26169,
|
| 1741 |
+
26188,
|
| 1742 |
+
26230,
|
| 1743 |
+
26238,
|
| 1744 |
+
26245,
|
| 1745 |
+
26254,
|
| 1746 |
+
26259,
|
| 1747 |
+
26280,
|
| 1748 |
+
26285,
|
| 1749 |
+
26311,
|
| 1750 |
+
26336,
|
| 1751 |
+
26384,
|
| 1752 |
+
26405,
|
| 1753 |
+
26409,
|
| 1754 |
+
26432,
|
| 1755 |
+
26442,
|
| 1756 |
+
26454,
|
| 1757 |
+
26469,
|
| 1758 |
+
26487,
|
| 1759 |
+
26496,
|
| 1760 |
+
26506,
|
| 1761 |
+
26525,
|
| 1762 |
+
26546,
|
| 1763 |
+
26556,
|
| 1764 |
+
26566,
|
| 1765 |
+
26578,
|
| 1766 |
+
26579,
|
| 1767 |
+
26601,
|
| 1768 |
+
26609,
|
| 1769 |
+
26637,
|
| 1770 |
+
26690,
|
| 1771 |
+
26717,
|
| 1772 |
+
26731,
|
| 1773 |
+
26771,
|
| 1774 |
+
26772,
|
| 1775 |
+
26782,
|
| 1776 |
+
26794,
|
| 1777 |
+
26809,
|
| 1778 |
+
26828,
|
| 1779 |
+
26840,
|
| 1780 |
+
26850,
|
| 1781 |
+
26853,
|
| 1782 |
+
26856,
|
| 1783 |
+
26861,
|
| 1784 |
+
26903,
|
| 1785 |
+
26919,
|
| 1786 |
+
26927,
|
| 1787 |
+
26974,
|
| 1788 |
+
26999,
|
| 1789 |
+
27007,
|
| 1790 |
+
27010,
|
| 1791 |
+
27027,
|
| 1792 |
+
27042,
|
| 1793 |
+
27050,
|
| 1794 |
+
27062,
|
| 1795 |
+
27070,
|
| 1796 |
+
27085,
|
| 1797 |
+
27095,
|
| 1798 |
+
27113,
|
| 1799 |
+
27119,
|
| 1800 |
+
27126,
|
| 1801 |
+
27144,
|
| 1802 |
+
27151,
|
| 1803 |
+
27166,
|
| 1804 |
+
27184,
|
| 1805 |
+
27189,
|
| 1806 |
+
27191,
|
| 1807 |
+
27209,
|
| 1808 |
+
27214,
|
| 1809 |
+
27220,
|
| 1810 |
+
27249,
|
| 1811 |
+
27260,
|
| 1812 |
+
27271,
|
| 1813 |
+
27275,
|
| 1814 |
+
27301,
|
| 1815 |
+
27311,
|
| 1816 |
+
27316,
|
| 1817 |
+
27325,
|
| 1818 |
+
27352,
|
| 1819 |
+
27365,
|
| 1820 |
+
27398,
|
| 1821 |
+
27424,
|
| 1822 |
+
27427,
|
| 1823 |
+
27435,
|
| 1824 |
+
27438,
|
| 1825 |
+
27439,
|
| 1826 |
+
27443,
|
| 1827 |
+
27486,
|
| 1828 |
+
27487,
|
| 1829 |
+
27506,
|
| 1830 |
+
27510,
|
| 1831 |
+
27517,
|
| 1832 |
+
27538,
|
| 1833 |
+
27568,
|
| 1834 |
+
27580,
|
| 1835 |
+
27584,
|
| 1836 |
+
27610,
|
| 1837 |
+
27614,
|
| 1838 |
+
27631,
|
| 1839 |
+
27640,
|
| 1840 |
+
27654,
|
| 1841 |
+
27659,
|
| 1842 |
+
27668,
|
| 1843 |
+
27676,
|
| 1844 |
+
27701,
|
| 1845 |
+
27704,
|
| 1846 |
+
27757,
|
| 1847 |
+
27762,
|
| 1848 |
+
27766,
|
| 1849 |
+
27767,
|
| 1850 |
+
27771,
|
| 1851 |
+
27772,
|
| 1852 |
+
27818,
|
| 1853 |
+
27845,
|
| 1854 |
+
27855,
|
| 1855 |
+
27866,
|
| 1856 |
+
27876,
|
| 1857 |
+
27884,
|
| 1858 |
+
27901,
|
| 1859 |
+
27907,
|
| 1860 |
+
27978,
|
| 1861 |
+
27982,
|
| 1862 |
+
27999,
|
| 1863 |
+
28019,
|
| 1864 |
+
28038,
|
| 1865 |
+
28075,
|
| 1866 |
+
28094,
|
| 1867 |
+
28107,
|
| 1868 |
+
28114,
|
| 1869 |
+
28116,
|
| 1870 |
+
28127,
|
| 1871 |
+
28145,
|
| 1872 |
+
28154,
|
| 1873 |
+
28168,
|
| 1874 |
+
28175,
|
| 1875 |
+
28197,
|
| 1876 |
+
28207,
|
| 1877 |
+
28247,
|
| 1878 |
+
28261,
|
| 1879 |
+
28266,
|
| 1880 |
+
28272,
|
| 1881 |
+
28281,
|
| 1882 |
+
28311,
|
| 1883 |
+
28325,
|
| 1884 |
+
28329,
|
| 1885 |
+
28336,
|
| 1886 |
+
28348,
|
| 1887 |
+
28372,
|
| 1888 |
+
28375,
|
| 1889 |
+
28382,
|
| 1890 |
+
28389,
|
| 1891 |
+
28394,
|
| 1892 |
+
28406,
|
| 1893 |
+
28429,
|
| 1894 |
+
28447,
|
| 1895 |
+
28489,
|
| 1896 |
+
28520,
|
| 1897 |
+
28565,
|
| 1898 |
+
28570,
|
| 1899 |
+
28581,
|
| 1900 |
+
28653,
|
| 1901 |
+
28654,
|
| 1902 |
+
28665,
|
| 1903 |
+
28669,
|
| 1904 |
+
28671,
|
| 1905 |
+
28673,
|
| 1906 |
+
28680,
|
| 1907 |
+
28706,
|
| 1908 |
+
28712,
|
| 1909 |
+
28743,
|
| 1910 |
+
28757,
|
| 1911 |
+
28864,
|
| 1912 |
+
28875,
|
| 1913 |
+
28880,
|
| 1914 |
+
28907,
|
| 1915 |
+
28918,
|
| 1916 |
+
28927,
|
| 1917 |
+
28958,
|
| 1918 |
+
28974,
|
| 1919 |
+
28978,
|
| 1920 |
+
28987,
|
| 1921 |
+
29043,
|
| 1922 |
+
29076,
|
| 1923 |
+
29083,
|
| 1924 |
+
29084,
|
| 1925 |
+
29089,
|
| 1926 |
+
29110,
|
| 1927 |
+
29113,
|
| 1928 |
+
29122,
|
| 1929 |
+
29128,
|
| 1930 |
+
29150,
|
| 1931 |
+
29184,
|
| 1932 |
+
29191,
|
| 1933 |
+
29209,
|
| 1934 |
+
29220,
|
| 1935 |
+
29237,
|
| 1936 |
+
29240,
|
| 1937 |
+
29254,
|
| 1938 |
+
29324,
|
| 1939 |
+
29333,
|
| 1940 |
+
29345,
|
| 1941 |
+
29355,
|
| 1942 |
+
29359,
|
| 1943 |
+
29376,
|
| 1944 |
+
29389,
|
| 1945 |
+
29465,
|
| 1946 |
+
29487,
|
| 1947 |
+
29529,
|
| 1948 |
+
29555,
|
| 1949 |
+
29562,
|
| 1950 |
+
29592,
|
| 1951 |
+
29605,
|
| 1952 |
+
29616,
|
| 1953 |
+
29621,
|
| 1954 |
+
29633,
|
| 1955 |
+
29636,
|
| 1956 |
+
29675,
|
| 1957 |
+
29710,
|
| 1958 |
+
29721,
|
| 1959 |
+
29766,
|
| 1960 |
+
29768,
|
| 1961 |
+
29771,
|
| 1962 |
+
29773,
|
| 1963 |
+
29776,
|
| 1964 |
+
29811,
|
| 1965 |
+
29816,
|
| 1966 |
+
29833,
|
| 1967 |
+
29836,
|
| 1968 |
+
29879,
|
| 1969 |
+
29893,
|
| 1970 |
+
29932,
|
| 1971 |
+
29941,
|
| 1972 |
+
29955,
|
| 1973 |
+
29963,
|
| 1974 |
+
29975,
|
| 1975 |
+
29976,
|
| 1976 |
+
30006,
|
| 1977 |
+
30008,
|
| 1978 |
+
30018,
|
| 1979 |
+
30034,
|
| 1980 |
+
30085,
|
| 1981 |
+
30122,
|
| 1982 |
+
30139,
|
| 1983 |
+
30154,
|
| 1984 |
+
30212,
|
| 1985 |
+
30218,
|
| 1986 |
+
30247,
|
| 1987 |
+
30260,
|
| 1988 |
+
30263,
|
| 1989 |
+
30274,
|
| 1990 |
+
30323,
|
| 1991 |
+
30325,
|
| 1992 |
+
30354,
|
| 1993 |
+
30375,
|
| 1994 |
+
30376,
|
| 1995 |
+
30389,
|
| 1996 |
+
30390,
|
| 1997 |
+
30395,
|
| 1998 |
+
30407,
|
| 1999 |
+
30409,
|
| 2000 |
+
30424,
|
| 2001 |
+
30438,
|
| 2002 |
+
30458,
|
| 2003 |
+
30463,
|
| 2004 |
+
30467,
|
| 2005 |
+
30469,
|
| 2006 |
+
30475,
|
| 2007 |
+
30484,
|
| 2008 |
+
30493,
|
| 2009 |
+
30520,
|
| 2010 |
+
30523,
|
| 2011 |
+
30535,
|
| 2012 |
+
30558,
|
| 2013 |
+
30584,
|
| 2014 |
+
30625,
|
| 2015 |
+
30631,
|
| 2016 |
+
30634,
|
| 2017 |
+
30638,
|
| 2018 |
+
30645,
|
| 2019 |
+
30678,
|
| 2020 |
+
30695,
|
| 2021 |
+
30723,
|
| 2022 |
+
30734,
|
| 2023 |
+
30736,
|
| 2024 |
+
30749,
|
| 2025 |
+
30750,
|
| 2026 |
+
30757,
|
| 2027 |
+
30779,
|
| 2028 |
+
30793,
|
| 2029 |
+
30828,
|
| 2030 |
+
30831,
|
| 2031 |
+
30838,
|
| 2032 |
+
30850,
|
| 2033 |
+
30873,
|
| 2034 |
+
30885,
|
| 2035 |
+
30916,
|
| 2036 |
+
30917,
|
| 2037 |
+
30948,
|
| 2038 |
+
30949,
|
| 2039 |
+
30958,
|
| 2040 |
+
30981,
|
| 2041 |
+
30991,
|
| 2042 |
+
31159,
|
| 2043 |
+
31200,
|
| 2044 |
+
31218,
|
| 2045 |
+
31225,
|
| 2046 |
+
31239,
|
| 2047 |
+
31257,
|
| 2048 |
+
31278,
|
| 2049 |
+
31286,
|
| 2050 |
+
31295,
|
| 2051 |
+
31296,
|
| 2052 |
+
31305,
|
| 2053 |
+
31307,
|
| 2054 |
+
31338,
|
| 2055 |
+
31356,
|
| 2056 |
+
31368,
|
| 2057 |
+
31411,
|
| 2058 |
+
31418,
|
| 2059 |
+
31424,
|
| 2060 |
+
31436,
|
| 2061 |
+
31470,
|
| 2062 |
+
31482,
|
| 2063 |
+
31483,
|
| 2064 |
+
31487,
|
| 2065 |
+
31501,
|
| 2066 |
+
31540,
|
| 2067 |
+
31567,
|
| 2068 |
+
31587,
|
| 2069 |
+
31601,
|
| 2070 |
+
31673,
|
| 2071 |
+
31688,
|
| 2072 |
+
31706,
|
| 2073 |
+
31707,
|
| 2074 |
+
31715,
|
| 2075 |
+
31723,
|
| 2076 |
+
31729,
|
| 2077 |
+
31732,
|
| 2078 |
+
31740,
|
| 2079 |
+
31764,
|
| 2080 |
+
31781,
|
| 2081 |
+
31797,
|
| 2082 |
+
31813,
|
| 2083 |
+
31816,
|
| 2084 |
+
31856,
|
| 2085 |
+
31870,
|
| 2086 |
+
31884,
|
| 2087 |
+
31888,
|
| 2088 |
+
31906,
|
| 2089 |
+
31911,
|
| 2090 |
+
31931,
|
| 2091 |
+
31933,
|
| 2092 |
+
31951,
|
| 2093 |
+
31975,
|
| 2094 |
+
31980,
|
| 2095 |
+
31982,
|
| 2096 |
+
32013,
|
| 2097 |
+
32014,
|
| 2098 |
+
32028,
|
| 2099 |
+
32057,
|
| 2100 |
+
32068,
|
| 2101 |
+
32083,
|
| 2102 |
+
32087,
|
| 2103 |
+
32090,
|
| 2104 |
+
32148,
|
| 2105 |
+
32162,
|
| 2106 |
+
32181,
|
| 2107 |
+
32184,
|
| 2108 |
+
32203,
|
| 2109 |
+
32208,
|
| 2110 |
+
32224,
|
| 2111 |
+
32254,
|
| 2112 |
+
32263,
|
| 2113 |
+
32268,
|
| 2114 |
+
32279,
|
| 2115 |
+
32295,
|
| 2116 |
+
32314,
|
| 2117 |
+
32326,
|
| 2118 |
+
32343,
|
| 2119 |
+
32356,
|
| 2120 |
+
32373,
|
| 2121 |
+
32386,
|
| 2122 |
+
32423,
|
| 2123 |
+
32431,
|
| 2124 |
+
32450,
|
| 2125 |
+
32465,
|
| 2126 |
+
32484,
|
| 2127 |
+
32495,
|
| 2128 |
+
32511,
|
| 2129 |
+
32544,
|
| 2130 |
+
32545,
|
| 2131 |
+
32548,
|
| 2132 |
+
32574,
|
| 2133 |
+
32585,
|
| 2134 |
+
32596,
|
| 2135 |
+
32598,
|
| 2136 |
+
32602,
|
| 2137 |
+
32609,
|
| 2138 |
+
32616,
|
| 2139 |
+
32623,
|
| 2140 |
+
32624,
|
| 2141 |
+
32636,
|
| 2142 |
+
32647,
|
| 2143 |
+
32691,
|
| 2144 |
+
32735,
|
| 2145 |
+
32737,
|
| 2146 |
+
32756,
|
| 2147 |
+
32798,
|
| 2148 |
+
32805,
|
| 2149 |
+
32843,
|
| 2150 |
+
32868,
|
| 2151 |
+
32872,
|
| 2152 |
+
32881,
|
| 2153 |
+
32926,
|
| 2154 |
+
32968,
|
| 2155 |
+
32985,
|
| 2156 |
+
32989,
|
| 2157 |
+
32991,
|
| 2158 |
+
32996,
|
| 2159 |
+
33010,
|
| 2160 |
+
33013,
|
| 2161 |
+
33016,
|
| 2162 |
+
33021,
|
| 2163 |
+
33028,
|
| 2164 |
+
33030,
|
| 2165 |
+
33077,
|
| 2166 |
+
33084,
|
| 2167 |
+
33089,
|
| 2168 |
+
33093,
|
| 2169 |
+
33104,
|
| 2170 |
+
33130,
|
| 2171 |
+
33152,
|
| 2172 |
+
33157,
|
| 2173 |
+
33173,
|
| 2174 |
+
33179,
|
| 2175 |
+
33199,
|
| 2176 |
+
33293,
|
| 2177 |
+
33294,
|
| 2178 |
+
33333,
|
| 2179 |
+
33351,
|
| 2180 |
+
33352,
|
| 2181 |
+
33397,
|
| 2182 |
+
33413,
|
| 2183 |
+
33418,
|
| 2184 |
+
33419,
|
| 2185 |
+
33424,
|
| 2186 |
+
33436,
|
| 2187 |
+
33440,
|
| 2188 |
+
33442,
|
| 2189 |
+
33478,
|
| 2190 |
+
33484,
|
| 2191 |
+
33498,
|
| 2192 |
+
33543,
|
| 2193 |
+
33546,
|
| 2194 |
+
33552,
|
| 2195 |
+
33556,
|
| 2196 |
+
33579,
|
| 2197 |
+
33593,
|
| 2198 |
+
33621,
|
| 2199 |
+
33626,
|
| 2200 |
+
33641,
|
| 2201 |
+
33645,
|
| 2202 |
+
33660,
|
| 2203 |
+
33666,
|
| 2204 |
+
33673,
|
| 2205 |
+
33687,
|
| 2206 |
+
33694,
|
| 2207 |
+
33711,
|
| 2208 |
+
33734,
|
| 2209 |
+
33739,
|
| 2210 |
+
33761,
|
| 2211 |
+
33766,
|
| 2212 |
+
33783,
|
| 2213 |
+
33794,
|
| 2214 |
+
33800,
|
| 2215 |
+
33804,
|
| 2216 |
+
33810,
|
| 2217 |
+
33826,
|
| 2218 |
+
33862,
|
| 2219 |
+
33871,
|
| 2220 |
+
33916,
|
| 2221 |
+
33928,
|
| 2222 |
+
33929,
|
| 2223 |
+
33933,
|
| 2224 |
+
33943,
|
| 2225 |
+
33947,
|
| 2226 |
+
33949,
|
| 2227 |
+
33955,
|
| 2228 |
+
33959,
|
| 2229 |
+
33986,
|
| 2230 |
+
33987,
|
| 2231 |
+
33989,
|
| 2232 |
+
33999,
|
| 2233 |
+
34007,
|
| 2234 |
+
34010,
|
| 2235 |
+
34026,
|
| 2236 |
+
34052,
|
| 2237 |
+
34081,
|
| 2238 |
+
34082,
|
| 2239 |
+
34083,
|
| 2240 |
+
34135,
|
| 2241 |
+
34141,
|
| 2242 |
+
34143,
|
| 2243 |
+
34149,
|
| 2244 |
+
34184,
|
| 2245 |
+
34203,
|
| 2246 |
+
34232,
|
| 2247 |
+
34297,
|
| 2248 |
+
34299,
|
| 2249 |
+
34300,
|
| 2250 |
+
34321,
|
| 2251 |
+
34322,
|
| 2252 |
+
34327,
|
| 2253 |
+
34331,
|
| 2254 |
+
34332,
|
| 2255 |
+
34341,
|
| 2256 |
+
34369,
|
| 2257 |
+
34403,
|
| 2258 |
+
34410,
|
| 2259 |
+
34420,
|
| 2260 |
+
34425,
|
| 2261 |
+
34429,
|
| 2262 |
+
34480,
|
| 2263 |
+
34483,
|
| 2264 |
+
34499,
|
| 2265 |
+
34546,
|
| 2266 |
+
34577,
|
| 2267 |
+
34583,
|
| 2268 |
+
34590,
|
| 2269 |
+
34600,
|
| 2270 |
+
34622,
|
| 2271 |
+
34629,
|
| 2272 |
+
34642,
|
| 2273 |
+
34649,
|
| 2274 |
+
34670,
|
| 2275 |
+
34690,
|
| 2276 |
+
34759,
|
| 2277 |
+
34764,
|
| 2278 |
+
34773,
|
| 2279 |
+
34793,
|
| 2280 |
+
34799,
|
| 2281 |
+
34811,
|
| 2282 |
+
34812,
|
| 2283 |
+
34820,
|
| 2284 |
+
34821,
|
| 2285 |
+
34829,
|
| 2286 |
+
34864,
|
| 2287 |
+
34866,
|
| 2288 |
+
34885,
|
| 2289 |
+
34895,
|
| 2290 |
+
34923,
|
| 2291 |
+
34939,
|
| 2292 |
+
34944,
|
| 2293 |
+
34973,
|
| 2294 |
+
34985,
|
| 2295 |
+
34992,
|
| 2296 |
+
35017,
|
| 2297 |
+
35049,
|
| 2298 |
+
35055,
|
| 2299 |
+
35063,
|
| 2300 |
+
35065,
|
| 2301 |
+
35066,
|
| 2302 |
+
35075,
|
| 2303 |
+
35099,
|
| 2304 |
+
35106,
|
| 2305 |
+
35115,
|
| 2306 |
+
35117,
|
| 2307 |
+
35125,
|
| 2308 |
+
35146,
|
| 2309 |
+
35173,
|
| 2310 |
+
35178,
|
| 2311 |
+
35184,
|
| 2312 |
+
35190,
|
| 2313 |
+
35199,
|
| 2314 |
+
35200,
|
| 2315 |
+
35208,
|
| 2316 |
+
35219,
|
| 2317 |
+
35229,
|
| 2318 |
+
35248,
|
| 2319 |
+
35274,
|
| 2320 |
+
35289,
|
| 2321 |
+
35293,
|
| 2322 |
+
35297,
|
| 2323 |
+
35306,
|
| 2324 |
+
35311,
|
| 2325 |
+
35330,
|
| 2326 |
+
35334,
|
| 2327 |
+
35335,
|
| 2328 |
+
35358,
|
| 2329 |
+
35392,
|
| 2330 |
+
35393,
|
| 2331 |
+
35394,
|
| 2332 |
+
35410,
|
| 2333 |
+
35419,
|
| 2334 |
+
35420,
|
| 2335 |
+
35429,
|
| 2336 |
+
35438,
|
| 2337 |
+
35452,
|
| 2338 |
+
35460,
|
| 2339 |
+
35496,
|
| 2340 |
+
35521,
|
| 2341 |
+
35528,
|
| 2342 |
+
35537,
|
| 2343 |
+
35538,
|
| 2344 |
+
35553,
|
| 2345 |
+
35582,
|
| 2346 |
+
35635,
|
| 2347 |
+
35636,
|
| 2348 |
+
35653,
|
| 2349 |
+
35674,
|
| 2350 |
+
35676,
|
| 2351 |
+
35677,
|
| 2352 |
+
35680,
|
| 2353 |
+
35687,
|
| 2354 |
+
35696,
|
| 2355 |
+
35712,
|
| 2356 |
+
35718,
|
| 2357 |
+
35720,
|
| 2358 |
+
35721,
|
| 2359 |
+
35755,
|
| 2360 |
+
35786,
|
| 2361 |
+
35811,
|
| 2362 |
+
35829,
|
| 2363 |
+
35833,
|
| 2364 |
+
35850,
|
| 2365 |
+
35855,
|
| 2366 |
+
35864,
|
| 2367 |
+
35866,
|
| 2368 |
+
35888,
|
| 2369 |
+
35898,
|
| 2370 |
+
35963,
|
| 2371 |
+
36001,
|
| 2372 |
+
36014,
|
| 2373 |
+
36046,
|
| 2374 |
+
36073,
|
| 2375 |
+
36087,
|
| 2376 |
+
36088,
|
| 2377 |
+
36097,
|
| 2378 |
+
36109,
|
| 2379 |
+
36131,
|
| 2380 |
+
36168,
|
| 2381 |
+
36170,
|
| 2382 |
+
36174,
|
| 2383 |
+
36180,
|
| 2384 |
+
36197,
|
| 2385 |
+
36206,
|
| 2386 |
+
36207,
|
| 2387 |
+
36246,
|
| 2388 |
+
36260,
|
| 2389 |
+
36288,
|
| 2390 |
+
36289,
|
| 2391 |
+
36308,
|
| 2392 |
+
36323,
|
| 2393 |
+
36330,
|
| 2394 |
+
36334,
|
| 2395 |
+
36360,
|
| 2396 |
+
36363,
|
| 2397 |
+
36368,
|
| 2398 |
+
36384,
|
| 2399 |
+
36456,
|
| 2400 |
+
36474,
|
| 2401 |
+
36484,
|
| 2402 |
+
36502,
|
| 2403 |
+
36514,
|
| 2404 |
+
36548,
|
| 2405 |
+
36577,
|
| 2406 |
+
36606,
|
| 2407 |
+
36609,
|
| 2408 |
+
36610,
|
| 2409 |
+
36618,
|
| 2410 |
+
36622,
|
| 2411 |
+
36624,
|
| 2412 |
+
36652,
|
| 2413 |
+
36669,
|
| 2414 |
+
36677,
|
| 2415 |
+
36695,
|
| 2416 |
+
36713,
|
| 2417 |
+
36715,
|
| 2418 |
+
36720,
|
| 2419 |
+
36778,
|
| 2420 |
+
36781,
|
| 2421 |
+
36800,
|
| 2422 |
+
36818,
|
| 2423 |
+
36825,
|
| 2424 |
+
36827,
|
| 2425 |
+
36845,
|
| 2426 |
+
36876,
|
| 2427 |
+
36882,
|
| 2428 |
+
36884,
|
| 2429 |
+
36902,
|
| 2430 |
+
36914,
|
| 2431 |
+
36915,
|
| 2432 |
+
36928,
|
| 2433 |
+
36944,
|
| 2434 |
+
36951,
|
| 2435 |
+
36968,
|
| 2436 |
+
36978,
|
| 2437 |
+
36979,
|
| 2438 |
+
36984,
|
| 2439 |
+
37023,
|
| 2440 |
+
37038,
|
| 2441 |
+
37048,
|
| 2442 |
+
37051,
|
| 2443 |
+
37064,
|
| 2444 |
+
37076,
|
| 2445 |
+
37084,
|
| 2446 |
+
37096,
|
| 2447 |
+
37124,
|
| 2448 |
+
37148,
|
| 2449 |
+
37157,
|
| 2450 |
+
37178,
|
| 2451 |
+
37195,
|
| 2452 |
+
37204,
|
| 2453 |
+
37235,
|
| 2454 |
+
37254,
|
| 2455 |
+
37258,
|
| 2456 |
+
37265,
|
| 2457 |
+
37270,
|
| 2458 |
+
37275,
|
| 2459 |
+
37283,
|
| 2460 |
+
37289,
|
| 2461 |
+
37334,
|
| 2462 |
+
37336,
|
| 2463 |
+
37341,
|
| 2464 |
+
37365,
|
| 2465 |
+
37389,
|
| 2466 |
+
37396,
|
| 2467 |
+
37403,
|
| 2468 |
+
37440,
|
| 2469 |
+
37441,
|
| 2470 |
+
37445,
|
| 2471 |
+
37472,
|
| 2472 |
+
37485,
|
| 2473 |
+
37490,
|
| 2474 |
+
37509,
|
| 2475 |
+
37544,
|
| 2476 |
+
37595,
|
| 2477 |
+
37621,
|
| 2478 |
+
37640,
|
| 2479 |
+
37663,
|
| 2480 |
+
37673,
|
| 2481 |
+
37692,
|
| 2482 |
+
37698,
|
| 2483 |
+
37701,
|
| 2484 |
+
37713,
|
| 2485 |
+
37719,
|
| 2486 |
+
37770,
|
| 2487 |
+
37790,
|
| 2488 |
+
37792,
|
| 2489 |
+
37807,
|
| 2490 |
+
37833,
|
| 2491 |
+
37844,
|
| 2492 |
+
37846,
|
| 2493 |
+
37859,
|
| 2494 |
+
37880,
|
| 2495 |
+
37890,
|
| 2496 |
+
37913,
|
| 2497 |
+
37927,
|
| 2498 |
+
37945,
|
| 2499 |
+
37959,
|
| 2500 |
+
37960,
|
| 2501 |
+
37994,
|
| 2502 |
+
38036,
|
| 2503 |
+
38085,
|
| 2504 |
+
38088,
|
| 2505 |
+
38104,
|
| 2506 |
+
38177,
|
| 2507 |
+
38178,
|
| 2508 |
+
38192,
|
| 2509 |
+
38209,
|
| 2510 |
+
38210,
|
| 2511 |
+
38225,
|
| 2512 |
+
38249,
|
| 2513 |
+
38250,
|
| 2514 |
+
38291,
|
| 2515 |
+
38320,
|
| 2516 |
+
38330,
|
| 2517 |
+
38356,
|
| 2518 |
+
38382,
|
| 2519 |
+
38386,
|
| 2520 |
+
38408,
|
| 2521 |
+
38419,
|
| 2522 |
+
38427,
|
| 2523 |
+
38433,
|
| 2524 |
+
38436,
|
| 2525 |
+
38441,
|
| 2526 |
+
38445,
|
| 2527 |
+
38459,
|
| 2528 |
+
38464,
|
| 2529 |
+
38497,
|
| 2530 |
+
38502,
|
| 2531 |
+
38522,
|
| 2532 |
+
38523,
|
| 2533 |
+
38535,
|
| 2534 |
+
38547,
|
| 2535 |
+
38564,
|
| 2536 |
+
38577,
|
| 2537 |
+
38584,
|
| 2538 |
+
38592,
|
| 2539 |
+
38607,
|
| 2540 |
+
38608,
|
| 2541 |
+
38609,
|
| 2542 |
+
38615,
|
| 2543 |
+
38646,
|
| 2544 |
+
38657,
|
| 2545 |
+
38669,
|
| 2546 |
+
38679,
|
| 2547 |
+
38691,
|
| 2548 |
+
38705,
|
| 2549 |
+
38707,
|
| 2550 |
+
38732,
|
| 2551 |
+
38738,
|
| 2552 |
+
38739,
|
| 2553 |
+
38772,
|
| 2554 |
+
38776,
|
| 2555 |
+
38802,
|
| 2556 |
+
38812,
|
| 2557 |
+
38837,
|
| 2558 |
+
38842,
|
| 2559 |
+
38852,
|
| 2560 |
+
38866,
|
| 2561 |
+
38881,
|
| 2562 |
+
38903,
|
| 2563 |
+
38911,
|
| 2564 |
+
38915,
|
| 2565 |
+
38942,
|
| 2566 |
+
38958,
|
| 2567 |
+
38962,
|
| 2568 |
+
38966,
|
| 2569 |
+
38981,
|
| 2570 |
+
39002,
|
| 2571 |
+
39004,
|
| 2572 |
+
39012,
|
| 2573 |
+
39019,
|
| 2574 |
+
39024,
|
| 2575 |
+
39025,
|
| 2576 |
+
39047,
|
| 2577 |
+
39071,
|
| 2578 |
+
39098,
|
| 2579 |
+
39137,
|
| 2580 |
+
39144,
|
| 2581 |
+
39147,
|
| 2582 |
+
39175,
|
| 2583 |
+
39193,
|
| 2584 |
+
39205,
|
| 2585 |
+
39206,
|
| 2586 |
+
39226,
|
| 2587 |
+
39276,
|
| 2588 |
+
39278,
|
| 2589 |
+
39290,
|
| 2590 |
+
39315,
|
| 2591 |
+
39317,
|
| 2592 |
+
39321,
|
| 2593 |
+
39327,
|
| 2594 |
+
39341,
|
| 2595 |
+
39365,
|
| 2596 |
+
39366,
|
| 2597 |
+
39417,
|
| 2598 |
+
39444,
|
| 2599 |
+
39464,
|
| 2600 |
+
39467,
|
| 2601 |
+
39503,
|
| 2602 |
+
39514,
|
| 2603 |
+
39524,
|
| 2604 |
+
39528,
|
| 2605 |
+
39555,
|
| 2606 |
+
39567,
|
| 2607 |
+
39569,
|
| 2608 |
+
39573,
|
| 2609 |
+
39595,
|
| 2610 |
+
39635,
|
| 2611 |
+
39647,
|
| 2612 |
+
39648,
|
| 2613 |
+
39663,
|
| 2614 |
+
39678,
|
| 2615 |
+
39680,
|
| 2616 |
+
39692,
|
| 2617 |
+
39724,
|
| 2618 |
+
39729,
|
| 2619 |
+
39734,
|
| 2620 |
+
39749,
|
| 2621 |
+
39769,
|
| 2622 |
+
39774,
|
| 2623 |
+
39778,
|
| 2624 |
+
39781,
|
| 2625 |
+
39789,
|
| 2626 |
+
39790,
|
| 2627 |
+
39805,
|
| 2628 |
+
39809,
|
| 2629 |
+
39821,
|
| 2630 |
+
39831,
|
| 2631 |
+
39834,
|
| 2632 |
+
39839,
|
| 2633 |
+
39865,
|
| 2634 |
+
39866,
|
| 2635 |
+
39887,
|
| 2636 |
+
39902,
|
| 2637 |
+
39908,
|
| 2638 |
+
39928,
|
| 2639 |
+
39945,
|
| 2640 |
+
39952,
|
| 2641 |
+
39955,
|
| 2642 |
+
39969,
|
| 2643 |
+
39974,
|
| 2644 |
+
40005,
|
| 2645 |
+
40007,
|
| 2646 |
+
40023,
|
| 2647 |
+
40044,
|
| 2648 |
+
40046,
|
| 2649 |
+
40056,
|
| 2650 |
+
40057,
|
| 2651 |
+
40071,
|
| 2652 |
+
40087,
|
| 2653 |
+
40148,
|
| 2654 |
+
40201,
|
| 2655 |
+
40250,
|
| 2656 |
+
40254,
|
| 2657 |
+
40268,
|
| 2658 |
+
40304,
|
| 2659 |
+
40317,
|
| 2660 |
+
40318,
|
| 2661 |
+
40330,
|
| 2662 |
+
40337,
|
| 2663 |
+
40401,
|
| 2664 |
+
40419,
|
| 2665 |
+
40494,
|
| 2666 |
+
40539,
|
| 2667 |
+
40548,
|
| 2668 |
+
40556,
|
| 2669 |
+
40571,
|
| 2670 |
+
40583,
|
| 2671 |
+
40589,
|
| 2672 |
+
40610,
|
| 2673 |
+
40612,
|
| 2674 |
+
40617,
|
| 2675 |
+
40625,
|
| 2676 |
+
40629,
|
| 2677 |
+
40642,
|
| 2678 |
+
40650,
|
| 2679 |
+
40653,
|
| 2680 |
+
40654,
|
| 2681 |
+
40666,
|
| 2682 |
+
40691,
|
| 2683 |
+
40714,
|
| 2684 |
+
40722,
|
| 2685 |
+
40723,
|
| 2686 |
+
40725,
|
| 2687 |
+
40732,
|
| 2688 |
+
40742,
|
| 2689 |
+
40747,
|
| 2690 |
+
40764,
|
| 2691 |
+
40771,
|
| 2692 |
+
40804,
|
| 2693 |
+
40840,
|
| 2694 |
+
40845,
|
| 2695 |
+
40877,
|
| 2696 |
+
40901,
|
| 2697 |
+
40919,
|
| 2698 |
+
40938,
|
| 2699 |
+
40949,
|
| 2700 |
+
40964,
|
| 2701 |
+
41025,
|
| 2702 |
+
41037,
|
| 2703 |
+
41040,
|
| 2704 |
+
41075,
|
| 2705 |
+
41091,
|
| 2706 |
+
41117,
|
| 2707 |
+
41129,
|
| 2708 |
+
41153,
|
| 2709 |
+
41165,
|
| 2710 |
+
41169,
|
| 2711 |
+
41191,
|
| 2712 |
+
41196,
|
| 2713 |
+
41197,
|
| 2714 |
+
41233,
|
| 2715 |
+
41236,
|
| 2716 |
+
41237,
|
| 2717 |
+
41263,
|
| 2718 |
+
41289,
|
| 2719 |
+
41295,
|
| 2720 |
+
41320,
|
| 2721 |
+
41344,
|
| 2722 |
+
41364,
|
| 2723 |
+
41399,
|
| 2724 |
+
41401,
|
| 2725 |
+
41405,
|
| 2726 |
+
41422,
|
| 2727 |
+
41446,
|
| 2728 |
+
41453,
|
| 2729 |
+
41458,
|
| 2730 |
+
41479,
|
| 2731 |
+
41491,
|
| 2732 |
+
41516,
|
| 2733 |
+
41529,
|
| 2734 |
+
41546,
|
| 2735 |
+
41553,
|
| 2736 |
+
41573,
|
| 2737 |
+
41577,
|
| 2738 |
+
41578,
|
| 2739 |
+
41583,
|
| 2740 |
+
41596,
|
| 2741 |
+
41620,
|
| 2742 |
+
41636,
|
| 2743 |
+
41649,
|
| 2744 |
+
41655,
|
| 2745 |
+
41693,
|
| 2746 |
+
41694,
|
| 2747 |
+
41749,
|
| 2748 |
+
41785,
|
| 2749 |
+
41794,
|
| 2750 |
+
41838,
|
| 2751 |
+
41843,
|
| 2752 |
+
41853,
|
| 2753 |
+
41864,
|
| 2754 |
+
41892,
|
| 2755 |
+
41902,
|
| 2756 |
+
41909,
|
| 2757 |
+
41920,
|
| 2758 |
+
41922,
|
| 2759 |
+
41940,
|
| 2760 |
+
41942,
|
| 2761 |
+
41952,
|
| 2762 |
+
41958,
|
| 2763 |
+
41998,
|
| 2764 |
+
42012,
|
| 2765 |
+
42013,
|
| 2766 |
+
42015,
|
| 2767 |
+
42059,
|
| 2768 |
+
42071,
|
| 2769 |
+
42073,
|
| 2770 |
+
42078,
|
| 2771 |
+
42080,
|
| 2772 |
+
42083,
|
| 2773 |
+
42109,
|
| 2774 |
+
42132,
|
| 2775 |
+
42144,
|
| 2776 |
+
42154,
|
| 2777 |
+
42179,
|
| 2778 |
+
42181,
|
| 2779 |
+
42182,
|
| 2780 |
+
42194,
|
| 2781 |
+
42197,
|
| 2782 |
+
42236,
|
| 2783 |
+
42252,
|
| 2784 |
+
42273,
|
| 2785 |
+
42303,
|
| 2786 |
+
42307,
|
| 2787 |
+
42311,
|
| 2788 |
+
42342,
|
| 2789 |
+
42344,
|
| 2790 |
+
42363,
|
| 2791 |
+
42372,
|
| 2792 |
+
42384,
|
| 2793 |
+
42392,
|
| 2794 |
+
42398,
|
| 2795 |
+
42419,
|
| 2796 |
+
42450,
|
| 2797 |
+
42455,
|
| 2798 |
+
42476,
|
| 2799 |
+
42519,
|
| 2800 |
+
42521,
|
| 2801 |
+
42534,
|
| 2802 |
+
42574,
|
| 2803 |
+
42595,
|
| 2804 |
+
42604,
|
| 2805 |
+
42618,
|
| 2806 |
+
42625,
|
| 2807 |
+
42718,
|
| 2808 |
+
42732,
|
| 2809 |
+
42735,
|
| 2810 |
+
42788,
|
| 2811 |
+
42795,
|
| 2812 |
+
42833,
|
| 2813 |
+
42849,
|
| 2814 |
+
42871,
|
| 2815 |
+
42892,
|
| 2816 |
+
42902,
|
| 2817 |
+
42999,
|
| 2818 |
+
43002,
|
| 2819 |
+
43005,
|
| 2820 |
+
43036,
|
| 2821 |
+
43057,
|
| 2822 |
+
43060,
|
| 2823 |
+
43146,
|
| 2824 |
+
43153,
|
| 2825 |
+
43163,
|
| 2826 |
+
43175,
|
| 2827 |
+
43196,
|
| 2828 |
+
43202,
|
| 2829 |
+
43234,
|
| 2830 |
+
43270,
|
| 2831 |
+
43284,
|
| 2832 |
+
43305,
|
| 2833 |
+
43317,
|
| 2834 |
+
43333,
|
| 2835 |
+
43336,
|
| 2836 |
+
43341,
|
| 2837 |
+
43349,
|
| 2838 |
+
43355,
|
| 2839 |
+
43373,
|
| 2840 |
+
43385,
|
| 2841 |
+
43397,
|
| 2842 |
+
43410,
|
| 2843 |
+
43448,
|
| 2844 |
+
43459,
|
| 2845 |
+
43471,
|
| 2846 |
+
43472,
|
| 2847 |
+
43488,
|
| 2848 |
+
43493,
|
| 2849 |
+
43501,
|
| 2850 |
+
43502,
|
| 2851 |
+
43507,
|
| 2852 |
+
43547,
|
| 2853 |
+
43552,
|
| 2854 |
+
43559,
|
| 2855 |
+
43575,
|
| 2856 |
+
43606,
|
| 2857 |
+
43608,
|
| 2858 |
+
43614,
|
| 2859 |
+
43644,
|
| 2860 |
+
43664,
|
| 2861 |
+
43691,
|
| 2862 |
+
43716,
|
| 2863 |
+
43720,
|
| 2864 |
+
43722,
|
| 2865 |
+
43724,
|
| 2866 |
+
43738,
|
| 2867 |
+
43752,
|
| 2868 |
+
43759,
|
| 2869 |
+
43779,
|
| 2870 |
+
43839,
|
| 2871 |
+
43853,
|
| 2872 |
+
43872,
|
| 2873 |
+
43886,
|
| 2874 |
+
43926,
|
| 2875 |
+
43946,
|
| 2876 |
+
43952,
|
| 2877 |
+
44004,
|
| 2878 |
+
44014,
|
| 2879 |
+
44044,
|
| 2880 |
+
44048,
|
| 2881 |
+
44051,
|
| 2882 |
+
44054,
|
| 2883 |
+
44062,
|
| 2884 |
+
44075,
|
| 2885 |
+
44098,
|
| 2886 |
+
44099,
|
| 2887 |
+
44103,
|
| 2888 |
+
44104,
|
| 2889 |
+
44122,
|
| 2890 |
+
44132,
|
| 2891 |
+
44142,
|
| 2892 |
+
44147,
|
| 2893 |
+
44155,
|
| 2894 |
+
44163,
|
| 2895 |
+
44194,
|
| 2896 |
+
44212,
|
| 2897 |
+
44258,
|
| 2898 |
+
44292,
|
| 2899 |
+
44307,
|
| 2900 |
+
44311,
|
| 2901 |
+
44316,
|
| 2902 |
+
44342,
|
| 2903 |
+
44360,
|
| 2904 |
+
44364,
|
| 2905 |
+
44383,
|
| 2906 |
+
44386,
|
| 2907 |
+
44388,
|
| 2908 |
+
44401,
|
| 2909 |
+
44415,
|
| 2910 |
+
44416,
|
| 2911 |
+
44481,
|
| 2912 |
+
44490,
|
| 2913 |
+
44504,
|
| 2914 |
+
44568,
|
| 2915 |
+
44608,
|
| 2916 |
+
44611,
|
| 2917 |
+
44635,
|
| 2918 |
+
44651,
|
| 2919 |
+
44654,
|
| 2920 |
+
44660,
|
| 2921 |
+
44665,
|
| 2922 |
+
44680,
|
| 2923 |
+
44702,
|
| 2924 |
+
44706,
|
| 2925 |
+
44720,
|
| 2926 |
+
44723,
|
| 2927 |
+
44726,
|
| 2928 |
+
44732,
|
| 2929 |
+
44735,
|
| 2930 |
+
44746,
|
| 2931 |
+
44749,
|
| 2932 |
+
44752,
|
| 2933 |
+
44784,
|
| 2934 |
+
44811,
|
| 2935 |
+
44818,
|
| 2936 |
+
44824,
|
| 2937 |
+
44828,
|
| 2938 |
+
44832,
|
| 2939 |
+
44834,
|
| 2940 |
+
44841,
|
| 2941 |
+
44851,
|
| 2942 |
+
44862,
|
| 2943 |
+
44888,
|
| 2944 |
+
44891,
|
| 2945 |
+
44955,
|
| 2946 |
+
44957,
|
| 2947 |
+
44959,
|
| 2948 |
+
44965,
|
| 2949 |
+
44970,
|
| 2950 |
+
44973,
|
| 2951 |
+
44993,
|
| 2952 |
+
45014,
|
| 2953 |
+
45016,
|
| 2954 |
+
45023,
|
| 2955 |
+
45027,
|
| 2956 |
+
45029,
|
| 2957 |
+
45030,
|
| 2958 |
+
45033,
|
| 2959 |
+
45076,
|
| 2960 |
+
45100,
|
| 2961 |
+
45104,
|
| 2962 |
+
45119,
|
| 2963 |
+
45128,
|
| 2964 |
+
45130,
|
| 2965 |
+
45164,
|
| 2966 |
+
45169,
|
| 2967 |
+
45175,
|
| 2968 |
+
45219,
|
| 2969 |
+
45244,
|
| 2970 |
+
45313,
|
| 2971 |
+
45320,
|
| 2972 |
+
45335,
|
| 2973 |
+
45349,
|
| 2974 |
+
45375,
|
| 2975 |
+
45385,
|
| 2976 |
+
45407,
|
| 2977 |
+
45426,
|
| 2978 |
+
45432,
|
| 2979 |
+
45434,
|
| 2980 |
+
45438,
|
| 2981 |
+
45443,
|
| 2982 |
+
45456,
|
| 2983 |
+
45538,
|
| 2984 |
+
45575,
|
| 2985 |
+
45608,
|
| 2986 |
+
45609,
|
| 2987 |
+
45611,
|
| 2988 |
+
45626,
|
| 2989 |
+
45632,
|
| 2990 |
+
45638,
|
| 2991 |
+
45649,
|
| 2992 |
+
45675,
|
| 2993 |
+
45676,
|
| 2994 |
+
45705,
|
| 2995 |
+
45722,
|
| 2996 |
+
45748,
|
| 2997 |
+
45752,
|
| 2998 |
+
45806,
|
| 2999 |
+
45807,
|
| 3000 |
+
45811,
|
| 3001 |
+
45814,
|
| 3002 |
+
45830,
|
| 3003 |
+
45850,
|
| 3004 |
+
45858,
|
| 3005 |
+
45875,
|
| 3006 |
+
45881,
|
| 3007 |
+
45904,
|
| 3008 |
+
45924,
|
| 3009 |
+
45929,
|
| 3010 |
+
45961,
|
| 3011 |
+
45982,
|
| 3012 |
+
46006,
|
| 3013 |
+
46018,
|
| 3014 |
+
46021,
|
| 3015 |
+
46030,
|
| 3016 |
+
46046,
|
| 3017 |
+
46091,
|
| 3018 |
+
46151,
|
| 3019 |
+
46165,
|
| 3020 |
+
46186,
|
| 3021 |
+
46203,
|
| 3022 |
+
46215,
|
| 3023 |
+
46218,
|
| 3024 |
+
46225,
|
| 3025 |
+
46232,
|
| 3026 |
+
46251,
|
| 3027 |
+
46255,
|
| 3028 |
+
46259,
|
| 3029 |
+
46277,
|
| 3030 |
+
46282,
|
| 3031 |
+
46338,
|
| 3032 |
+
46341,
|
| 3033 |
+
46346,
|
| 3034 |
+
46353,
|
| 3035 |
+
46356,
|
| 3036 |
+
46373,
|
| 3037 |
+
46418,
|
| 3038 |
+
46426,
|
| 3039 |
+
46434,
|
| 3040 |
+
46442,
|
| 3041 |
+
46452,
|
| 3042 |
+
46500,
|
| 3043 |
+
46505,
|
| 3044 |
+
46519,
|
| 3045 |
+
46542,
|
| 3046 |
+
46548,
|
| 3047 |
+
46556,
|
| 3048 |
+
46577,
|
| 3049 |
+
46602,
|
| 3050 |
+
46605,
|
| 3051 |
+
46607,
|
| 3052 |
+
46644,
|
| 3053 |
+
46649,
|
| 3054 |
+
46656,
|
| 3055 |
+
46729,
|
| 3056 |
+
46739,
|
| 3057 |
+
46744,
|
| 3058 |
+
46750,
|
| 3059 |
+
46789,
|
| 3060 |
+
46796,
|
| 3061 |
+
46800,
|
| 3062 |
+
46801,
|
| 3063 |
+
46826,
|
| 3064 |
+
46827,
|
| 3065 |
+
46832,
|
| 3066 |
+
46851,
|
| 3067 |
+
46871,
|
| 3068 |
+
46873,
|
| 3069 |
+
46896,
|
| 3070 |
+
46903,
|
| 3071 |
+
46914,
|
| 3072 |
+
46964,
|
| 3073 |
+
46986,
|
| 3074 |
+
46998,
|
| 3075 |
+
47022,
|
| 3076 |
+
47065,
|
| 3077 |
+
47080,
|
| 3078 |
+
47101,
|
| 3079 |
+
47135,
|
| 3080 |
+
47144,
|
| 3081 |
+
47152,
|
| 3082 |
+
47184,
|
| 3083 |
+
47189,
|
| 3084 |
+
47207,
|
| 3085 |
+
47215,
|
| 3086 |
+
47218,
|
| 3087 |
+
47221,
|
| 3088 |
+
47254,
|
| 3089 |
+
47266,
|
| 3090 |
+
47300,
|
| 3091 |
+
47326,
|
| 3092 |
+
47336,
|
| 3093 |
+
47362,
|
| 3094 |
+
47369,
|
| 3095 |
+
47378,
|
| 3096 |
+
47379,
|
| 3097 |
+
47383,
|
| 3098 |
+
47415,
|
| 3099 |
+
47423,
|
| 3100 |
+
47446,
|
| 3101 |
+
47449,
|
| 3102 |
+
47453,
|
| 3103 |
+
47455,
|
| 3104 |
+
47456,
|
| 3105 |
+
47486,
|
| 3106 |
+
47489,
|
| 3107 |
+
47494,
|
| 3108 |
+
47503,
|
| 3109 |
+
47505,
|
| 3110 |
+
47527,
|
| 3111 |
+
47531,
|
| 3112 |
+
47552,
|
| 3113 |
+
47563,
|
| 3114 |
+
47603,
|
| 3115 |
+
47614,
|
| 3116 |
+
47616,
|
| 3117 |
+
47617,
|
| 3118 |
+
47620,
|
| 3119 |
+
47665,
|
| 3120 |
+
47683,
|
| 3121 |
+
47717,
|
| 3122 |
+
47726,
|
| 3123 |
+
47729,
|
| 3124 |
+
47760,
|
| 3125 |
+
47761,
|
| 3126 |
+
47785,
|
| 3127 |
+
47843,
|
| 3128 |
+
47857,
|
| 3129 |
+
47867,
|
| 3130 |
+
47893,
|
| 3131 |
+
47895,
|
| 3132 |
+
47911,
|
| 3133 |
+
47915,
|
| 3134 |
+
47936,
|
| 3135 |
+
47966,
|
| 3136 |
+
47972,
|
| 3137 |
+
47979,
|
| 3138 |
+
47989,
|
| 3139 |
+
48018,
|
| 3140 |
+
48030,
|
| 3141 |
+
48046,
|
| 3142 |
+
48059,
|
| 3143 |
+
48064,
|
| 3144 |
+
48076,
|
| 3145 |
+
48085,
|
| 3146 |
+
48108,
|
| 3147 |
+
48109,
|
| 3148 |
+
48115,
|
| 3149 |
+
48116,
|
| 3150 |
+
48139,
|
| 3151 |
+
48148,
|
| 3152 |
+
48174,
|
| 3153 |
+
48230,
|
| 3154 |
+
48242,
|
| 3155 |
+
48269,
|
| 3156 |
+
48271,
|
| 3157 |
+
48272,
|
| 3158 |
+
48281,
|
| 3159 |
+
48312,
|
| 3160 |
+
48320,
|
| 3161 |
+
48321,
|
| 3162 |
+
48330,
|
| 3163 |
+
48340,
|
| 3164 |
+
48364,
|
| 3165 |
+
48396,
|
| 3166 |
+
48405,
|
| 3167 |
+
48426,
|
| 3168 |
+
48443,
|
| 3169 |
+
48455,
|
| 3170 |
+
48458,
|
| 3171 |
+
48462,
|
| 3172 |
+
48503,
|
| 3173 |
+
48527,
|
| 3174 |
+
48531,
|
| 3175 |
+
48533,
|
| 3176 |
+
48566,
|
| 3177 |
+
48571,
|
| 3178 |
+
48591,
|
| 3179 |
+
48603,
|
| 3180 |
+
48622,
|
| 3181 |
+
48643,
|
| 3182 |
+
48644,
|
| 3183 |
+
48645,
|
| 3184 |
+
48651,
|
| 3185 |
+
48654,
|
| 3186 |
+
48656,
|
| 3187 |
+
48666,
|
| 3188 |
+
48668,
|
| 3189 |
+
48683,
|
| 3190 |
+
48690,
|
| 3191 |
+
48721,
|
| 3192 |
+
48724,
|
| 3193 |
+
48727,
|
| 3194 |
+
48746,
|
| 3195 |
+
48749,
|
| 3196 |
+
48754,
|
| 3197 |
+
48800,
|
| 3198 |
+
48814,
|
| 3199 |
+
48817,
|
| 3200 |
+
48840,
|
| 3201 |
+
48885,
|
| 3202 |
+
48898,
|
| 3203 |
+
48937,
|
| 3204 |
+
48949,
|
| 3205 |
+
48950,
|
| 3206 |
+
48953,
|
| 3207 |
+
48962,
|
| 3208 |
+
48967,
|
| 3209 |
+
48974,
|
| 3210 |
+
48997,
|
| 3211 |
+
49038,
|
| 3212 |
+
49048,
|
| 3213 |
+
49071,
|
| 3214 |
+
49088,
|
| 3215 |
+
49092,
|
| 3216 |
+
49100,
|
| 3217 |
+
49106,
|
| 3218 |
+
49116,
|
| 3219 |
+
49128,
|
| 3220 |
+
49129,
|
| 3221 |
+
49155,
|
| 3222 |
+
49166,
|
| 3223 |
+
49173,
|
| 3224 |
+
49174,
|
| 3225 |
+
49196,
|
| 3226 |
+
49217,
|
| 3227 |
+
49235,
|
| 3228 |
+
49237,
|
| 3229 |
+
49245,
|
| 3230 |
+
49248,
|
| 3231 |
+
49254,
|
| 3232 |
+
49270,
|
| 3233 |
+
49289,
|
| 3234 |
+
49323,
|
| 3235 |
+
49348,
|
| 3236 |
+
49408,
|
| 3237 |
+
49420,
|
| 3238 |
+
49422,
|
| 3239 |
+
49434,
|
| 3240 |
+
49475,
|
| 3241 |
+
49493,
|
| 3242 |
+
49542,
|
| 3243 |
+
49548,
|
| 3244 |
+
49555,
|
| 3245 |
+
49577,
|
| 3246 |
+
49589,
|
| 3247 |
+
49595,
|
| 3248 |
+
49602,
|
| 3249 |
+
49618,
|
| 3250 |
+
49622,
|
| 3251 |
+
49624,
|
| 3252 |
+
49669,
|
| 3253 |
+
49725,
|
| 3254 |
+
49747,
|
| 3255 |
+
49760,
|
| 3256 |
+
49777,
|
| 3257 |
+
49810,
|
| 3258 |
+
49854,
|
| 3259 |
+
49884,
|
| 3260 |
+
49897,
|
| 3261 |
+
49901,
|
| 3262 |
+
49917,
|
| 3263 |
+
49923,
|
| 3264 |
+
49943,
|
| 3265 |
+
49957,
|
| 3266 |
+
49962,
|
| 3267 |
+
49987,
|
| 3268 |
+
50048,
|
| 3269 |
+
50075,
|
| 3270 |
+
50102,
|
| 3271 |
+
50111,
|
| 3272 |
+
50119,
|
| 3273 |
+
50121,
|
| 3274 |
+
50134,
|
| 3275 |
+
50165,
|
| 3276 |
+
50177,
|
| 3277 |
+
50188,
|
| 3278 |
+
50236,
|
| 3279 |
+
50245,
|
| 3280 |
+
50294,
|
| 3281 |
+
50305,
|
| 3282 |
+
50316,
|
| 3283 |
+
50320,
|
| 3284 |
+
50347,
|
| 3285 |
+
50362,
|
| 3286 |
+
50432,
|
| 3287 |
+
50474,
|
| 3288 |
+
50496,
|
| 3289 |
+
50510,
|
| 3290 |
+
50514,
|
| 3291 |
+
50524,
|
| 3292 |
+
50534,
|
| 3293 |
+
50549,
|
| 3294 |
+
50593,
|
| 3295 |
+
50599,
|
| 3296 |
+
50600,
|
| 3297 |
+
50608,
|
| 3298 |
+
50640,
|
| 3299 |
+
50680,
|
| 3300 |
+
50713,
|
| 3301 |
+
50714,
|
| 3302 |
+
50718,
|
| 3303 |
+
50721,
|
| 3304 |
+
50724,
|
| 3305 |
+
50746,
|
| 3306 |
+
50758,
|
| 3307 |
+
50760,
|
| 3308 |
+
50803,
|
| 3309 |
+
50805,
|
| 3310 |
+
50807,
|
| 3311 |
+
50841,
|
| 3312 |
+
50869,
|
| 3313 |
+
50886,
|
| 3314 |
+
50919,
|
| 3315 |
+
50928,
|
| 3316 |
+
50938,
|
| 3317 |
+
50940,
|
| 3318 |
+
50948,
|
| 3319 |
+
50950,
|
| 3320 |
+
50963,
|
| 3321 |
+
50970,
|
| 3322 |
+
50978,
|
| 3323 |
+
50989,
|
| 3324 |
+
50994,
|
| 3325 |
+
51012,
|
| 3326 |
+
51027,
|
| 3327 |
+
51028,
|
| 3328 |
+
51030,
|
| 3329 |
+
51048,
|
| 3330 |
+
51067,
|
| 3331 |
+
51076,
|
| 3332 |
+
51088,
|
| 3333 |
+
51100,
|
| 3334 |
+
51113,
|
| 3335 |
+
51118,
|
| 3336 |
+
51124,
|
| 3337 |
+
51126,
|
| 3338 |
+
51128,
|
| 3339 |
+
51141,
|
| 3340 |
+
51200,
|
| 3341 |
+
51264,
|
| 3342 |
+
51275,
|
| 3343 |
+
51278,
|
| 3344 |
+
51308,
|
| 3345 |
+
51356,
|
| 3346 |
+
51363,
|
| 3347 |
+
51364,
|
| 3348 |
+
51377,
|
| 3349 |
+
51386,
|
| 3350 |
+
51387,
|
| 3351 |
+
51414,
|
| 3352 |
+
51418,
|
| 3353 |
+
51423,
|
| 3354 |
+
51427,
|
| 3355 |
+
51442,
|
| 3356 |
+
51461,
|
| 3357 |
+
51480,
|
| 3358 |
+
51494,
|
| 3359 |
+
51497,
|
| 3360 |
+
51506,
|
| 3361 |
+
51507,
|
| 3362 |
+
51519,
|
| 3363 |
+
51622,
|
| 3364 |
+
51632,
|
| 3365 |
+
51658,
|
| 3366 |
+
51666,
|
| 3367 |
+
51669,
|
| 3368 |
+
51672,
|
| 3369 |
+
51687,
|
| 3370 |
+
51746,
|
| 3371 |
+
51750,
|
| 3372 |
+
51752,
|
| 3373 |
+
51754,
|
| 3374 |
+
51787,
|
| 3375 |
+
51796,
|
| 3376 |
+
51814,
|
| 3377 |
+
51820,
|
| 3378 |
+
51837,
|
| 3379 |
+
51877,
|
| 3380 |
+
51902,
|
| 3381 |
+
51912,
|
| 3382 |
+
51921,
|
| 3383 |
+
51944,
|
| 3384 |
+
51946,
|
| 3385 |
+
52011,
|
| 3386 |
+
52027,
|
| 3387 |
+
52031,
|
| 3388 |
+
52039,
|
| 3389 |
+
52054,
|
| 3390 |
+
52072,
|
| 3391 |
+
52073,
|
| 3392 |
+
52080,
|
| 3393 |
+
52133,
|
| 3394 |
+
52154,
|
| 3395 |
+
52169,
|
| 3396 |
+
52187,
|
| 3397 |
+
52195,
|
| 3398 |
+
52240,
|
| 3399 |
+
52252,
|
| 3400 |
+
52262,
|
| 3401 |
+
52268,
|
| 3402 |
+
52285,
|
| 3403 |
+
52294,
|
| 3404 |
+
52324,
|
| 3405 |
+
52338,
|
| 3406 |
+
52347,
|
| 3407 |
+
52372,
|
| 3408 |
+
52386,
|
| 3409 |
+
52388,
|
| 3410 |
+
52397,
|
| 3411 |
+
52408,
|
| 3412 |
+
52411,
|
| 3413 |
+
52438,
|
| 3414 |
+
52444,
|
| 3415 |
+
52462,
|
| 3416 |
+
52463,
|
| 3417 |
+
52474,
|
| 3418 |
+
52481,
|
| 3419 |
+
52489,
|
| 3420 |
+
52506,
|
| 3421 |
+
52516,
|
| 3422 |
+
52527,
|
| 3423 |
+
52531,
|
| 3424 |
+
52574,
|
| 3425 |
+
52599,
|
| 3426 |
+
52607,
|
| 3427 |
+
52610,
|
| 3428 |
+
52613,
|
| 3429 |
+
52617,
|
| 3430 |
+
52620,
|
| 3431 |
+
52623,
|
| 3432 |
+
52629,
|
| 3433 |
+
52664,
|
| 3434 |
+
52684,
|
| 3435 |
+
52699,
|
| 3436 |
+
52707,
|
| 3437 |
+
52714,
|
| 3438 |
+
52720,
|
| 3439 |
+
52731,
|
| 3440 |
+
52792,
|
| 3441 |
+
52797,
|
| 3442 |
+
52798,
|
| 3443 |
+
52806,
|
| 3444 |
+
52818,
|
| 3445 |
+
52859,
|
| 3446 |
+
52887,
|
| 3447 |
+
52976,
|
| 3448 |
+
52981,
|
| 3449 |
+
52991,
|
| 3450 |
+
53005,
|
| 3451 |
+
53006,
|
| 3452 |
+
53025,
|
| 3453 |
+
53075,
|
| 3454 |
+
53099,
|
| 3455 |
+
53111,
|
| 3456 |
+
53126,
|
| 3457 |
+
53136,
|
| 3458 |
+
53196,
|
| 3459 |
+
53278,
|
| 3460 |
+
53279,
|
| 3461 |
+
53304,
|
| 3462 |
+
53321,
|
| 3463 |
+
53322,
|
| 3464 |
+
53372,
|
| 3465 |
+
53418,
|
| 3466 |
+
53430,
|
| 3467 |
+
53437,
|
| 3468 |
+
53440,
|
| 3469 |
+
53496,
|
| 3470 |
+
53497,
|
| 3471 |
+
53505,
|
| 3472 |
+
53556,
|
| 3473 |
+
53560,
|
| 3474 |
+
53589,
|
| 3475 |
+
53599,
|
| 3476 |
+
53600,
|
| 3477 |
+
53614,
|
| 3478 |
+
53632,
|
| 3479 |
+
53675,
|
| 3480 |
+
53722,
|
| 3481 |
+
53736,
|
| 3482 |
+
53740,
|
| 3483 |
+
53751,
|
| 3484 |
+
53780,
|
| 3485 |
+
53781,
|
| 3486 |
+
53808,
|
| 3487 |
+
53810,
|
| 3488 |
+
53815,
|
| 3489 |
+
53848,
|
| 3490 |
+
53895,
|
| 3491 |
+
53897,
|
| 3492 |
+
53916,
|
| 3493 |
+
53922,
|
| 3494 |
+
53923,
|
| 3495 |
+
53949,
|
| 3496 |
+
53973,
|
| 3497 |
+
53982,
|
| 3498 |
+
53989,
|
| 3499 |
+
53995,
|
| 3500 |
+
54027,
|
| 3501 |
+
54028,
|
| 3502 |
+
54050,
|
| 3503 |
+
54053,
|
| 3504 |
+
54060,
|
| 3505 |
+
54093,
|
| 3506 |
+
54108,
|
| 3507 |
+
54109,
|
| 3508 |
+
54128,
|
| 3509 |
+
54130,
|
| 3510 |
+
54131,
|
| 3511 |
+
54136,
|
| 3512 |
+
54145,
|
| 3513 |
+
54201,
|
| 3514 |
+
54203,
|
| 3515 |
+
54210,
|
| 3516 |
+
54229,
|
| 3517 |
+
54258,
|
| 3518 |
+
54268,
|
| 3519 |
+
54296,
|
| 3520 |
+
54323,
|
| 3521 |
+
54378,
|
| 3522 |
+
54394,
|
| 3523 |
+
54402,
|
| 3524 |
+
54403,
|
| 3525 |
+
54436,
|
| 3526 |
+
54443,
|
| 3527 |
+
54453,
|
| 3528 |
+
54457,
|
| 3529 |
+
54463,
|
| 3530 |
+
54470,
|
| 3531 |
+
54471,
|
| 3532 |
+
54489,
|
| 3533 |
+
54491,
|
| 3534 |
+
54492,
|
| 3535 |
+
54494,
|
| 3536 |
+
54496,
|
| 3537 |
+
54538,
|
| 3538 |
+
54597,
|
| 3539 |
+
54599,
|
| 3540 |
+
54616,
|
| 3541 |
+
54622,
|
| 3542 |
+
54630,
|
| 3543 |
+
54642,
|
| 3544 |
+
54646,
|
| 3545 |
+
54672,
|
| 3546 |
+
54680,
|
| 3547 |
+
54693,
|
| 3548 |
+
54697,
|
| 3549 |
+
54699,
|
| 3550 |
+
54702,
|
| 3551 |
+
54716,
|
| 3552 |
+
54728,
|
| 3553 |
+
54769,
|
| 3554 |
+
54784,
|
| 3555 |
+
54786,
|
| 3556 |
+
54837,
|
| 3557 |
+
54869,
|
| 3558 |
+
54878,
|
| 3559 |
+
54880,
|
| 3560 |
+
54907,
|
| 3561 |
+
54914,
|
| 3562 |
+
54924,
|
| 3563 |
+
54934,
|
| 3564 |
+
54941,
|
| 3565 |
+
54955,
|
| 3566 |
+
54978,
|
| 3567 |
+
54980,
|
| 3568 |
+
54995,
|
| 3569 |
+
55008,
|
| 3570 |
+
55030,
|
| 3571 |
+
55051,
|
| 3572 |
+
55059,
|
| 3573 |
+
55064,
|
| 3574 |
+
55065,
|
| 3575 |
+
55073,
|
| 3576 |
+
55079,
|
| 3577 |
+
55087,
|
| 3578 |
+
55098,
|
| 3579 |
+
55120,
|
| 3580 |
+
55122,
|
| 3581 |
+
55144,
|
| 3582 |
+
55157,
|
| 3583 |
+
55168,
|
| 3584 |
+
55178,
|
| 3585 |
+
55186,
|
| 3586 |
+
55187,
|
| 3587 |
+
55188,
|
| 3588 |
+
55212,
|
| 3589 |
+
55223,
|
| 3590 |
+
55224,
|
| 3591 |
+
55226,
|
| 3592 |
+
55237,
|
| 3593 |
+
55243,
|
| 3594 |
+
55266,
|
| 3595 |
+
55280,
|
| 3596 |
+
55283,
|
| 3597 |
+
55342,
|
| 3598 |
+
55350,
|
| 3599 |
+
55414,
|
| 3600 |
+
55421,
|
| 3601 |
+
55430,
|
| 3602 |
+
55435,
|
| 3603 |
+
55447,
|
| 3604 |
+
55458,
|
| 3605 |
+
55479,
|
| 3606 |
+
55483,
|
| 3607 |
+
55493,
|
| 3608 |
+
55504,
|
| 3609 |
+
55531,
|
| 3610 |
+
55546,
|
| 3611 |
+
55556,
|
| 3612 |
+
55561,
|
| 3613 |
+
55574,
|
| 3614 |
+
55589,
|
| 3615 |
+
55681,
|
| 3616 |
+
55685,
|
| 3617 |
+
55691,
|
| 3618 |
+
55698,
|
| 3619 |
+
55702,
|
| 3620 |
+
55705,
|
| 3621 |
+
55722,
|
| 3622 |
+
55729,
|
| 3623 |
+
55750,
|
| 3624 |
+
55764,
|
| 3625 |
+
55783,
|
| 3626 |
+
55809,
|
| 3627 |
+
55819,
|
| 3628 |
+
55823,
|
| 3629 |
+
55828,
|
| 3630 |
+
55838,
|
| 3631 |
+
55855,
|
| 3632 |
+
55890,
|
| 3633 |
+
55919,
|
| 3634 |
+
55924,
|
| 3635 |
+
55927,
|
| 3636 |
+
55957,
|
| 3637 |
+
55961,
|
| 3638 |
+
55962,
|
| 3639 |
+
55969,
|
| 3640 |
+
55979,
|
| 3641 |
+
55983,
|
| 3642 |
+
56002,
|
| 3643 |
+
56024,
|
| 3644 |
+
56040,
|
| 3645 |
+
56041,
|
| 3646 |
+
56045,
|
| 3647 |
+
56058,
|
| 3648 |
+
56062,
|
| 3649 |
+
56065,
|
| 3650 |
+
56073,
|
| 3651 |
+
56085,
|
| 3652 |
+
56114,
|
| 3653 |
+
56121,
|
| 3654 |
+
56132,
|
| 3655 |
+
56141,
|
| 3656 |
+
56144,
|
| 3657 |
+
56154,
|
| 3658 |
+
56162,
|
| 3659 |
+
56177,
|
| 3660 |
+
56247,
|
| 3661 |
+
56252,
|
| 3662 |
+
56268,
|
| 3663 |
+
56286,
|
| 3664 |
+
56291,
|
| 3665 |
+
56293,
|
| 3666 |
+
56337,
|
| 3667 |
+
56339,
|
| 3668 |
+
56351,
|
| 3669 |
+
56361,
|
| 3670 |
+
56391,
|
| 3671 |
+
56422,
|
| 3672 |
+
56504,
|
| 3673 |
+
56596,
|
| 3674 |
+
56606,
|
| 3675 |
+
56701,
|
| 3676 |
+
56703,
|
| 3677 |
+
56718,
|
| 3678 |
+
56761,
|
| 3679 |
+
56779,
|
| 3680 |
+
56782,
|
| 3681 |
+
56823,
|
| 3682 |
+
56831,
|
| 3683 |
+
56842,
|
| 3684 |
+
56870,
|
| 3685 |
+
56877,
|
| 3686 |
+
56882,
|
| 3687 |
+
56890,
|
| 3688 |
+
56912,
|
| 3689 |
+
56948,
|
| 3690 |
+
56962,
|
| 3691 |
+
56964,
|
| 3692 |
+
56980,
|
| 3693 |
+
56993,
|
| 3694 |
+
57018,
|
| 3695 |
+
57036,
|
| 3696 |
+
57048,
|
| 3697 |
+
57050,
|
| 3698 |
+
57068,
|
| 3699 |
+
57069,
|
| 3700 |
+
57073,
|
| 3701 |
+
57130,
|
| 3702 |
+
57133,
|
| 3703 |
+
57150,
|
| 3704 |
+
57154,
|
| 3705 |
+
57160,
|
| 3706 |
+
57178,
|
| 3707 |
+
57183,
|
| 3708 |
+
57213,
|
| 3709 |
+
57214,
|
| 3710 |
+
57223,
|
| 3711 |
+
57224,
|
| 3712 |
+
57249,
|
| 3713 |
+
57252,
|
| 3714 |
+
57307,
|
| 3715 |
+
57320,
|
| 3716 |
+
57332,
|
| 3717 |
+
57350,
|
| 3718 |
+
57351,
|
| 3719 |
+
57352,
|
| 3720 |
+
57362,
|
| 3721 |
+
57374,
|
| 3722 |
+
57384,
|
| 3723 |
+
57395,
|
| 3724 |
+
57425,
|
| 3725 |
+
57439,
|
| 3726 |
+
57475,
|
| 3727 |
+
57495,
|
| 3728 |
+
57524,
|
| 3729 |
+
57535,
|
| 3730 |
+
57545,
|
| 3731 |
+
57551,
|
| 3732 |
+
57564,
|
| 3733 |
+
57565,
|
| 3734 |
+
57570,
|
| 3735 |
+
57574,
|
| 3736 |
+
57576,
|
| 3737 |
+
57590,
|
| 3738 |
+
57599,
|
| 3739 |
+
57619,
|
| 3740 |
+
57709,
|
| 3741 |
+
57723,
|
| 3742 |
+
57737,
|
| 3743 |
+
57743,
|
| 3744 |
+
57758,
|
| 3745 |
+
57777,
|
| 3746 |
+
57786,
|
| 3747 |
+
57788,
|
| 3748 |
+
57798,
|
| 3749 |
+
57802,
|
| 3750 |
+
57807,
|
| 3751 |
+
57836,
|
| 3752 |
+
57862,
|
| 3753 |
+
57865,
|
| 3754 |
+
57867,
|
| 3755 |
+
57879,
|
| 3756 |
+
57887,
|
| 3757 |
+
57891,
|
| 3758 |
+
57911,
|
| 3759 |
+
57944,
|
| 3760 |
+
57956,
|
| 3761 |
+
57968,
|
| 3762 |
+
57979,
|
| 3763 |
+
58007,
|
| 3764 |
+
58018,
|
| 3765 |
+
58053,
|
| 3766 |
+
58062,
|
| 3767 |
+
58071,
|
| 3768 |
+
58081,
|
| 3769 |
+
58087,
|
| 3770 |
+
58092,
|
| 3771 |
+
58098,
|
| 3772 |
+
58128,
|
| 3773 |
+
58136,
|
| 3774 |
+
58157,
|
| 3775 |
+
58169,
|
| 3776 |
+
58172,
|
| 3777 |
+
58174,
|
| 3778 |
+
58177,
|
| 3779 |
+
58201,
|
| 3780 |
+
58208,
|
| 3781 |
+
58219,
|
| 3782 |
+
58230,
|
| 3783 |
+
58265,
|
| 3784 |
+
58290,
|
| 3785 |
+
58291,
|
| 3786 |
+
58299,
|
| 3787 |
+
58336,
|
| 3788 |
+
58337,
|
| 3789 |
+
58338,
|
| 3790 |
+
58359,
|
| 3791 |
+
58375,
|
| 3792 |
+
58384,
|
| 3793 |
+
58389,
|
| 3794 |
+
58406,
|
| 3795 |
+
58407,
|
| 3796 |
+
58410,
|
| 3797 |
+
58418,
|
| 3798 |
+
58423,
|
| 3799 |
+
58433,
|
| 3800 |
+
58445,
|
| 3801 |
+
58464,
|
| 3802 |
+
58501,
|
| 3803 |
+
58522,
|
| 3804 |
+
58557,
|
| 3805 |
+
58559,
|
| 3806 |
+
58590,
|
| 3807 |
+
58602,
|
| 3808 |
+
58606,
|
| 3809 |
+
58627,
|
| 3810 |
+
58629,
|
| 3811 |
+
58645,
|
| 3812 |
+
58658,
|
| 3813 |
+
58715,
|
| 3814 |
+
58724,
|
| 3815 |
+
58789,
|
| 3816 |
+
58831,
|
| 3817 |
+
58869,
|
| 3818 |
+
58872,
|
| 3819 |
+
58899,
|
| 3820 |
+
58902,
|
| 3821 |
+
58934,
|
| 3822 |
+
58935,
|
| 3823 |
+
58942,
|
| 3824 |
+
58949,
|
| 3825 |
+
58957,
|
| 3826 |
+
58958,
|
| 3827 |
+
58994,
|
| 3828 |
+
59000,
|
| 3829 |
+
59024,
|
| 3830 |
+
59026,
|
| 3831 |
+
59036,
|
| 3832 |
+
59043,
|
| 3833 |
+
59049,
|
| 3834 |
+
59053,
|
| 3835 |
+
59093,
|
| 3836 |
+
59101,
|
| 3837 |
+
59125,
|
| 3838 |
+
59139,
|
| 3839 |
+
59154,
|
| 3840 |
+
59204,
|
| 3841 |
+
59208,
|
| 3842 |
+
59209,
|
| 3843 |
+
59210,
|
| 3844 |
+
59216,
|
| 3845 |
+
59217,
|
| 3846 |
+
59312,
|
| 3847 |
+
59336,
|
| 3848 |
+
59360,
|
| 3849 |
+
59403,
|
| 3850 |
+
59404,
|
| 3851 |
+
59423,
|
| 3852 |
+
59454,
|
| 3853 |
+
59461,
|
| 3854 |
+
59475,
|
| 3855 |
+
59478,
|
| 3856 |
+
59479,
|
| 3857 |
+
59480,
|
| 3858 |
+
59482,
|
| 3859 |
+
59483,
|
| 3860 |
+
59484,
|
| 3861 |
+
59509,
|
| 3862 |
+
59544,
|
| 3863 |
+
59564,
|
| 3864 |
+
59581,
|
| 3865 |
+
59591,
|
| 3866 |
+
59603,
|
| 3867 |
+
59610,
|
| 3868 |
+
59611,
|
| 3869 |
+
59630,
|
| 3870 |
+
59649,
|
| 3871 |
+
59712,
|
| 3872 |
+
59757,
|
| 3873 |
+
59792,
|
| 3874 |
+
59841,
|
| 3875 |
+
59845,
|
| 3876 |
+
59865,
|
| 3877 |
+
59867,
|
| 3878 |
+
59876,
|
| 3879 |
+
59877,
|
| 3880 |
+
59911,
|
| 3881 |
+
59928,
|
| 3882 |
+
59979,
|
| 3883 |
+
59999,
|
| 3884 |
+
60016,
|
| 3885 |
+
60038,
|
| 3886 |
+
60083,
|
| 3887 |
+
60131,
|
| 3888 |
+
60156,
|
| 3889 |
+
60170,
|
| 3890 |
+
60171,
|
| 3891 |
+
60198,
|
| 3892 |
+
60207,
|
| 3893 |
+
60235,
|
| 3894 |
+
60240,
|
| 3895 |
+
60266,
|
| 3896 |
+
60288,
|
| 3897 |
+
60338,
|
| 3898 |
+
60344,
|
| 3899 |
+
60460,
|
| 3900 |
+
60488,
|
| 3901 |
+
60525,
|
| 3902 |
+
60543,
|
| 3903 |
+
60559,
|
| 3904 |
+
60581,
|
| 3905 |
+
60586,
|
| 3906 |
+
60596,
|
| 3907 |
+
60604,
|
| 3908 |
+
60627,
|
| 3909 |
+
60628,
|
| 3910 |
+
60671,
|
| 3911 |
+
60672,
|
| 3912 |
+
60674,
|
| 3913 |
+
60681,
|
| 3914 |
+
60704,
|
| 3915 |
+
60715,
|
| 3916 |
+
60740,
|
| 3917 |
+
60757,
|
| 3918 |
+
60765,
|
| 3919 |
+
60803,
|
| 3920 |
+
60808,
|
| 3921 |
+
60856,
|
| 3922 |
+
60864,
|
| 3923 |
+
60872,
|
| 3924 |
+
60873,
|
| 3925 |
+
60880,
|
| 3926 |
+
60895,
|
| 3927 |
+
60907,
|
| 3928 |
+
60971,
|
| 3929 |
+
60985,
|
| 3930 |
+
60994,
|
| 3931 |
+
60998,
|
| 3932 |
+
61002,
|
| 3933 |
+
61004,
|
| 3934 |
+
61021,
|
| 3935 |
+
61022,
|
| 3936 |
+
61032,
|
| 3937 |
+
61064,
|
| 3938 |
+
61081,
|
| 3939 |
+
61083,
|
| 3940 |
+
61118,
|
| 3941 |
+
61163,
|
| 3942 |
+
61166,
|
| 3943 |
+
61173,
|
| 3944 |
+
61200,
|
| 3945 |
+
61210,
|
| 3946 |
+
61211,
|
| 3947 |
+
61241,
|
| 3948 |
+
61250,
|
| 3949 |
+
61261,
|
| 3950 |
+
61265,
|
| 3951 |
+
61277,
|
| 3952 |
+
61281,
|
| 3953 |
+
61290,
|
| 3954 |
+
61301,
|
| 3955 |
+
61318,
|
| 3956 |
+
61320,
|
| 3957 |
+
61338,
|
| 3958 |
+
61340,
|
| 3959 |
+
61355,
|
| 3960 |
+
61381,
|
| 3961 |
+
61413,
|
| 3962 |
+
61414,
|
| 3963 |
+
61439,
|
| 3964 |
+
61513,
|
| 3965 |
+
61519,
|
| 3966 |
+
61525,
|
| 3967 |
+
61528,
|
| 3968 |
+
61556,
|
| 3969 |
+
61557,
|
| 3970 |
+
61563,
|
| 3971 |
+
61580,
|
| 3972 |
+
61581,
|
| 3973 |
+
61586,
|
| 3974 |
+
61617,
|
| 3975 |
+
61629,
|
| 3976 |
+
61633,
|
| 3977 |
+
61657,
|
| 3978 |
+
61680,
|
| 3979 |
+
61710,
|
| 3980 |
+
61765,
|
| 3981 |
+
61772,
|
| 3982 |
+
61780,
|
| 3983 |
+
61804,
|
| 3984 |
+
61827,
|
| 3985 |
+
61843,
|
| 3986 |
+
61861,
|
| 3987 |
+
61870,
|
| 3988 |
+
61910,
|
| 3989 |
+
61968,
|
| 3990 |
+
61969,
|
| 3991 |
+
61983,
|
| 3992 |
+
61993,
|
| 3993 |
+
61996,
|
| 3994 |
+
61997,
|
| 3995 |
+
62005,
|
| 3996 |
+
62021,
|
| 3997 |
+
62033,
|
| 3998 |
+
62036,
|
| 3999 |
+
62067,
|
| 4000 |
+
62099,
|
| 4001 |
+
62100,
|
| 4002 |
+
62108,
|
| 4003 |
+
62117,
|
| 4004 |
+
62123,
|
| 4005 |
+
62143,
|
| 4006 |
+
62191,
|
| 4007 |
+
62198,
|
| 4008 |
+
62217,
|
| 4009 |
+
62218,
|
| 4010 |
+
62256,
|
| 4011 |
+
62274,
|
| 4012 |
+
62296,
|
| 4013 |
+
62302,
|
| 4014 |
+
62307,
|
| 4015 |
+
62318,
|
| 4016 |
+
62319,
|
| 4017 |
+
62338,
|
| 4018 |
+
62344,
|
| 4019 |
+
62349,
|
| 4020 |
+
62382,
|
| 4021 |
+
62403,
|
| 4022 |
+
62416,
|
| 4023 |
+
62422,
|
| 4024 |
+
62447,
|
| 4025 |
+
62479,
|
| 4026 |
+
62480,
|
| 4027 |
+
62497,
|
| 4028 |
+
62512,
|
| 4029 |
+
62537,
|
| 4030 |
+
62540,
|
| 4031 |
+
62544,
|
| 4032 |
+
62555,
|
| 4033 |
+
62564,
|
| 4034 |
+
62591,
|
| 4035 |
+
62601,
|
| 4036 |
+
62610,
|
| 4037 |
+
62618,
|
| 4038 |
+
62631,
|
| 4039 |
+
62674,
|
| 4040 |
+
62697,
|
| 4041 |
+
62705,
|
| 4042 |
+
62720,
|
| 4043 |
+
62732,
|
| 4044 |
+
62740,
|
| 4045 |
+
62770,
|
| 4046 |
+
62789,
|
| 4047 |
+
62799,
|
| 4048 |
+
62817,
|
| 4049 |
+
62823,
|
| 4050 |
+
62863,
|
| 4051 |
+
62877,
|
| 4052 |
+
62879,
|
| 4053 |
+
62887,
|
| 4054 |
+
62896,
|
| 4055 |
+
62918,
|
| 4056 |
+
62965,
|
| 4057 |
+
62982,
|
| 4058 |
+
62986,
|
| 4059 |
+
62991,
|
| 4060 |
+
62994,
|
| 4061 |
+
63039,
|
| 4062 |
+
63040,
|
| 4063 |
+
63046,
|
| 4064 |
+
63106,
|
| 4065 |
+
63119,
|
| 4066 |
+
63156,
|
| 4067 |
+
63159,
|
| 4068 |
+
63173,
|
| 4069 |
+
63191,
|
| 4070 |
+
63194,
|
| 4071 |
+
63211,
|
| 4072 |
+
63219,
|
| 4073 |
+
63230,
|
| 4074 |
+
63242,
|
| 4075 |
+
63276,
|
| 4076 |
+
63295,
|
| 4077 |
+
63296,
|
| 4078 |
+
63324,
|
| 4079 |
+
63348,
|
| 4080 |
+
63351,
|
| 4081 |
+
63371,
|
| 4082 |
+
63372,
|
| 4083 |
+
63393,
|
| 4084 |
+
63400,
|
| 4085 |
+
63407,
|
| 4086 |
+
63453,
|
| 4087 |
+
63458,
|
| 4088 |
+
63477,
|
| 4089 |
+
63481,
|
| 4090 |
+
63485,
|
| 4091 |
+
63538,
|
| 4092 |
+
63545,
|
| 4093 |
+
63553,
|
| 4094 |
+
63554,
|
| 4095 |
+
63624,
|
| 4096 |
+
63632,
|
| 4097 |
+
63636,
|
| 4098 |
+
63660,
|
| 4099 |
+
63698,
|
| 4100 |
+
63720,
|
| 4101 |
+
63740,
|
| 4102 |
+
63741,
|
| 4103 |
+
63749,
|
| 4104 |
+
63761,
|
| 4105 |
+
63779,
|
| 4106 |
+
63802,
|
| 4107 |
+
63853,
|
| 4108 |
+
63861,
|
| 4109 |
+
63887,
|
| 4110 |
+
63926,
|
| 4111 |
+
63941,
|
| 4112 |
+
63963,
|
| 4113 |
+
63966,
|
| 4114 |
+
63985,
|
| 4115 |
+
63993,
|
| 4116 |
+
64044,
|
| 4117 |
+
64054,
|
| 4118 |
+
64058,
|
| 4119 |
+
64059,
|
| 4120 |
+
64071,
|
| 4121 |
+
64077,
|
| 4122 |
+
64092,
|
| 4123 |
+
64113,
|
| 4124 |
+
64114,
|
| 4125 |
+
64137,
|
| 4126 |
+
64139,
|
| 4127 |
+
64166,
|
| 4128 |
+
64175,
|
| 4129 |
+
64190,
|
| 4130 |
+
64212,
|
| 4131 |
+
64217,
|
| 4132 |
+
64247,
|
| 4133 |
+
64253,
|
| 4134 |
+
64266,
|
| 4135 |
+
64277,
|
| 4136 |
+
64322,
|
| 4137 |
+
64329,
|
| 4138 |
+
64359,
|
| 4139 |
+
64360,
|
| 4140 |
+
64388,
|
| 4141 |
+
64395,
|
| 4142 |
+
64399,
|
| 4143 |
+
64417,
|
| 4144 |
+
64419,
|
| 4145 |
+
64433,
|
| 4146 |
+
64434,
|
| 4147 |
+
64457,
|
| 4148 |
+
64497,
|
| 4149 |
+
64501,
|
| 4150 |
+
64518,
|
| 4151 |
+
64520,
|
| 4152 |
+
64540,
|
| 4153 |
+
64545,
|
| 4154 |
+
64568,
|
| 4155 |
+
64589,
|
| 4156 |
+
64600,
|
| 4157 |
+
64607,
|
| 4158 |
+
64627,
|
| 4159 |
+
64631,
|
| 4160 |
+
64632,
|
| 4161 |
+
64660,
|
| 4162 |
+
64772,
|
| 4163 |
+
64783,
|
| 4164 |
+
64805,
|
| 4165 |
+
64822,
|
| 4166 |
+
64827,
|
| 4167 |
+
64881,
|
| 4168 |
+
64884,
|
| 4169 |
+
64888,
|
| 4170 |
+
64893,
|
| 4171 |
+
64897,
|
| 4172 |
+
64976,
|
| 4173 |
+
65011,
|
| 4174 |
+
65016,
|
| 4175 |
+
65018,
|
| 4176 |
+
65019,
|
| 4177 |
+
65033,
|
| 4178 |
+
65037,
|
| 4179 |
+
65038,
|
| 4180 |
+
65052,
|
| 4181 |
+
65069,
|
| 4182 |
+
65079,
|
| 4183 |
+
65097,
|
| 4184 |
+
65131,
|
| 4185 |
+
65138,
|
| 4186 |
+
65159,
|
| 4187 |
+
65173,
|
| 4188 |
+
65185,
|
| 4189 |
+
65197,
|
| 4190 |
+
65225,
|
| 4191 |
+
65259,
|
| 4192 |
+
65260,
|
| 4193 |
+
65261,
|
| 4194 |
+
65264,
|
| 4195 |
+
65267,
|
| 4196 |
+
65287,
|
| 4197 |
+
65291,
|
| 4198 |
+
65297,
|
| 4199 |
+
65300,
|
| 4200 |
+
65305,
|
| 4201 |
+
65317,
|
| 4202 |
+
65360,
|
| 4203 |
+
65383,
|
| 4204 |
+
65387,
|
| 4205 |
+
65405,
|
| 4206 |
+
65416,
|
| 4207 |
+
65434,
|
| 4208 |
+
65440,
|
| 4209 |
+
65451,
|
| 4210 |
+
65456,
|
| 4211 |
+
65473,
|
| 4212 |
+
65490,
|
| 4213 |
+
65506,
|
| 4214 |
+
65519,
|
| 4215 |
+
65543,
|
| 4216 |
+
65553,
|
| 4217 |
+
65570,
|
| 4218 |
+
65579,
|
| 4219 |
+
65589,
|
| 4220 |
+
65611,
|
| 4221 |
+
65612,
|
| 4222 |
+
65622,
|
| 4223 |
+
65664,
|
| 4224 |
+
65667,
|
| 4225 |
+
65668,
|
| 4226 |
+
65672,
|
| 4227 |
+
65678,
|
| 4228 |
+
65683,
|
| 4229 |
+
65699,
|
| 4230 |
+
65722,
|
| 4231 |
+
65727,
|
| 4232 |
+
65737,
|
| 4233 |
+
65745,
|
| 4234 |
+
65759,
|
| 4235 |
+
65763,
|
| 4236 |
+
65766,
|
| 4237 |
+
65777,
|
| 4238 |
+
65787,
|
| 4239 |
+
65792,
|
| 4240 |
+
65810,
|
| 4241 |
+
65815,
|
| 4242 |
+
65830,
|
| 4243 |
+
65831,
|
| 4244 |
+
65846,
|
| 4245 |
+
65850,
|
| 4246 |
+
65861,
|
| 4247 |
+
65870,
|
| 4248 |
+
65871,
|
| 4249 |
+
65877,
|
| 4250 |
+
65887,
|
| 4251 |
+
65901,
|
| 4252 |
+
65912,
|
| 4253 |
+
65974,
|
| 4254 |
+
65980,
|
| 4255 |
+
66014,
|
| 4256 |
+
66092,
|
| 4257 |
+
66112,
|
| 4258 |
+
66118,
|
| 4259 |
+
66120,
|
| 4260 |
+
66153,
|
| 4261 |
+
66163,
|
| 4262 |
+
66203,
|
| 4263 |
+
66233,
|
| 4264 |
+
66261,
|
| 4265 |
+
66285,
|
| 4266 |
+
66297,
|
| 4267 |
+
66323,
|
| 4268 |
+
66371,
|
| 4269 |
+
66376,
|
| 4270 |
+
66377,
|
| 4271 |
+
66401,
|
| 4272 |
+
66405,
|
| 4273 |
+
66426,
|
| 4274 |
+
66436,
|
| 4275 |
+
66444,
|
| 4276 |
+
66474,
|
| 4277 |
+
66475,
|
| 4278 |
+
66498,
|
| 4279 |
+
66506,
|
| 4280 |
+
66519,
|
| 4281 |
+
66521,
|
| 4282 |
+
66535,
|
| 4283 |
+
66595,
|
| 4284 |
+
66600,
|
| 4285 |
+
66606,
|
| 4286 |
+
66627,
|
| 4287 |
+
66629,
|
| 4288 |
+
66635,
|
| 4289 |
+
66647,
|
| 4290 |
+
66656,
|
| 4291 |
+
66686,
|
| 4292 |
+
66689,
|
| 4293 |
+
66731,
|
| 4294 |
+
66778,
|
| 4295 |
+
66781,
|
| 4296 |
+
66783,
|
| 4297 |
+
66786,
|
| 4298 |
+
66816,
|
| 4299 |
+
66824,
|
| 4300 |
+
66834,
|
| 4301 |
+
66844,
|
| 4302 |
+
66853,
|
| 4303 |
+
66870,
|
| 4304 |
+
66882,
|
| 4305 |
+
66905,
|
| 4306 |
+
66910,
|
| 4307 |
+
66929,
|
| 4308 |
+
66941,
|
| 4309 |
+
66960,
|
| 4310 |
+
66995,
|
| 4311 |
+
67018,
|
| 4312 |
+
67022,
|
| 4313 |
+
67036,
|
| 4314 |
+
67054,
|
| 4315 |
+
67066,
|
| 4316 |
+
67073,
|
| 4317 |
+
67083,
|
| 4318 |
+
67097,
|
| 4319 |
+
67108,
|
| 4320 |
+
67150,
|
| 4321 |
+
67172,
|
| 4322 |
+
67183,
|
| 4323 |
+
67219,
|
| 4324 |
+
67225,
|
| 4325 |
+
67240,
|
| 4326 |
+
67293,
|
| 4327 |
+
67314,
|
| 4328 |
+
67334,
|
| 4329 |
+
67372,
|
| 4330 |
+
67392,
|
| 4331 |
+
67393,
|
| 4332 |
+
67411,
|
| 4333 |
+
67432,
|
| 4334 |
+
67436,
|
| 4335 |
+
67451,
|
| 4336 |
+
67455,
|
| 4337 |
+
67471,
|
| 4338 |
+
67476,
|
| 4339 |
+
67506,
|
| 4340 |
+
67564,
|
| 4341 |
+
67591,
|
| 4342 |
+
67615,
|
| 4343 |
+
67618,
|
| 4344 |
+
67625,
|
| 4345 |
+
67638,
|
| 4346 |
+
67650,
|
| 4347 |
+
67664,
|
| 4348 |
+
67680,
|
| 4349 |
+
67701,
|
| 4350 |
+
67708,
|
| 4351 |
+
67709,
|
| 4352 |
+
67750,
|
| 4353 |
+
67758,
|
| 4354 |
+
67773,
|
| 4355 |
+
67774,
|
| 4356 |
+
67796,
|
| 4357 |
+
67807,
|
| 4358 |
+
67811,
|
| 4359 |
+
67838,
|
| 4360 |
+
67848,
|
| 4361 |
+
67864,
|
| 4362 |
+
67886,
|
| 4363 |
+
67895,
|
| 4364 |
+
67914,
|
| 4365 |
+
67922,
|
| 4366 |
+
67924,
|
| 4367 |
+
67938,
|
| 4368 |
+
67940,
|
| 4369 |
+
67977,
|
| 4370 |
+
68006,
|
| 4371 |
+
68013,
|
| 4372 |
+
68046,
|
| 4373 |
+
68048,
|
| 4374 |
+
68081,
|
| 4375 |
+
68101,
|
| 4376 |
+
68132,
|
| 4377 |
+
68133,
|
| 4378 |
+
68165,
|
| 4379 |
+
68166,
|
| 4380 |
+
68169,
|
| 4381 |
+
68172,
|
| 4382 |
+
68174,
|
| 4383 |
+
68187,
|
| 4384 |
+
68191,
|
| 4385 |
+
68221,
|
| 4386 |
+
68241,
|
| 4387 |
+
68250,
|
| 4388 |
+
68258,
|
| 4389 |
+
68271,
|
| 4390 |
+
68294,
|
| 4391 |
+
68298,
|
| 4392 |
+
68300,
|
| 4393 |
+
68303,
|
| 4394 |
+
68327,
|
| 4395 |
+
68329,
|
| 4396 |
+
68346,
|
| 4397 |
+
68379,
|
| 4398 |
+
68405,
|
| 4399 |
+
68417,
|
| 4400 |
+
68420,
|
| 4401 |
+
68433,
|
| 4402 |
+
68434,
|
| 4403 |
+
68454,
|
| 4404 |
+
68464,
|
| 4405 |
+
68485,
|
| 4406 |
+
68492,
|
| 4407 |
+
68502,
|
| 4408 |
+
68547,
|
| 4409 |
+
68562,
|
| 4410 |
+
68590,
|
| 4411 |
+
68597,
|
| 4412 |
+
68601,
|
| 4413 |
+
68603,
|
| 4414 |
+
68612,
|
| 4415 |
+
68615,
|
| 4416 |
+
68638,
|
| 4417 |
+
68650,
|
| 4418 |
+
68653,
|
| 4419 |
+
68739,
|
| 4420 |
+
68746,
|
| 4421 |
+
68751,
|
| 4422 |
+
68752,
|
| 4423 |
+
68760,
|
| 4424 |
+
68762,
|
| 4425 |
+
68776,
|
| 4426 |
+
68780,
|
| 4427 |
+
68786,
|
| 4428 |
+
68804,
|
| 4429 |
+
68806,
|
| 4430 |
+
68827,
|
| 4431 |
+
68843,
|
| 4432 |
+
68888,
|
| 4433 |
+
68890,
|
| 4434 |
+
68901,
|
| 4435 |
+
68907,
|
| 4436 |
+
68908,
|
| 4437 |
+
68915,
|
| 4438 |
+
68916,
|
| 4439 |
+
68920,
|
| 4440 |
+
68941,
|
| 4441 |
+
69016,
|
| 4442 |
+
69033,
|
| 4443 |
+
69043,
|
| 4444 |
+
69068,
|
| 4445 |
+
69099,
|
| 4446 |
+
69127,
|
| 4447 |
+
69161,
|
| 4448 |
+
69163,
|
| 4449 |
+
69165,
|
| 4450 |
+
69169,
|
| 4451 |
+
69178,
|
| 4452 |
+
69192,
|
| 4453 |
+
69196,
|
| 4454 |
+
69210,
|
| 4455 |
+
69222,
|
| 4456 |
+
69227,
|
| 4457 |
+
69237,
|
| 4458 |
+
69248,
|
| 4459 |
+
69266,
|
| 4460 |
+
69272,
|
| 4461 |
+
69276,
|
| 4462 |
+
69366,
|
| 4463 |
+
69382,
|
| 4464 |
+
69383,
|
| 4465 |
+
69441,
|
| 4466 |
+
69457,
|
| 4467 |
+
69493,
|
| 4468 |
+
69494,
|
| 4469 |
+
69515,
|
| 4470 |
+
69540,
|
| 4471 |
+
69550,
|
| 4472 |
+
69567,
|
| 4473 |
+
69570,
|
| 4474 |
+
69597,
|
| 4475 |
+
69646,
|
| 4476 |
+
69687,
|
| 4477 |
+
69757,
|
| 4478 |
+
69761,
|
| 4479 |
+
69768,
|
| 4480 |
+
69782,
|
| 4481 |
+
69792,
|
| 4482 |
+
69826,
|
| 4483 |
+
69877,
|
| 4484 |
+
69903,
|
| 4485 |
+
69909,
|
| 4486 |
+
69911,
|
| 4487 |
+
69937,
|
| 4488 |
+
69938,
|
| 4489 |
+
69943,
|
| 4490 |
+
69950,
|
| 4491 |
+
69963,
|
| 4492 |
+
70031,
|
| 4493 |
+
70044,
|
| 4494 |
+
70053,
|
| 4495 |
+
70073,
|
| 4496 |
+
70079,
|
| 4497 |
+
70113,
|
| 4498 |
+
70119,
|
| 4499 |
+
70130,
|
| 4500 |
+
70143,
|
| 4501 |
+
70170,
|
| 4502 |
+
70177,
|
| 4503 |
+
70179,
|
| 4504 |
+
70180,
|
| 4505 |
+
70191,
|
| 4506 |
+
70193,
|
| 4507 |
+
70234,
|
| 4508 |
+
70235,
|
| 4509 |
+
70247,
|
| 4510 |
+
70249,
|
| 4511 |
+
70269,
|
| 4512 |
+
70285,
|
| 4513 |
+
70297,
|
| 4514 |
+
70305,
|
| 4515 |
+
70329,
|
| 4516 |
+
70339,
|
| 4517 |
+
70340,
|
| 4518 |
+
70342,
|
| 4519 |
+
70377,
|
| 4520 |
+
70457,
|
| 4521 |
+
70463,
|
| 4522 |
+
70467,
|
| 4523 |
+
70491,
|
| 4524 |
+
70542,
|
| 4525 |
+
70549,
|
| 4526 |
+
70557,
|
| 4527 |
+
70571,
|
| 4528 |
+
70576,
|
| 4529 |
+
70585,
|
| 4530 |
+
70597,
|
| 4531 |
+
70606,
|
| 4532 |
+
70634,
|
| 4533 |
+
70639,
|
| 4534 |
+
70641,
|
| 4535 |
+
70652,
|
| 4536 |
+
70674,
|
| 4537 |
+
70676,
|
| 4538 |
+
70685,
|
| 4539 |
+
70701,
|
| 4540 |
+
70731,
|
| 4541 |
+
70755,
|
| 4542 |
+
70759,
|
| 4543 |
+
70787,
|
| 4544 |
+
70818,
|
| 4545 |
+
70828,
|
| 4546 |
+
70844,
|
| 4547 |
+
70846,
|
| 4548 |
+
70851,
|
| 4549 |
+
70873,
|
| 4550 |
+
70876,
|
| 4551 |
+
70878,
|
| 4552 |
+
70881,
|
| 4553 |
+
70918,
|
| 4554 |
+
70931,
|
| 4555 |
+
70955,
|
| 4556 |
+
70956,
|
| 4557 |
+
70963,
|
| 4558 |
+
70975,
|
| 4559 |
+
70988,
|
| 4560 |
+
71013,
|
| 4561 |
+
71035,
|
| 4562 |
+
71064,
|
| 4563 |
+
71077,
|
| 4564 |
+
71100,
|
| 4565 |
+
71113,
|
| 4566 |
+
71119,
|
| 4567 |
+
71146,
|
| 4568 |
+
71153,
|
| 4569 |
+
71163,
|
| 4570 |
+
71167,
|
| 4571 |
+
71189,
|
| 4572 |
+
71192,
|
| 4573 |
+
71210,
|
| 4574 |
+
71220,
|
| 4575 |
+
71230,
|
| 4576 |
+
71239,
|
| 4577 |
+
71248,
|
| 4578 |
+
71265,
|
| 4579 |
+
71306,
|
| 4580 |
+
71362,
|
| 4581 |
+
71373,
|
| 4582 |
+
71379,
|
| 4583 |
+
71389,
|
| 4584 |
+
71412,
|
| 4585 |
+
71430,
|
| 4586 |
+
71443,
|
| 4587 |
+
71469,
|
| 4588 |
+
71471,
|
| 4589 |
+
71472,
|
| 4590 |
+
71473,
|
| 4591 |
+
71476,
|
| 4592 |
+
71481,
|
| 4593 |
+
71496,
|
| 4594 |
+
71515,
|
| 4595 |
+
71522,
|
| 4596 |
+
71524,
|
| 4597 |
+
71537,
|
| 4598 |
+
71544,
|
| 4599 |
+
71566,
|
| 4600 |
+
71568,
|
| 4601 |
+
71588,
|
| 4602 |
+
71610,
|
| 4603 |
+
71612,
|
| 4604 |
+
71630,
|
| 4605 |
+
71634,
|
| 4606 |
+
71646,
|
| 4607 |
+
71649,
|
| 4608 |
+
71650,
|
| 4609 |
+
71664,
|
| 4610 |
+
71698,
|
| 4611 |
+
71714,
|
| 4612 |
+
71721,
|
| 4613 |
+
71779,
|
| 4614 |
+
71812,
|
| 4615 |
+
71820,
|
| 4616 |
+
71847,
|
| 4617 |
+
71868,
|
| 4618 |
+
71880,
|
| 4619 |
+
71928,
|
| 4620 |
+
71930,
|
| 4621 |
+
71933,
|
| 4622 |
+
71943,
|
| 4623 |
+
71956,
|
| 4624 |
+
71970,
|
| 4625 |
+
72002,
|
| 4626 |
+
72009,
|
| 4627 |
+
72011,
|
| 4628 |
+
72016,
|
| 4629 |
+
72021,
|
| 4630 |
+
72025,
|
| 4631 |
+
72036,
|
| 4632 |
+
72080,
|
| 4633 |
+
72086,
|
| 4634 |
+
72103,
|
| 4635 |
+
72208,
|
| 4636 |
+
72219,
|
| 4637 |
+
72229,
|
| 4638 |
+
72253,
|
| 4639 |
+
72280,
|
| 4640 |
+
72333,
|
| 4641 |
+
72341,
|
| 4642 |
+
72344,
|
| 4643 |
+
72353,
|
| 4644 |
+
72383,
|
| 4645 |
+
72389,
|
| 4646 |
+
72430,
|
| 4647 |
+
72446,
|
| 4648 |
+
72458,
|
| 4649 |
+
72473,
|
| 4650 |
+
72476,
|
| 4651 |
+
72496,
|
| 4652 |
+
72497,
|
| 4653 |
+
72504,
|
| 4654 |
+
72507,
|
| 4655 |
+
72509,
|
| 4656 |
+
72534,
|
| 4657 |
+
72573,
|
| 4658 |
+
72589,
|
| 4659 |
+
72615,
|
| 4660 |
+
72636,
|
| 4661 |
+
72646,
|
| 4662 |
+
72648,
|
| 4663 |
+
72712,
|
| 4664 |
+
72727,
|
| 4665 |
+
72745,
|
| 4666 |
+
72764,
|
| 4667 |
+
72782,
|
| 4668 |
+
72785,
|
| 4669 |
+
72791,
|
| 4670 |
+
72793,
|
| 4671 |
+
72795,
|
| 4672 |
+
72796,
|
| 4673 |
+
72821,
|
| 4674 |
+
72825,
|
| 4675 |
+
72839,
|
| 4676 |
+
72855,
|
| 4677 |
+
72877,
|
| 4678 |
+
72882,
|
| 4679 |
+
72903,
|
| 4680 |
+
72905,
|
| 4681 |
+
72916,
|
| 4682 |
+
72929,
|
| 4683 |
+
72931,
|
| 4684 |
+
72946,
|
| 4685 |
+
73002,
|
| 4686 |
+
73024,
|
| 4687 |
+
73031,
|
| 4688 |
+
73066,
|
| 4689 |
+
73104,
|
| 4690 |
+
73131,
|
| 4691 |
+
73133,
|
| 4692 |
+
73140,
|
| 4693 |
+
73147,
|
| 4694 |
+
73162,
|
| 4695 |
+
73173,
|
| 4696 |
+
73196,
|
| 4697 |
+
73209,
|
| 4698 |
+
73242,
|
| 4699 |
+
73259,
|
| 4700 |
+
73269,
|
| 4701 |
+
73303,
|
| 4702 |
+
73330,
|
| 4703 |
+
73357,
|
| 4704 |
+
73363,
|
| 4705 |
+
73375,
|
| 4706 |
+
73392,
|
| 4707 |
+
73407,
|
| 4708 |
+
73416,
|
| 4709 |
+
73427,
|
| 4710 |
+
73443,
|
| 4711 |
+
73462,
|
| 4712 |
+
73472,
|
| 4713 |
+
73480,
|
| 4714 |
+
73510,
|
| 4715 |
+
73524,
|
| 4716 |
+
73530,
|
| 4717 |
+
73534,
|
| 4718 |
+
73554,
|
| 4719 |
+
73582,
|
| 4720 |
+
73592,
|
| 4721 |
+
73593,
|
| 4722 |
+
73611,
|
| 4723 |
+
73650,
|
| 4724 |
+
73663,
|
| 4725 |
+
73691,
|
| 4726 |
+
73699,
|
| 4727 |
+
73727,
|
| 4728 |
+
73744,
|
| 4729 |
+
73745,
|
| 4730 |
+
73748,
|
| 4731 |
+
73751,
|
| 4732 |
+
73798,
|
| 4733 |
+
73822,
|
| 4734 |
+
73834,
|
| 4735 |
+
73845,
|
| 4736 |
+
73863,
|
| 4737 |
+
73867,
|
| 4738 |
+
73900,
|
| 4739 |
+
73903,
|
| 4740 |
+
73925,
|
| 4741 |
+
73927,
|
| 4742 |
+
73952,
|
| 4743 |
+
73953,
|
| 4744 |
+
73963,
|
| 4745 |
+
73964,
|
| 4746 |
+
73971,
|
| 4747 |
+
73983,
|
| 4748 |
+
74029,
|
| 4749 |
+
74034,
|
| 4750 |
+
74071,
|
| 4751 |
+
74083,
|
| 4752 |
+
74092,
|
| 4753 |
+
74123,
|
| 4754 |
+
74128,
|
| 4755 |
+
74138,
|
| 4756 |
+
74165,
|
| 4757 |
+
74186,
|
| 4758 |
+
74196,
|
| 4759 |
+
74199,
|
| 4760 |
+
74203,
|
| 4761 |
+
74209,
|
| 4762 |
+
74228,
|
| 4763 |
+
74276,
|
| 4764 |
+
74282,
|
| 4765 |
+
74285,
|
| 4766 |
+
74312,
|
| 4767 |
+
74324,
|
| 4768 |
+
74326,
|
| 4769 |
+
74342,
|
| 4770 |
+
74361,
|
| 4771 |
+
74376,
|
| 4772 |
+
74384,
|
| 4773 |
+
74385,
|
| 4774 |
+
74446,
|
| 4775 |
+
74491,
|
| 4776 |
+
74494,
|
| 4777 |
+
74499,
|
| 4778 |
+
74525,
|
| 4779 |
+
74526,
|
| 4780 |
+
74545,
|
| 4781 |
+
74577,
|
| 4782 |
+
74588,
|
| 4783 |
+
74637,
|
| 4784 |
+
74678,
|
| 4785 |
+
74687,
|
| 4786 |
+
74699,
|
| 4787 |
+
74706,
|
| 4788 |
+
74727,
|
| 4789 |
+
74734,
|
| 4790 |
+
74740,
|
| 4791 |
+
74782,
|
| 4792 |
+
74792,
|
| 4793 |
+
74794,
|
| 4794 |
+
74824,
|
| 4795 |
+
74834,
|
| 4796 |
+
74843,
|
| 4797 |
+
74866,
|
| 4798 |
+
74869,
|
| 4799 |
+
74884,
|
| 4800 |
+
74897,
|
| 4801 |
+
75014,
|
| 4802 |
+
75026,
|
| 4803 |
+
75033,
|
| 4804 |
+
75042,
|
| 4805 |
+
75048,
|
| 4806 |
+
75053,
|
| 4807 |
+
75089,
|
| 4808 |
+
75097,
|
| 4809 |
+
75107,
|
| 4810 |
+
75132,
|
| 4811 |
+
75142,
|
| 4812 |
+
75145,
|
| 4813 |
+
75156,
|
| 4814 |
+
75191,
|
| 4815 |
+
75192,
|
| 4816 |
+
75218,
|
| 4817 |
+
75228,
|
| 4818 |
+
75241,
|
| 4819 |
+
75244,
|
| 4820 |
+
75246,
|
| 4821 |
+
75258,
|
| 4822 |
+
75276,
|
| 4823 |
+
75279,
|
| 4824 |
+
75282,
|
| 4825 |
+
75295,
|
| 4826 |
+
75346,
|
| 4827 |
+
75352,
|
| 4828 |
+
75360,
|
| 4829 |
+
75375,
|
| 4830 |
+
75387,
|
| 4831 |
+
75396,
|
| 4832 |
+
75453,
|
| 4833 |
+
75456,
|
| 4834 |
+
75467,
|
| 4835 |
+
75487,
|
| 4836 |
+
75499,
|
| 4837 |
+
75531,
|
| 4838 |
+
75558,
|
| 4839 |
+
75583,
|
| 4840 |
+
75598,
|
| 4841 |
+
75600,
|
| 4842 |
+
75616,
|
| 4843 |
+
75624,
|
| 4844 |
+
75640,
|
| 4845 |
+
75665,
|
| 4846 |
+
75671,
|
| 4847 |
+
75679,
|
| 4848 |
+
75693,
|
| 4849 |
+
75694,
|
| 4850 |
+
75699,
|
| 4851 |
+
75707,
|
| 4852 |
+
75719,
|
| 4853 |
+
75723,
|
| 4854 |
+
75743,
|
| 4855 |
+
75781,
|
| 4856 |
+
75800,
|
| 4857 |
+
75846,
|
| 4858 |
+
75862,
|
| 4859 |
+
75869,
|
| 4860 |
+
75883,
|
| 4861 |
+
75884,
|
| 4862 |
+
75890,
|
| 4863 |
+
75908,
|
| 4864 |
+
75910,
|
| 4865 |
+
75912,
|
| 4866 |
+
75947,
|
| 4867 |
+
75960,
|
| 4868 |
+
75962,
|
| 4869 |
+
75976,
|
| 4870 |
+
76014,
|
| 4871 |
+
76058,
|
| 4872 |
+
76080,
|
| 4873 |
+
76101,
|
| 4874 |
+
76122,
|
| 4875 |
+
76125,
|
| 4876 |
+
76172,
|
| 4877 |
+
76199,
|
| 4878 |
+
76206,
|
| 4879 |
+
76216,
|
| 4880 |
+
76222,
|
| 4881 |
+
76263,
|
| 4882 |
+
76270,
|
| 4883 |
+
76299,
|
| 4884 |
+
76300,
|
| 4885 |
+
76325,
|
| 4886 |
+
76327,
|
| 4887 |
+
76350,
|
| 4888 |
+
76352,
|
| 4889 |
+
76379,
|
| 4890 |
+
76423,
|
| 4891 |
+
76432,
|
| 4892 |
+
76440,
|
| 4893 |
+
76459,
|
| 4894 |
+
76496,
|
| 4895 |
+
76497,
|
| 4896 |
+
76540,
|
| 4897 |
+
76564,
|
| 4898 |
+
76590,
|
| 4899 |
+
76591,
|
| 4900 |
+
76606,
|
| 4901 |
+
76627,
|
| 4902 |
+
76643,
|
| 4903 |
+
76659,
|
| 4904 |
+
76669,
|
| 4905 |
+
76670,
|
| 4906 |
+
76675,
|
| 4907 |
+
76689,
|
| 4908 |
+
76690,
|
| 4909 |
+
76694,
|
| 4910 |
+
76723,
|
| 4911 |
+
76737,
|
| 4912 |
+
76741,
|
| 4913 |
+
76768,
|
| 4914 |
+
76777,
|
| 4915 |
+
76788,
|
| 4916 |
+
76840,
|
| 4917 |
+
76847,
|
| 4918 |
+
76850,
|
| 4919 |
+
76852,
|
| 4920 |
+
76860,
|
| 4921 |
+
76878,
|
| 4922 |
+
76888,
|
| 4923 |
+
76895,
|
| 4924 |
+
76910,
|
| 4925 |
+
76918,
|
| 4926 |
+
76919,
|
| 4927 |
+
76941,
|
| 4928 |
+
76952,
|
| 4929 |
+
76977,
|
| 4930 |
+
76986,
|
| 4931 |
+
77007,
|
| 4932 |
+
77009,
|
| 4933 |
+
77047,
|
| 4934 |
+
77051,
|
| 4935 |
+
77057,
|
| 4936 |
+
77127,
|
| 4937 |
+
77130,
|
| 4938 |
+
77136,
|
| 4939 |
+
77137,
|
| 4940 |
+
77156,
|
| 4941 |
+
77168,
|
| 4942 |
+
77204,
|
| 4943 |
+
77219,
|
| 4944 |
+
77305,
|
| 4945 |
+
77311,
|
| 4946 |
+
77314,
|
| 4947 |
+
77344,
|
| 4948 |
+
77358,
|
| 4949 |
+
77376,
|
| 4950 |
+
77383,
|
| 4951 |
+
77390,
|
| 4952 |
+
77407,
|
| 4953 |
+
77410,
|
| 4954 |
+
77417,
|
| 4955 |
+
77423,
|
| 4956 |
+
77434,
|
| 4957 |
+
77479,
|
| 4958 |
+
77496,
|
| 4959 |
+
77503,
|
| 4960 |
+
77515,
|
| 4961 |
+
77535,
|
| 4962 |
+
77544,
|
| 4963 |
+
77561,
|
| 4964 |
+
77565,
|
| 4965 |
+
77596,
|
| 4966 |
+
77620,
|
| 4967 |
+
77623,
|
| 4968 |
+
77684,
|
| 4969 |
+
77706,
|
| 4970 |
+
77721,
|
| 4971 |
+
77754,
|
| 4972 |
+
77767,
|
| 4973 |
+
77787,
|
| 4974 |
+
77804,
|
| 4975 |
+
77828,
|
| 4976 |
+
77833,
|
| 4977 |
+
77862,
|
| 4978 |
+
77863,
|
| 4979 |
+
77872,
|
| 4980 |
+
77908,
|
| 4981 |
+
77927,
|
| 4982 |
+
77933,
|
| 4983 |
+
77943,
|
| 4984 |
+
77955,
|
| 4985 |
+
77962,
|
| 4986 |
+
77978,
|
| 4987 |
+
77980,
|
| 4988 |
+
77993,
|
| 4989 |
+
78003,
|
| 4990 |
+
78009,
|
| 4991 |
+
78016,
|
| 4992 |
+
78039,
|
| 4993 |
+
78042,
|
| 4994 |
+
78082,
|
| 4995 |
+
78105,
|
| 4996 |
+
78108,
|
| 4997 |
+
78110,
|
| 4998 |
+
78126,
|
| 4999 |
+
78135,
|
| 5000 |
+
78137,
|
| 5001 |
+
78182,
|
| 5002 |
+
78239,
|
| 5003 |
+
78241,
|
| 5004 |
+
78254,
|
| 5005 |
+
78264,
|
| 5006 |
+
78286,
|
| 5007 |
+
78300,
|
| 5008 |
+
78314,
|
| 5009 |
+
78336,
|
| 5010 |
+
78337,
|
| 5011 |
+
78346,
|
| 5012 |
+
78355,
|
| 5013 |
+
78378,
|
| 5014 |
+
78384,
|
| 5015 |
+
78401,
|
| 5016 |
+
78402,
|
| 5017 |
+
78435,
|
| 5018 |
+
78458,
|
| 5019 |
+
78515,
|
| 5020 |
+
78552,
|
| 5021 |
+
78602,
|
| 5022 |
+
78608,
|
| 5023 |
+
78637,
|
| 5024 |
+
78642,
|
| 5025 |
+
78657,
|
| 5026 |
+
78664,
|
| 5027 |
+
78672,
|
| 5028 |
+
78757,
|
| 5029 |
+
78772,
|
| 5030 |
+
78774,
|
| 5031 |
+
78777,
|
| 5032 |
+
78778,
|
| 5033 |
+
78837,
|
| 5034 |
+
78838,
|
| 5035 |
+
78878,
|
| 5036 |
+
78900,
|
| 5037 |
+
78903,
|
| 5038 |
+
78910,
|
| 5039 |
+
78916,
|
| 5040 |
+
78921,
|
| 5041 |
+
78923,
|
| 5042 |
+
78928,
|
| 5043 |
+
78929,
|
| 5044 |
+
78938,
|
| 5045 |
+
78955,
|
| 5046 |
+
78971,
|
| 5047 |
+
78988,
|
| 5048 |
+
79000,
|
| 5049 |
+
79018,
|
| 5050 |
+
79076,
|
| 5051 |
+
79083,
|
| 5052 |
+
79089,
|
| 5053 |
+
79091,
|
| 5054 |
+
79098,
|
| 5055 |
+
79133,
|
| 5056 |
+
79141,
|
| 5057 |
+
79142,
|
| 5058 |
+
79146,
|
| 5059 |
+
79189,
|
| 5060 |
+
79201,
|
| 5061 |
+
79203,
|
| 5062 |
+
79207,
|
| 5063 |
+
79208,
|
| 5064 |
+
79218,
|
| 5065 |
+
79226,
|
| 5066 |
+
79245,
|
| 5067 |
+
79255,
|
| 5068 |
+
79268,
|
| 5069 |
+
79279,
|
| 5070 |
+
79295,
|
| 5071 |
+
79302,
|
| 5072 |
+
79304,
|
| 5073 |
+
79318,
|
| 5074 |
+
79319,
|
| 5075 |
+
79321,
|
| 5076 |
+
79322,
|
| 5077 |
+
79325,
|
| 5078 |
+
79326,
|
| 5079 |
+
79342,
|
| 5080 |
+
79352,
|
| 5081 |
+
79364,
|
| 5082 |
+
79371,
|
| 5083 |
+
79375,
|
| 5084 |
+
79389,
|
| 5085 |
+
79390,
|
| 5086 |
+
79394,
|
| 5087 |
+
79403,
|
| 5088 |
+
79413,
|
| 5089 |
+
79427,
|
| 5090 |
+
79448,
|
| 5091 |
+
79453,
|
| 5092 |
+
79480,
|
| 5093 |
+
79483,
|
| 5094 |
+
79515,
|
| 5095 |
+
79531,
|
| 5096 |
+
79535,
|
| 5097 |
+
79553,
|
| 5098 |
+
79558,
|
| 5099 |
+
79567,
|
| 5100 |
+
79583,
|
| 5101 |
+
79590,
|
| 5102 |
+
79597,
|
| 5103 |
+
79621,
|
| 5104 |
+
79625,
|
| 5105 |
+
79654,
|
| 5106 |
+
79714,
|
| 5107 |
+
79739,
|
| 5108 |
+
79775,
|
| 5109 |
+
79787,
|
| 5110 |
+
79795,
|
| 5111 |
+
79846,
|
| 5112 |
+
79858,
|
| 5113 |
+
79865,
|
| 5114 |
+
79868,
|
| 5115 |
+
79878,
|
| 5116 |
+
79879,
|
| 5117 |
+
79883,
|
| 5118 |
+
79888,
|
| 5119 |
+
79895,
|
| 5120 |
+
79910,
|
| 5121 |
+
79920,
|
| 5122 |
+
79931,
|
| 5123 |
+
79939,
|
| 5124 |
+
79949,
|
| 5125 |
+
79965,
|
| 5126 |
+
79993,
|
| 5127 |
+
80007,
|
| 5128 |
+
80078,
|
| 5129 |
+
80080,
|
| 5130 |
+
80090,
|
| 5131 |
+
80142,
|
| 5132 |
+
80154,
|
| 5133 |
+
80156,
|
| 5134 |
+
80169,
|
| 5135 |
+
80171,
|
| 5136 |
+
80178,
|
| 5137 |
+
80181,
|
| 5138 |
+
80212,
|
| 5139 |
+
80220,
|
| 5140 |
+
80244,
|
| 5141 |
+
80281,
|
| 5142 |
+
80306,
|
| 5143 |
+
80316,
|
| 5144 |
+
80330,
|
| 5145 |
+
80345,
|
| 5146 |
+
80357,
|
| 5147 |
+
80361,
|
| 5148 |
+
80368,
|
| 5149 |
+
80391,
|
| 5150 |
+
80394,
|
| 5151 |
+
80403,
|
| 5152 |
+
80410,
|
| 5153 |
+
80434,
|
| 5154 |
+
80436,
|
| 5155 |
+
80445,
|
| 5156 |
+
80455,
|
| 5157 |
+
80488,
|
| 5158 |
+
80505,
|
| 5159 |
+
80540,
|
| 5160 |
+
80550,
|
| 5161 |
+
80592,
|
| 5162 |
+
80608,
|
| 5163 |
+
80613,
|
| 5164 |
+
80634,
|
| 5165 |
+
80640,
|
| 5166 |
+
80644,
|
| 5167 |
+
80653,
|
| 5168 |
+
80687,
|
| 5169 |
+
80698,
|
| 5170 |
+
80702,
|
| 5171 |
+
80719,
|
| 5172 |
+
80741,
|
| 5173 |
+
80749,
|
| 5174 |
+
80803,
|
| 5175 |
+
80818,
|
| 5176 |
+
80821,
|
| 5177 |
+
80823,
|
| 5178 |
+
80874,
|
| 5179 |
+
80961,
|
| 5180 |
+
80984,
|
| 5181 |
+
81011,
|
| 5182 |
+
81012,
|
| 5183 |
+
81014,
|
| 5184 |
+
81036,
|
| 5185 |
+
81042,
|
| 5186 |
+
81048,
|
| 5187 |
+
81057,
|
| 5188 |
+
81065,
|
| 5189 |
+
81081,
|
| 5190 |
+
81091,
|
| 5191 |
+
81131,
|
| 5192 |
+
81141,
|
| 5193 |
+
81142,
|
| 5194 |
+
81161,
|
| 5195 |
+
81174,
|
| 5196 |
+
81243,
|
| 5197 |
+
81246,
|
| 5198 |
+
81250,
|
| 5199 |
+
81254,
|
| 5200 |
+
81281,
|
| 5201 |
+
81285,
|
| 5202 |
+
81349,
|
| 5203 |
+
81392,
|
| 5204 |
+
81394,
|
| 5205 |
+
81436,
|
| 5206 |
+
81439,
|
| 5207 |
+
81452,
|
| 5208 |
+
81483,
|
| 5209 |
+
81499,
|
| 5210 |
+
81511,
|
| 5211 |
+
81554,
|
| 5212 |
+
81556,
|
| 5213 |
+
81572,
|
| 5214 |
+
81580,
|
| 5215 |
+
81599,
|
| 5216 |
+
81608,
|
| 5217 |
+
81609,
|
| 5218 |
+
81618,
|
| 5219 |
+
81645,
|
| 5220 |
+
81654,
|
| 5221 |
+
81661,
|
| 5222 |
+
81662,
|
| 5223 |
+
81723,
|
| 5224 |
+
81740,
|
| 5225 |
+
81767,
|
| 5226 |
+
81779,
|
| 5227 |
+
81802,
|
| 5228 |
+
81840,
|
| 5229 |
+
81866,
|
| 5230 |
+
81868,
|
| 5231 |
+
81892,
|
| 5232 |
+
81942,
|
| 5233 |
+
81949,
|
| 5234 |
+
81956,
|
| 5235 |
+
81962,
|
| 5236 |
+
81970,
|
| 5237 |
+
82003,
|
| 5238 |
+
82006,
|
| 5239 |
+
82024,
|
| 5240 |
+
82034,
|
| 5241 |
+
82042,
|
| 5242 |
+
82049,
|
| 5243 |
+
82074,
|
| 5244 |
+
82120,
|
| 5245 |
+
82172,
|
| 5246 |
+
82206,
|
| 5247 |
+
82208,
|
| 5248 |
+
82216,
|
| 5249 |
+
82266,
|
| 5250 |
+
82273,
|
| 5251 |
+
82294,
|
| 5252 |
+
82361,
|
| 5253 |
+
82368,
|
| 5254 |
+
82379,
|
| 5255 |
+
82382,
|
| 5256 |
+
82432,
|
| 5257 |
+
82446,
|
| 5258 |
+
82466,
|
| 5259 |
+
82475,
|
| 5260 |
+
82484,
|
| 5261 |
+
82501,
|
| 5262 |
+
82506,
|
| 5263 |
+
82511,
|
| 5264 |
+
82530,
|
| 5265 |
+
82596,
|
| 5266 |
+
82598,
|
| 5267 |
+
82606,
|
| 5268 |
+
82630,
|
| 5269 |
+
82669,
|
| 5270 |
+
82671,
|
| 5271 |
+
82672,
|
| 5272 |
+
82693,
|
| 5273 |
+
82706,
|
| 5274 |
+
82712,
|
| 5275 |
+
82776,
|
| 5276 |
+
82777,
|
| 5277 |
+
82794,
|
| 5278 |
+
82798,
|
| 5279 |
+
82815,
|
| 5280 |
+
82819,
|
| 5281 |
+
82822,
|
| 5282 |
+
82848,
|
| 5283 |
+
82866,
|
| 5284 |
+
82868,
|
| 5285 |
+
82888,
|
| 5286 |
+
82893,
|
| 5287 |
+
82912,
|
| 5288 |
+
82921,
|
| 5289 |
+
82923,
|
| 5290 |
+
82934,
|
| 5291 |
+
82961,
|
| 5292 |
+
82971,
|
| 5293 |
+
82979,
|
| 5294 |
+
82994,
|
| 5295 |
+
82997,
|
| 5296 |
+
83002,
|
| 5297 |
+
83006,
|
| 5298 |
+
83007,
|
| 5299 |
+
83050,
|
| 5300 |
+
83051,
|
| 5301 |
+
83058,
|
| 5302 |
+
83065,
|
| 5303 |
+
83073,
|
| 5304 |
+
83097,
|
| 5305 |
+
83107,
|
| 5306 |
+
83137,
|
| 5307 |
+
83164,
|
| 5308 |
+
83191,
|
| 5309 |
+
83197,
|
| 5310 |
+
83207,
|
| 5311 |
+
83222,
|
| 5312 |
+
83226,
|
| 5313 |
+
83237,
|
| 5314 |
+
83244,
|
| 5315 |
+
83271,
|
| 5316 |
+
83280,
|
| 5317 |
+
83312,
|
| 5318 |
+
83320,
|
| 5319 |
+
83327,
|
| 5320 |
+
83332,
|
| 5321 |
+
83347,
|
| 5322 |
+
83359,
|
| 5323 |
+
83383,
|
| 5324 |
+
83394,
|
| 5325 |
+
83434,
|
| 5326 |
+
83447,
|
| 5327 |
+
83457,
|
| 5328 |
+
83460,
|
| 5329 |
+
83485,
|
| 5330 |
+
83503,
|
| 5331 |
+
83515,
|
| 5332 |
+
83519,
|
| 5333 |
+
83522,
|
| 5334 |
+
83532,
|
| 5335 |
+
83554,
|
| 5336 |
+
83555,
|
| 5337 |
+
83570,
|
| 5338 |
+
83591,
|
| 5339 |
+
83626,
|
| 5340 |
+
83643,
|
| 5341 |
+
83663,
|
| 5342 |
+
83670,
|
| 5343 |
+
83671,
|
| 5344 |
+
83710,
|
| 5345 |
+
83711,
|
| 5346 |
+
83724,
|
| 5347 |
+
83725,
|
| 5348 |
+
83738,
|
| 5349 |
+
83748,
|
| 5350 |
+
83775,
|
| 5351 |
+
83790,
|
| 5352 |
+
83809,
|
| 5353 |
+
83844,
|
| 5354 |
+
83849,
|
| 5355 |
+
83852,
|
| 5356 |
+
83853,
|
| 5357 |
+
83877,
|
| 5358 |
+
83886,
|
| 5359 |
+
83894,
|
| 5360 |
+
83900,
|
| 5361 |
+
83913,
|
| 5362 |
+
83917,
|
| 5363 |
+
83921,
|
| 5364 |
+
83933,
|
| 5365 |
+
83941,
|
| 5366 |
+
83950,
|
| 5367 |
+
83970,
|
| 5368 |
+
84008,
|
| 5369 |
+
84019,
|
| 5370 |
+
84025,
|
| 5371 |
+
84044,
|
| 5372 |
+
84086,
|
| 5373 |
+
84109,
|
| 5374 |
+
84119,
|
| 5375 |
+
84133,
|
| 5376 |
+
84141,
|
| 5377 |
+
84164,
|
| 5378 |
+
84200,
|
| 5379 |
+
84201,
|
| 5380 |
+
84212,
|
| 5381 |
+
84215,
|
| 5382 |
+
84238,
|
| 5383 |
+
84271,
|
| 5384 |
+
84274,
|
| 5385 |
+
84325,
|
| 5386 |
+
84330,
|
| 5387 |
+
84333,
|
| 5388 |
+
84345,
|
| 5389 |
+
84356,
|
| 5390 |
+
84413,
|
| 5391 |
+
84462,
|
| 5392 |
+
84472,
|
| 5393 |
+
84496,
|
| 5394 |
+
84500,
|
| 5395 |
+
84517,
|
| 5396 |
+
84539,
|
| 5397 |
+
84554,
|
| 5398 |
+
84558,
|
| 5399 |
+
84559,
|
| 5400 |
+
84562,
|
| 5401 |
+
84563,
|
| 5402 |
+
84565,
|
| 5403 |
+
84567,
|
| 5404 |
+
84572,
|
| 5405 |
+
84576,
|
| 5406 |
+
84580,
|
| 5407 |
+
84588,
|
| 5408 |
+
84595,
|
| 5409 |
+
84613,
|
| 5410 |
+
84631,
|
| 5411 |
+
84636,
|
| 5412 |
+
84645,
|
| 5413 |
+
84685,
|
| 5414 |
+
84693,
|
| 5415 |
+
84702,
|
| 5416 |
+
84705,
|
| 5417 |
+
84716,
|
| 5418 |
+
84738,
|
| 5419 |
+
84741,
|
| 5420 |
+
84852,
|
| 5421 |
+
84863,
|
| 5422 |
+
84875,
|
| 5423 |
+
84877,
|
| 5424 |
+
84898,
|
| 5425 |
+
84929,
|
| 5426 |
+
84940,
|
| 5427 |
+
84944,
|
| 5428 |
+
84960,
|
| 5429 |
+
84999,
|
| 5430 |
+
85004,
|
| 5431 |
+
85054,
|
| 5432 |
+
85103,
|
| 5433 |
+
85120,
|
| 5434 |
+
85161,
|
| 5435 |
+
85166,
|
| 5436 |
+
85167,
|
| 5437 |
+
85177,
|
| 5438 |
+
85180,
|
| 5439 |
+
85203,
|
| 5440 |
+
85243,
|
| 5441 |
+
85268,
|
| 5442 |
+
85277,
|
| 5443 |
+
85288,
|
| 5444 |
+
85312,
|
| 5445 |
+
85318,
|
| 5446 |
+
85321,
|
| 5447 |
+
85334,
|
| 5448 |
+
85342,
|
| 5449 |
+
85368,
|
| 5450 |
+
85392,
|
| 5451 |
+
85398,
|
| 5452 |
+
85407,
|
| 5453 |
+
85413,
|
| 5454 |
+
85422,
|
| 5455 |
+
85434,
|
| 5456 |
+
85447,
|
| 5457 |
+
85465,
|
| 5458 |
+
85490,
|
| 5459 |
+
85494,
|
| 5460 |
+
85500,
|
| 5461 |
+
85503,
|
| 5462 |
+
85540,
|
| 5463 |
+
85545,
|
| 5464 |
+
85568,
|
| 5465 |
+
85595,
|
| 5466 |
+
85602,
|
| 5467 |
+
85604,
|
| 5468 |
+
85617,
|
| 5469 |
+
85629,
|
| 5470 |
+
85677,
|
| 5471 |
+
85714,
|
| 5472 |
+
85718,
|
| 5473 |
+
85764,
|
| 5474 |
+
85785,
|
| 5475 |
+
85794,
|
| 5476 |
+
85795,
|
| 5477 |
+
85846,
|
| 5478 |
+
85847,
|
| 5479 |
+
85863,
|
| 5480 |
+
85867,
|
| 5481 |
+
85886,
|
| 5482 |
+
85892,
|
| 5483 |
+
85912,
|
| 5484 |
+
85925,
|
| 5485 |
+
85931,
|
| 5486 |
+
85990,
|
| 5487 |
+
85991,
|
| 5488 |
+
85994,
|
| 5489 |
+
86021,
|
| 5490 |
+
86025,
|
| 5491 |
+
86062,
|
| 5492 |
+
86076,
|
| 5493 |
+
86085,
|
| 5494 |
+
86089,
|
| 5495 |
+
86114,
|
| 5496 |
+
86146,
|
| 5497 |
+
86154,
|
| 5498 |
+
86197,
|
| 5499 |
+
86214,
|
| 5500 |
+
86215,
|
| 5501 |
+
86232,
|
| 5502 |
+
86234,
|
| 5503 |
+
86237,
|
| 5504 |
+
86256,
|
| 5505 |
+
86265,
|
| 5506 |
+
86303,
|
| 5507 |
+
86316,
|
| 5508 |
+
86321,
|
| 5509 |
+
86344,
|
| 5510 |
+
86378,
|
| 5511 |
+
86427,
|
| 5512 |
+
86435,
|
| 5513 |
+
86436,
|
| 5514 |
+
86459,
|
| 5515 |
+
86465,
|
| 5516 |
+
86474,
|
| 5517 |
+
86503,
|
| 5518 |
+
86558,
|
| 5519 |
+
86620,
|
| 5520 |
+
86637,
|
| 5521 |
+
86643,
|
| 5522 |
+
86661,
|
| 5523 |
+
86709,
|
| 5524 |
+
86724,
|
| 5525 |
+
86726,
|
| 5526 |
+
86729,
|
| 5527 |
+
86770,
|
| 5528 |
+
86779,
|
| 5529 |
+
86812,
|
| 5530 |
+
86827,
|
| 5531 |
+
86828,
|
| 5532 |
+
86843,
|
| 5533 |
+
86853,
|
| 5534 |
+
86856,
|
| 5535 |
+
86881,
|
| 5536 |
+
86922,
|
| 5537 |
+
86967,
|
| 5538 |
+
87008,
|
| 5539 |
+
87036,
|
| 5540 |
+
87037,
|
| 5541 |
+
87059,
|
| 5542 |
+
87079,
|
| 5543 |
+
87094,
|
| 5544 |
+
87109,
|
| 5545 |
+
87110,
|
| 5546 |
+
87114,
|
| 5547 |
+
87120,
|
| 5548 |
+
87136,
|
| 5549 |
+
87141,
|
| 5550 |
+
87248,
|
| 5551 |
+
87260,
|
| 5552 |
+
87282,
|
| 5553 |
+
87299,
|
| 5554 |
+
87346,
|
| 5555 |
+
87358,
|
| 5556 |
+
87411,
|
| 5557 |
+
87414,
|
| 5558 |
+
87433,
|
| 5559 |
+
87441,
|
| 5560 |
+
87442,
|
| 5561 |
+
87489,
|
| 5562 |
+
87553,
|
| 5563 |
+
87565,
|
| 5564 |
+
87567,
|
| 5565 |
+
87569,
|
| 5566 |
+
87573,
|
| 5567 |
+
87574,
|
| 5568 |
+
87586,
|
| 5569 |
+
87597,
|
| 5570 |
+
87619,
|
| 5571 |
+
87628,
|
| 5572 |
+
87647,
|
| 5573 |
+
87653,
|
| 5574 |
+
87676,
|
| 5575 |
+
87685,
|
| 5576 |
+
87712,
|
| 5577 |
+
87736,
|
| 5578 |
+
87741,
|
| 5579 |
+
87754,
|
| 5580 |
+
87771,
|
| 5581 |
+
87775,
|
| 5582 |
+
87793,
|
| 5583 |
+
87861,
|
| 5584 |
+
87874,
|
| 5585 |
+
87894,
|
| 5586 |
+
87903,
|
| 5587 |
+
87942,
|
| 5588 |
+
87951,
|
| 5589 |
+
87959,
|
| 5590 |
+
87964,
|
| 5591 |
+
88002,
|
| 5592 |
+
88033,
|
| 5593 |
+
88090,
|
| 5594 |
+
88099,
|
| 5595 |
+
88102,
|
| 5596 |
+
88117,
|
| 5597 |
+
88120,
|
| 5598 |
+
88125,
|
| 5599 |
+
88141,
|
| 5600 |
+
88143,
|
| 5601 |
+
88176,
|
| 5602 |
+
88252,
|
| 5603 |
+
88281,
|
| 5604 |
+
88349,
|
| 5605 |
+
88363,
|
| 5606 |
+
88380,
|
| 5607 |
+
88385,
|
| 5608 |
+
88433,
|
| 5609 |
+
88463,
|
| 5610 |
+
88480,
|
| 5611 |
+
88490,
|
| 5612 |
+
88512,
|
| 5613 |
+
88523,
|
| 5614 |
+
88529,
|
| 5615 |
+
88541,
|
| 5616 |
+
88573,
|
| 5617 |
+
88622,
|
| 5618 |
+
88657,
|
| 5619 |
+
88691,
|
| 5620 |
+
88726,
|
| 5621 |
+
88744,
|
| 5622 |
+
88763,
|
| 5623 |
+
88774,
|
| 5624 |
+
88783,
|
| 5625 |
+
88804,
|
| 5626 |
+
88830,
|
| 5627 |
+
88853,
|
| 5628 |
+
88866,
|
| 5629 |
+
88889,
|
| 5630 |
+
88901,
|
| 5631 |
+
88903,
|
| 5632 |
+
88928,
|
| 5633 |
+
88940,
|
| 5634 |
+
88945,
|
| 5635 |
+
88946,
|
| 5636 |
+
88988,
|
| 5637 |
+
88998,
|
| 5638 |
+
89004,
|
| 5639 |
+
89036,
|
| 5640 |
+
89039,
|
| 5641 |
+
89049,
|
| 5642 |
+
89061,
|
| 5643 |
+
89063,
|
| 5644 |
+
89071,
|
| 5645 |
+
89083,
|
| 5646 |
+
89092,
|
| 5647 |
+
89093,
|
| 5648 |
+
89095,
|
| 5649 |
+
89101,
|
| 5650 |
+
89138,
|
| 5651 |
+
89148,
|
| 5652 |
+
89157,
|
| 5653 |
+
89160,
|
| 5654 |
+
89166,
|
| 5655 |
+
89179,
|
| 5656 |
+
89212,
|
| 5657 |
+
89213,
|
| 5658 |
+
89238,
|
| 5659 |
+
89253,
|
| 5660 |
+
89262,
|
| 5661 |
+
89291,
|
| 5662 |
+
89297,
|
| 5663 |
+
89318,
|
| 5664 |
+
89329,
|
| 5665 |
+
89363,
|
| 5666 |
+
89382,
|
| 5667 |
+
89383,
|
| 5668 |
+
89384,
|
| 5669 |
+
89385,
|
| 5670 |
+
89389,
|
| 5671 |
+
89401,
|
| 5672 |
+
89411,
|
| 5673 |
+
89419,
|
| 5674 |
+
89427,
|
| 5675 |
+
89434,
|
| 5676 |
+
89443,
|
| 5677 |
+
89459,
|
| 5678 |
+
89460,
|
| 5679 |
+
89467,
|
| 5680 |
+
89478,
|
| 5681 |
+
89486,
|
| 5682 |
+
89488,
|
| 5683 |
+
89494,
|
| 5684 |
+
89516,
|
| 5685 |
+
89526,
|
| 5686 |
+
89528,
|
| 5687 |
+
89543,
|
| 5688 |
+
89598,
|
| 5689 |
+
89650,
|
| 5690 |
+
89683,
|
| 5691 |
+
89684,
|
| 5692 |
+
89694,
|
| 5693 |
+
89720,
|
| 5694 |
+
89727,
|
| 5695 |
+
89744,
|
| 5696 |
+
89746,
|
| 5697 |
+
89764,
|
| 5698 |
+
89788,
|
| 5699 |
+
89835,
|
| 5700 |
+
89855,
|
| 5701 |
+
89856,
|
| 5702 |
+
89869,
|
| 5703 |
+
89882,
|
| 5704 |
+
89903,
|
| 5705 |
+
89921,
|
| 5706 |
+
89929,
|
| 5707 |
+
89950,
|
| 5708 |
+
89958,
|
| 5709 |
+
89966,
|
| 5710 |
+
89998,
|
| 5711 |
+
90001,
|
| 5712 |
+
90094,
|
| 5713 |
+
90096,
|
| 5714 |
+
90118,
|
| 5715 |
+
90147,
|
| 5716 |
+
90148,
|
| 5717 |
+
90155,
|
| 5718 |
+
90177,
|
| 5719 |
+
90178,
|
| 5720 |
+
90192,
|
| 5721 |
+
90204,
|
| 5722 |
+
90208,
|
| 5723 |
+
90218,
|
| 5724 |
+
90220,
|
| 5725 |
+
90222,
|
| 5726 |
+
90230,
|
| 5727 |
+
90237,
|
| 5728 |
+
90241,
|
| 5729 |
+
90265,
|
| 5730 |
+
90276,
|
| 5731 |
+
90277,
|
| 5732 |
+
90278,
|
| 5733 |
+
90306,
|
| 5734 |
+
90308,
|
| 5735 |
+
90314,
|
| 5736 |
+
90332,
|
| 5737 |
+
90335,
|
| 5738 |
+
90358,
|
| 5739 |
+
90380,
|
| 5740 |
+
90387,
|
| 5741 |
+
90395,
|
| 5742 |
+
90408,
|
| 5743 |
+
90410,
|
| 5744 |
+
90415,
|
| 5745 |
+
90430,
|
| 5746 |
+
90440,
|
| 5747 |
+
90475,
|
| 5748 |
+
90476,
|
| 5749 |
+
90496,
|
| 5750 |
+
90515,
|
| 5751 |
+
90522,
|
| 5752 |
+
90546,
|
| 5753 |
+
90557,
|
| 5754 |
+
90621,
|
| 5755 |
+
90639,
|
| 5756 |
+
90643,
|
| 5757 |
+
90651,
|
| 5758 |
+
90675,
|
| 5759 |
+
90677,
|
| 5760 |
+
90679,
|
| 5761 |
+
90688,
|
| 5762 |
+
90698,
|
| 5763 |
+
90711,
|
| 5764 |
+
90717,
|
| 5765 |
+
90730,
|
| 5766 |
+
90734,
|
| 5767 |
+
90759,
|
| 5768 |
+
90768,
|
| 5769 |
+
90798,
|
| 5770 |
+
90827,
|
| 5771 |
+
90832,
|
| 5772 |
+
90839,
|
| 5773 |
+
90894,
|
| 5774 |
+
90906,
|
| 5775 |
+
90911,
|
| 5776 |
+
90959,
|
| 5777 |
+
90983,
|
| 5778 |
+
91008,
|
| 5779 |
+
91018,
|
| 5780 |
+
91035,
|
| 5781 |
+
91048,
|
| 5782 |
+
91050,
|
| 5783 |
+
91088,
|
| 5784 |
+
91093,
|
| 5785 |
+
91099,
|
| 5786 |
+
91117,
|
| 5787 |
+
91182,
|
| 5788 |
+
91196,
|
| 5789 |
+
91205,
|
| 5790 |
+
91211,
|
| 5791 |
+
91223,
|
| 5792 |
+
91249,
|
| 5793 |
+
91276,
|
| 5794 |
+
91278,
|
| 5795 |
+
91283,
|
| 5796 |
+
91287,
|
| 5797 |
+
91301,
|
| 5798 |
+
91347,
|
| 5799 |
+
91349,
|
| 5800 |
+
91354,
|
| 5801 |
+
91360,
|
| 5802 |
+
91383,
|
| 5803 |
+
91389,
|
| 5804 |
+
91399,
|
| 5805 |
+
91403,
|
| 5806 |
+
91413,
|
| 5807 |
+
91479,
|
| 5808 |
+
91514,
|
| 5809 |
+
91515,
|
| 5810 |
+
91517,
|
| 5811 |
+
91528,
|
| 5812 |
+
91545,
|
| 5813 |
+
91573,
|
| 5814 |
+
91581,
|
| 5815 |
+
91586,
|
| 5816 |
+
91595,
|
| 5817 |
+
91630,
|
| 5818 |
+
91637,
|
| 5819 |
+
91644,
|
| 5820 |
+
91697,
|
| 5821 |
+
91699,
|
| 5822 |
+
91737,
|
| 5823 |
+
91752,
|
| 5824 |
+
91756,
|
| 5825 |
+
91771,
|
| 5826 |
+
91779,
|
| 5827 |
+
91812,
|
| 5828 |
+
91827,
|
| 5829 |
+
91841,
|
| 5830 |
+
91867,
|
| 5831 |
+
91868,
|
| 5832 |
+
91888,
|
| 5833 |
+
91889,
|
| 5834 |
+
91898,
|
| 5835 |
+
91904,
|
| 5836 |
+
91921,
|
| 5837 |
+
91927,
|
| 5838 |
+
91935,
|
| 5839 |
+
91940,
|
| 5840 |
+
91944,
|
| 5841 |
+
91958,
|
| 5842 |
+
91976,
|
| 5843 |
+
92000,
|
| 5844 |
+
92010,
|
| 5845 |
+
92047,
|
| 5846 |
+
92056,
|
| 5847 |
+
92081,
|
| 5848 |
+
92084,
|
| 5849 |
+
92099,
|
| 5850 |
+
92102,
|
| 5851 |
+
92103,
|
| 5852 |
+
92108,
|
| 5853 |
+
92111,
|
| 5854 |
+
92120,
|
| 5855 |
+
92142,
|
| 5856 |
+
92149,
|
| 5857 |
+
92163,
|
| 5858 |
+
92165,
|
| 5859 |
+
92171,
|
| 5860 |
+
92173,
|
| 5861 |
+
92181,
|
| 5862 |
+
92187,
|
| 5863 |
+
92190,
|
| 5864 |
+
92213,
|
| 5865 |
+
92222,
|
| 5866 |
+
92228,
|
| 5867 |
+
92243,
|
| 5868 |
+
92277,
|
| 5869 |
+
92327,
|
| 5870 |
+
92346,
|
| 5871 |
+
92349,
|
| 5872 |
+
92378,
|
| 5873 |
+
92379,
|
| 5874 |
+
92456,
|
| 5875 |
+
92464,
|
| 5876 |
+
92465,
|
| 5877 |
+
92515,
|
| 5878 |
+
92562,
|
| 5879 |
+
92590,
|
| 5880 |
+
92650,
|
| 5881 |
+
92710,
|
| 5882 |
+
92723,
|
| 5883 |
+
92737,
|
| 5884 |
+
92753,
|
| 5885 |
+
92763,
|
| 5886 |
+
92782,
|
| 5887 |
+
92783,
|
| 5888 |
+
92833,
|
| 5889 |
+
92855,
|
| 5890 |
+
92880,
|
| 5891 |
+
92893,
|
| 5892 |
+
92897,
|
| 5893 |
+
92910,
|
| 5894 |
+
92978,
|
| 5895 |
+
92986,
|
| 5896 |
+
93004,
|
| 5897 |
+
93008,
|
| 5898 |
+
93029,
|
| 5899 |
+
93045,
|
| 5900 |
+
93047,
|
| 5901 |
+
93075,
|
| 5902 |
+
93083,
|
| 5903 |
+
93170,
|
| 5904 |
+
93175,
|
| 5905 |
+
93178,
|
| 5906 |
+
93188,
|
| 5907 |
+
93191,
|
| 5908 |
+
93196,
|
| 5909 |
+
93219,
|
| 5910 |
+
93227,
|
| 5911 |
+
93241,
|
| 5912 |
+
93244,
|
| 5913 |
+
93255,
|
| 5914 |
+
93271,
|
| 5915 |
+
93273,
|
| 5916 |
+
93296,
|
| 5917 |
+
93299,
|
| 5918 |
+
93314,
|
| 5919 |
+
93316,
|
| 5920 |
+
93317,
|
| 5921 |
+
93333,
|
| 5922 |
+
93342,
|
| 5923 |
+
93349,
|
| 5924 |
+
93389,
|
| 5925 |
+
93397,
|
| 5926 |
+
93437,
|
| 5927 |
+
93448,
|
| 5928 |
+
93490,
|
| 5929 |
+
93509,
|
| 5930 |
+
93538,
|
| 5931 |
+
93544,
|
| 5932 |
+
93549,
|
| 5933 |
+
93558,
|
| 5934 |
+
93596,
|
| 5935 |
+
93601,
|
| 5936 |
+
93611,
|
| 5937 |
+
93614,
|
| 5938 |
+
93618,
|
| 5939 |
+
93627,
|
| 5940 |
+
93633,
|
| 5941 |
+
93652,
|
| 5942 |
+
93670,
|
| 5943 |
+
93682,
|
| 5944 |
+
93718,
|
| 5945 |
+
93728,
|
| 5946 |
+
93744,
|
| 5947 |
+
93746,
|
| 5948 |
+
93754,
|
| 5949 |
+
93826,
|
| 5950 |
+
93844,
|
| 5951 |
+
93873,
|
| 5952 |
+
93892,
|
| 5953 |
+
93896,
|
| 5954 |
+
93897,
|
| 5955 |
+
93902,
|
| 5956 |
+
93905,
|
| 5957 |
+
93911,
|
| 5958 |
+
93920,
|
| 5959 |
+
93922,
|
| 5960 |
+
93939,
|
| 5961 |
+
93941,
|
| 5962 |
+
93977,
|
| 5963 |
+
93986,
|
| 5964 |
+
94010,
|
| 5965 |
+
94023,
|
| 5966 |
+
94028,
|
| 5967 |
+
94034,
|
| 5968 |
+
94037,
|
| 5969 |
+
94052,
|
| 5970 |
+
94081,
|
| 5971 |
+
94125,
|
| 5972 |
+
94127,
|
| 5973 |
+
94128,
|
| 5974 |
+
94136,
|
| 5975 |
+
94141,
|
| 5976 |
+
94169,
|
| 5977 |
+
94208,
|
| 5978 |
+
94227,
|
| 5979 |
+
94239,
|
| 5980 |
+
94244,
|
| 5981 |
+
94305,
|
| 5982 |
+
94326,
|
| 5983 |
+
94334,
|
| 5984 |
+
94335,
|
| 5985 |
+
94345,
|
| 5986 |
+
94367,
|
| 5987 |
+
94374,
|
| 5988 |
+
94391,
|
| 5989 |
+
94432,
|
| 5990 |
+
94439,
|
| 5991 |
+
94448,
|
| 5992 |
+
94456,
|
| 5993 |
+
94464,
|
| 5994 |
+
94491,
|
| 5995 |
+
94502,
|
| 5996 |
+
94511,
|
| 5997 |
+
94521,
|
| 5998 |
+
94538,
|
| 5999 |
+
94601,
|
| 6000 |
+
94614,
|
| 6001 |
+
94620,
|
| 6002 |
+
94679,
|
| 6003 |
+
94691,
|
| 6004 |
+
94702,
|
| 6005 |
+
94714,
|
| 6006 |
+
94722,
|
| 6007 |
+
94730,
|
| 6008 |
+
94745,
|
| 6009 |
+
94753,
|
| 6010 |
+
94767,
|
| 6011 |
+
94773,
|
| 6012 |
+
94786,
|
| 6013 |
+
94792,
|
| 6014 |
+
94799,
|
| 6015 |
+
94807,
|
| 6016 |
+
94821,
|
| 6017 |
+
94825,
|
| 6018 |
+
94883,
|
| 6019 |
+
94884,
|
| 6020 |
+
94886,
|
| 6021 |
+
94888,
|
| 6022 |
+
94892,
|
| 6023 |
+
94925,
|
| 6024 |
+
94931,
|
| 6025 |
+
94945,
|
| 6026 |
+
94947,
|
| 6027 |
+
94951,
|
| 6028 |
+
94964,
|
| 6029 |
+
94976,
|
| 6030 |
+
94985,
|
| 6031 |
+
95024,
|
| 6032 |
+
95032,
|
| 6033 |
+
95036,
|
| 6034 |
+
95053,
|
| 6035 |
+
95063,
|
| 6036 |
+
95069,
|
| 6037 |
+
95071,
|
| 6038 |
+
95087,
|
| 6039 |
+
95105,
|
| 6040 |
+
95106,
|
| 6041 |
+
95113,
|
| 6042 |
+
95114,
|
| 6043 |
+
95140,
|
| 6044 |
+
95159,
|
| 6045 |
+
95173,
|
| 6046 |
+
95211,
|
| 6047 |
+
95248,
|
| 6048 |
+
95255,
|
| 6049 |
+
95267,
|
| 6050 |
+
95270,
|
| 6051 |
+
95274,
|
| 6052 |
+
95278,
|
| 6053 |
+
95288,
|
| 6054 |
+
95299,
|
| 6055 |
+
95323,
|
| 6056 |
+
95349,
|
| 6057 |
+
95350,
|
| 6058 |
+
95357,
|
| 6059 |
+
95363,
|
| 6060 |
+
95368,
|
| 6061 |
+
95377,
|
| 6062 |
+
95423,
|
| 6063 |
+
95426,
|
| 6064 |
+
95438,
|
| 6065 |
+
95482,
|
| 6066 |
+
95492,
|
| 6067 |
+
95519,
|
| 6068 |
+
95522,
|
| 6069 |
+
95525,
|
| 6070 |
+
95527,
|
| 6071 |
+
95528,
|
| 6072 |
+
95546,
|
| 6073 |
+
95586,
|
| 6074 |
+
95605,
|
| 6075 |
+
95620,
|
| 6076 |
+
95642,
|
| 6077 |
+
95654,
|
| 6078 |
+
95670,
|
| 6079 |
+
95674,
|
| 6080 |
+
95685,
|
| 6081 |
+
95687,
|
| 6082 |
+
95707,
|
| 6083 |
+
95741,
|
| 6084 |
+
95753,
|
| 6085 |
+
95754,
|
| 6086 |
+
95804,
|
| 6087 |
+
95810,
|
| 6088 |
+
95815,
|
| 6089 |
+
95843,
|
| 6090 |
+
95849,
|
| 6091 |
+
95851,
|
| 6092 |
+
95884,
|
| 6093 |
+
95892,
|
| 6094 |
+
95901,
|
| 6095 |
+
95906,
|
| 6096 |
+
95916,
|
| 6097 |
+
95970,
|
| 6098 |
+
95974,
|
| 6099 |
+
95989,
|
| 6100 |
+
96017,
|
| 6101 |
+
96021,
|
| 6102 |
+
96025,
|
| 6103 |
+
96033,
|
| 6104 |
+
96050,
|
| 6105 |
+
96055,
|
| 6106 |
+
96060,
|
| 6107 |
+
96065,
|
| 6108 |
+
96069,
|
| 6109 |
+
96075,
|
| 6110 |
+
96090,
|
| 6111 |
+
96116,
|
| 6112 |
+
96117,
|
| 6113 |
+
96121,
|
| 6114 |
+
96133,
|
| 6115 |
+
96138,
|
| 6116 |
+
96155,
|
| 6117 |
+
96200,
|
| 6118 |
+
96279,
|
| 6119 |
+
96332,
|
| 6120 |
+
96335,
|
| 6121 |
+
96351,
|
| 6122 |
+
96360,
|
| 6123 |
+
96366,
|
| 6124 |
+
96390,
|
| 6125 |
+
96426,
|
| 6126 |
+
96461,
|
| 6127 |
+
96466,
|
| 6128 |
+
96494,
|
| 6129 |
+
96501,
|
| 6130 |
+
96503,
|
| 6131 |
+
96530,
|
| 6132 |
+
96561,
|
| 6133 |
+
96580,
|
| 6134 |
+
96581,
|
| 6135 |
+
96595,
|
| 6136 |
+
96604,
|
| 6137 |
+
96683,
|
| 6138 |
+
96705,
|
| 6139 |
+
96711,
|
| 6140 |
+
96721,
|
| 6141 |
+
96731,
|
| 6142 |
+
96756,
|
| 6143 |
+
96759,
|
| 6144 |
+
96771,
|
| 6145 |
+
96773,
|
| 6146 |
+
96786,
|
| 6147 |
+
96806,
|
| 6148 |
+
96808,
|
| 6149 |
+
96859,
|
| 6150 |
+
96866,
|
| 6151 |
+
96887,
|
| 6152 |
+
96899,
|
| 6153 |
+
96911,
|
| 6154 |
+
96912,
|
| 6155 |
+
96938,
|
| 6156 |
+
96950,
|
| 6157 |
+
96996,
|
| 6158 |
+
97000,
|
| 6159 |
+
97015,
|
| 6160 |
+
97061,
|
| 6161 |
+
97064,
|
| 6162 |
+
97085,
|
| 6163 |
+
97086,
|
| 6164 |
+
97095,
|
| 6165 |
+
97112,
|
| 6166 |
+
97149,
|
| 6167 |
+
97172,
|
| 6168 |
+
97207,
|
| 6169 |
+
97216,
|
| 6170 |
+
97233,
|
| 6171 |
+
97236,
|
| 6172 |
+
97238,
|
| 6173 |
+
97256,
|
| 6174 |
+
97259,
|
| 6175 |
+
97309,
|
| 6176 |
+
97314,
|
| 6177 |
+
97332,
|
| 6178 |
+
97342,
|
| 6179 |
+
97347,
|
| 6180 |
+
97348,
|
| 6181 |
+
97403,
|
| 6182 |
+
97433,
|
| 6183 |
+
97469,
|
| 6184 |
+
97470,
|
| 6185 |
+
97478,
|
| 6186 |
+
97494,
|
| 6187 |
+
97514,
|
| 6188 |
+
97529,
|
| 6189 |
+
97539,
|
| 6190 |
+
97556,
|
| 6191 |
+
97568,
|
| 6192 |
+
97591,
|
| 6193 |
+
97605,
|
| 6194 |
+
97606,
|
| 6195 |
+
97619,
|
| 6196 |
+
97644,
|
| 6197 |
+
97676,
|
| 6198 |
+
97739,
|
| 6199 |
+
97741,
|
| 6200 |
+
97833,
|
| 6201 |
+
97856,
|
| 6202 |
+
97887,
|
| 6203 |
+
97918,
|
| 6204 |
+
97923,
|
| 6205 |
+
97937,
|
| 6206 |
+
97942,
|
| 6207 |
+
97946,
|
| 6208 |
+
97962,
|
| 6209 |
+
97999,
|
| 6210 |
+
98008,
|
| 6211 |
+
98029,
|
| 6212 |
+
98045,
|
| 6213 |
+
98048,
|
| 6214 |
+
98079,
|
| 6215 |
+
98102,
|
| 6216 |
+
98140,
|
| 6217 |
+
98155,
|
| 6218 |
+
98164,
|
| 6219 |
+
98174,
|
| 6220 |
+
98187,
|
| 6221 |
+
98203,
|
| 6222 |
+
98207,
|
| 6223 |
+
98208,
|
| 6224 |
+
98220,
|
| 6225 |
+
98249,
|
| 6226 |
+
98251,
|
| 6227 |
+
98274,
|
| 6228 |
+
98276,
|
| 6229 |
+
98282,
|
| 6230 |
+
98291,
|
| 6231 |
+
98302,
|
| 6232 |
+
98313,
|
| 6233 |
+
98319,
|
| 6234 |
+
98320,
|
| 6235 |
+
98329,
|
| 6236 |
+
98330,
|
| 6237 |
+
98347,
|
| 6238 |
+
98364,
|
| 6239 |
+
98366,
|
| 6240 |
+
98372,
|
| 6241 |
+
98379,
|
| 6242 |
+
98385,
|
| 6243 |
+
98398,
|
| 6244 |
+
98401,
|
| 6245 |
+
98406,
|
| 6246 |
+
98422,
|
| 6247 |
+
98434,
|
| 6248 |
+
98436,
|
| 6249 |
+
98443,
|
| 6250 |
+
98517,
|
| 6251 |
+
98524,
|
| 6252 |
+
98527,
|
| 6253 |
+
98610,
|
| 6254 |
+
98642,
|
| 6255 |
+
98655,
|
| 6256 |
+
98665,
|
| 6257 |
+
98670,
|
| 6258 |
+
98685,
|
| 6259 |
+
98688,
|
| 6260 |
+
98708,
|
| 6261 |
+
98722,
|
| 6262 |
+
98729,
|
| 6263 |
+
98734,
|
| 6264 |
+
98737,
|
| 6265 |
+
98747,
|
| 6266 |
+
98759,
|
| 6267 |
+
98769,
|
| 6268 |
+
98788,
|
| 6269 |
+
98821,
|
| 6270 |
+
98837,
|
| 6271 |
+
98853,
|
| 6272 |
+
98873,
|
| 6273 |
+
98880,
|
| 6274 |
+
98891,
|
| 6275 |
+
98893,
|
| 6276 |
+
98899,
|
| 6277 |
+
98903,
|
| 6278 |
+
98906,
|
| 6279 |
+
98926,
|
| 6280 |
+
98952,
|
| 6281 |
+
98964,
|
| 6282 |
+
98965,
|
| 6283 |
+
98973,
|
| 6284 |
+
98976,
|
| 6285 |
+
98986,
|
| 6286 |
+
98997,
|
| 6287 |
+
99007,
|
| 6288 |
+
99010,
|
| 6289 |
+
99012,
|
| 6290 |
+
99057,
|
| 6291 |
+
99058,
|
| 6292 |
+
99076,
|
| 6293 |
+
99082,
|
| 6294 |
+
99095,
|
| 6295 |
+
99102,
|
| 6296 |
+
99141,
|
| 6297 |
+
99144,
|
| 6298 |
+
99151,
|
| 6299 |
+
99156,
|
| 6300 |
+
99157,
|
| 6301 |
+
99158,
|
| 6302 |
+
99159,
|
| 6303 |
+
99160,
|
| 6304 |
+
99161,
|
| 6305 |
+
99162,
|
| 6306 |
+
99163,
|
| 6307 |
+
99166,
|
| 6308 |
+
99167,
|
| 6309 |
+
99168,
|
| 6310 |
+
99169,
|
| 6311 |
+
99170,
|
| 6312 |
+
99171,
|
| 6313 |
+
99173,
|
| 6314 |
+
99174,
|
| 6315 |
+
99175,
|
| 6316 |
+
99176,
|
| 6317 |
+
99177,
|
| 6318 |
+
99179,
|
| 6319 |
+
99181,
|
| 6320 |
+
99183,
|
| 6321 |
+
99184,
|
| 6322 |
+
99187,
|
| 6323 |
+
99188,
|
| 6324 |
+
99189,
|
| 6325 |
+
99192,
|
| 6326 |
+
99196,
|
| 6327 |
+
99197,
|
| 6328 |
+
99198,
|
| 6329 |
+
99201,
|
| 6330 |
+
99202,
|
| 6331 |
+
99203,
|
| 6332 |
+
99206,
|
| 6333 |
+
99207,
|
| 6334 |
+
99211,
|
| 6335 |
+
99214,
|
| 6336 |
+
99215,
|
| 6337 |
+
99220,
|
| 6338 |
+
99221,
|
| 6339 |
+
99224,
|
| 6340 |
+
99228,
|
| 6341 |
+
99229,
|
| 6342 |
+
99230,
|
| 6343 |
+
99231,
|
| 6344 |
+
99238,
|
| 6345 |
+
99239,
|
| 6346 |
+
99240,
|
| 6347 |
+
99247,
|
| 6348 |
+
99248,
|
| 6349 |
+
99249,
|
| 6350 |
+
99254,
|
| 6351 |
+
99255,
|
| 6352 |
+
99256,
|
| 6353 |
+
99264,
|
| 6354 |
+
99265,
|
| 6355 |
+
99266,
|
| 6356 |
+
99267,
|
| 6357 |
+
99268,
|
| 6358 |
+
99269,
|
| 6359 |
+
99274,
|
| 6360 |
+
99275,
|
| 6361 |
+
99276,
|
| 6362 |
+
99281,
|
| 6363 |
+
99282,
|
| 6364 |
+
99289,
|
| 6365 |
+
99290,
|
| 6366 |
+
99291,
|
| 6367 |
+
99300,
|
| 6368 |
+
99301,
|
| 6369 |
+
99302,
|
| 6370 |
+
99303,
|
| 6371 |
+
99311,
|
| 6372 |
+
99323,
|
| 6373 |
+
99324,
|
| 6374 |
+
99325,
|
| 6375 |
+
99341,
|
| 6376 |
+
99342,
|
| 6377 |
+
99343,
|
| 6378 |
+
99344,
|
| 6379 |
+
99359,
|
| 6380 |
+
99374,
|
| 6381 |
+
99380,
|
| 6382 |
+
99381,
|
| 6383 |
+
99382,
|
| 6384 |
+
99401,
|
| 6385 |
+
99402,
|
| 6386 |
+
99423,
|
| 6387 |
+
99439,
|
| 6388 |
+
99442,
|
| 6389 |
+
99443,
|
| 6390 |
+
99444,
|
| 6391 |
+
99456,
|
| 6392 |
+
99484,
|
| 6393 |
+
99485,
|
| 6394 |
+
99516,
|
| 6395 |
+
99551,
|
| 6396 |
+
99552,
|
| 6397 |
+
99597,
|
| 6398 |
+
99598,
|
| 6399 |
+
99643,
|
| 6400 |
+
99648,
|
| 6401 |
+
99649,
|
| 6402 |
+
99714,
|
| 6403 |
+
99715,
|
| 6404 |
+
99777,
|
| 6405 |
+
99785,
|
| 6406 |
+
99874,
|
| 6407 |
+
99875,
|
| 6408 |
+
99977,
|
| 6409 |
+
99997,
|
| 6410 |
+
100024,
|
| 6411 |
+
100120,
|
| 6412 |
+
100121,
|
| 6413 |
+
100127,
|
| 6414 |
+
100128,
|
| 6415 |
+
100129,
|
| 6416 |
+
100130,
|
| 6417 |
+
100337,
|
| 6418 |
+
100459,
|
| 6419 |
+
100563,
|
| 6420 |
+
100620,
|
| 6421 |
+
100621,
|
| 6422 |
+
100988,
|
| 6423 |
+
101018,
|
| 6424 |
+
101022,
|
| 6425 |
+
101024,
|
| 6426 |
+
101025,
|
| 6427 |
+
101026,
|
| 6428 |
+
101027,
|
| 6429 |
+
101028,
|
| 6430 |
+
101029,
|
| 6431 |
+
101030,
|
| 6432 |
+
101031,
|
| 6433 |
+
101032,
|
| 6434 |
+
101033,
|
| 6435 |
+
101759,
|
| 6436 |
+
101838,
|
| 6437 |
+
101851,
|
| 6438 |
+
101860,
|
| 6439 |
+
101861,
|
| 6440 |
+
101862,
|
| 6441 |
+
101863,
|
| 6442 |
+
101864,
|
| 6443 |
+
101865,
|
| 6444 |
+
101866,
|
| 6445 |
+
101867,
|
| 6446 |
+
101868,
|
| 6447 |
+
101869,
|
| 6448 |
+
101870,
|
| 6449 |
+
101871,
|
| 6450 |
+
101872,
|
| 6451 |
+
101873,
|
| 6452 |
+
101874,
|
| 6453 |
+
101875,
|
| 6454 |
+
101876,
|
| 6455 |
+
101877,
|
| 6456 |
+
101878,
|
| 6457 |
+
101879,
|
| 6458 |
+
101880,
|
| 6459 |
+
101881,
|
| 6460 |
+
103893,
|
| 6461 |
+
103894,
|
| 6462 |
+
103895,
|
| 6463 |
+
103896,
|
| 6464 |
+
103897,
|
| 6465 |
+
103898,
|
| 6466 |
+
103899,
|
| 6467 |
+
103900,
|
| 6468 |
+
103901,
|
| 6469 |
+
103902,
|
| 6470 |
+
103903,
|
| 6471 |
+
103904,
|
| 6472 |
+
103905,
|
| 6473 |
+
103906,
|
| 6474 |
+
103907,
|
| 6475 |
+
103908,
|
| 6476 |
+
103909,
|
| 6477 |
+
103910,
|
| 6478 |
+
103911,
|
| 6479 |
+
103912,
|
| 6480 |
+
103913,
|
| 6481 |
+
103914,
|
| 6482 |
+
103915,
|
| 6483 |
+
103916,
|
| 6484 |
+
103917,
|
| 6485 |
+
104905,
|
| 6486 |
+
105619,
|
| 6487 |
+
109241,
|
| 6488 |
+
109992,
|
| 6489 |
+
110713,
|
| 6490 |
+
111747,
|
| 6491 |
+
112951,
|
| 6492 |
+
113943,
|
| 6493 |
+
114235,
|
| 6494 |
+
114397,
|
| 6495 |
+
115646,
|
| 6496 |
+
117035,
|
| 6497 |
+
119158,
|
| 6498 |
+
119346,
|
| 6499 |
+
119347,
|
| 6500 |
+
119348,
|
| 6501 |
+
119941,
|
| 6502 |
+
119964,
|
| 6503 |
+
120100,
|
| 6504 |
+
120409,
|
| 6505 |
+
121404,
|
| 6506 |
+
121667,
|
| 6507 |
+
121773,
|
| 6508 |
+
122154,
|
| 6509 |
+
122174,
|
| 6510 |
+
122202,
|
| 6511 |
+
122219,
|
| 6512 |
+
122222,
|
| 6513 |
+
122259,
|
| 6514 |
+
122267,
|
| 6515 |
+
122289,
|
| 6516 |
+
122317,
|
| 6517 |
+
122375,
|
| 6518 |
+
122382,
|
| 6519 |
+
122427,
|
| 6520 |
+
122448,
|
| 6521 |
+
122455,
|
| 6522 |
+
122514,
|
| 6523 |
+
122568,
|
| 6524 |
+
122596,
|
| 6525 |
+
122614,
|
| 6526 |
+
122618,
|
| 6527 |
+
122634,
|
| 6528 |
+
122659,
|
| 6529 |
+
122725,
|
| 6530 |
+
122740,
|
| 6531 |
+
122757,
|
| 6532 |
+
122802,
|
| 6533 |
+
122843,
|
| 6534 |
+
122855,
|
| 6535 |
+
122866,
|
| 6536 |
+
122890,
|
| 6537 |
+
122948,
|
| 6538 |
+
122950,
|
| 6539 |
+
122976,
|
| 6540 |
+
122985,
|
| 6541 |
+
122999,
|
| 6542 |
+
123007,
|
| 6543 |
+
123008,
|
| 6544 |
+
123016,
|
| 6545 |
+
123057,
|
| 6546 |
+
123064,
|
| 6547 |
+
123067,
|
| 6548 |
+
123072,
|
| 6549 |
+
123084,
|
| 6550 |
+
123091,
|
| 6551 |
+
123131,
|
| 6552 |
+
123164,
|
| 6553 |
+
123178,
|
| 6554 |
+
123182,
|
| 6555 |
+
123204,
|
| 6556 |
+
123206,
|
| 6557 |
+
123287,
|
| 6558 |
+
123301,
|
| 6559 |
+
123305,
|
| 6560 |
+
123318,
|
| 6561 |
+
123332,
|
| 6562 |
+
123378,
|
| 6563 |
+
123400,
|
| 6564 |
+
123408,
|
| 6565 |
+
123420,
|
| 6566 |
+
123489,
|
| 6567 |
+
123516,
|
| 6568 |
+
123527,
|
| 6569 |
+
123547,
|
| 6570 |
+
123614,
|
| 6571 |
+
123658,
|
| 6572 |
+
123676,
|
| 6573 |
+
123701,
|
| 6574 |
+
123714,
|
| 6575 |
+
123740,
|
| 6576 |
+
123747,
|
| 6577 |
+
123760,
|
| 6578 |
+
123806,
|
| 6579 |
+
123807,
|
| 6580 |
+
123808,
|
| 6581 |
+
123810,
|
| 6582 |
+
123811,
|
| 6583 |
+
123812,
|
| 6584 |
+
123813,
|
| 6585 |
+
123814,
|
| 6586 |
+
123815,
|
| 6587 |
+
123816,
|
| 6588 |
+
123817,
|
| 6589 |
+
123819,
|
| 6590 |
+
123821,
|
| 6591 |
+
123825,
|
| 6592 |
+
123827,
|
| 6593 |
+
123830,
|
| 6594 |
+
123836,
|
| 6595 |
+
123837,
|
| 6596 |
+
123839,
|
| 6597 |
+
123840,
|
| 6598 |
+
123841,
|
| 6599 |
+
123842,
|
| 6600 |
+
123844,
|
| 6601 |
+
123846,
|
| 6602 |
+
123847,
|
| 6603 |
+
123848,
|
| 6604 |
+
123851,
|
| 6605 |
+
123853,
|
| 6606 |
+
123854,
|
| 6607 |
+
123859,
|
| 6608 |
+
123867,
|
| 6609 |
+
123870,
|
| 6610 |
+
123871,
|
| 6611 |
+
123875,
|
| 6612 |
+
123876,
|
| 6613 |
+
123882,
|
| 6614 |
+
123889,
|
| 6615 |
+
123892,
|
| 6616 |
+
123893,
|
| 6617 |
+
123907,
|
| 6618 |
+
123908,
|
| 6619 |
+
123911,
|
| 6620 |
+
123912,
|
| 6621 |
+
123916,
|
| 6622 |
+
123917,
|
| 6623 |
+
123918,
|
| 6624 |
+
123927,
|
| 6625 |
+
123928,
|
| 6626 |
+
123929,
|
| 6627 |
+
123930,
|
| 6628 |
+
123931,
|
| 6629 |
+
123932,
|
| 6630 |
+
123933,
|
| 6631 |
+
123934,
|
| 6632 |
+
123946,
|
| 6633 |
+
123947,
|
| 6634 |
+
123950,
|
| 6635 |
+
123951,
|
| 6636 |
+
123953,
|
| 6637 |
+
123954,
|
| 6638 |
+
123955,
|
| 6639 |
+
123956,
|
| 6640 |
+
123957,
|
| 6641 |
+
123965,
|
| 6642 |
+
123967,
|
| 6643 |
+
123968,
|
| 6644 |
+
123969,
|
| 6645 |
+
123970,
|
| 6646 |
+
123986,
|
| 6647 |
+
123989,
|
| 6648 |
+
123996,
|
| 6649 |
+
124000,
|
| 6650 |
+
124001,
|
| 6651 |
+
124002,
|
| 6652 |
+
124003,
|
| 6653 |
+
124004,
|
| 6654 |
+
124005,
|
| 6655 |
+
124018,
|
| 6656 |
+
124019,
|
| 6657 |
+
124020,
|
| 6658 |
+
124021,
|
| 6659 |
+
124022,
|
| 6660 |
+
124023,
|
| 6661 |
+
124024,
|
| 6662 |
+
124025,
|
| 6663 |
+
124026,
|
| 6664 |
+
124049,
|
| 6665 |
+
124050,
|
| 6666 |
+
124051,
|
| 6667 |
+
124052,
|
| 6668 |
+
124053,
|
| 6669 |
+
124054,
|
| 6670 |
+
124063,
|
| 6671 |
+
124064,
|
| 6672 |
+
124066,
|
| 6673 |
+
124067,
|
| 6674 |
+
124068,
|
| 6675 |
+
124069,
|
| 6676 |
+
124070,
|
| 6677 |
+
124071,
|
| 6678 |
+
124092,
|
| 6679 |
+
124096,
|
| 6680 |
+
124098,
|
| 6681 |
+
124099,
|
| 6682 |
+
124100,
|
| 6683 |
+
124101,
|
| 6684 |
+
124102,
|
| 6685 |
+
124118,
|
| 6686 |
+
124134,
|
| 6687 |
+
124135,
|
| 6688 |
+
124136,
|
| 6689 |
+
124137,
|
| 6690 |
+
124149,
|
| 6691 |
+
124154,
|
| 6692 |
+
124159,
|
| 6693 |
+
124160,
|
| 6694 |
+
124161,
|
| 6695 |
+
124162,
|
| 6696 |
+
124163,
|
| 6697 |
+
124164,
|
| 6698 |
+
124165,
|
| 6699 |
+
124166,
|
| 6700 |
+
124167,
|
| 6701 |
+
124168,
|
| 6702 |
+
124193,
|
| 6703 |
+
124194,
|
| 6704 |
+
124195,
|
| 6705 |
+
124196,
|
| 6706 |
+
124197,
|
| 6707 |
+
124198,
|
| 6708 |
+
124199,
|
| 6709 |
+
124200,
|
| 6710 |
+
124201,
|
| 6711 |
+
124222,
|
| 6712 |
+
124235,
|
| 6713 |
+
124236,
|
| 6714 |
+
124240,
|
| 6715 |
+
124241,
|
| 6716 |
+
124243,
|
| 6717 |
+
124244,
|
| 6718 |
+
124245,
|
| 6719 |
+
124246,
|
| 6720 |
+
124247,
|
| 6721 |
+
124248,
|
| 6722 |
+
124249,
|
| 6723 |
+
124250,
|
| 6724 |
+
124251,
|
| 6725 |
+
124252,
|
| 6726 |
+
124287,
|
| 6727 |
+
124296,
|
| 6728 |
+
124297,
|
| 6729 |
+
124298,
|
| 6730 |
+
124299,
|
| 6731 |
+
124300,
|
| 6732 |
+
124301,
|
| 6733 |
+
124302,
|
| 6734 |
+
124303,
|
| 6735 |
+
124304,
|
| 6736 |
+
124305,
|
| 6737 |
+
124306,
|
| 6738 |
+
124307,
|
| 6739 |
+
124308,
|
| 6740 |
+
124309,
|
| 6741 |
+
124334,
|
| 6742 |
+
124349,
|
| 6743 |
+
124364,
|
| 6744 |
+
124365,
|
| 6745 |
+
124366,
|
| 6746 |
+
124367,
|
| 6747 |
+
124368,
|
| 6748 |
+
124369,
|
| 6749 |
+
124370,
|
| 6750 |
+
124371,
|
| 6751 |
+
124372,
|
| 6752 |
+
124373,
|
| 6753 |
+
124374,
|
| 6754 |
+
124433,
|
| 6755 |
+
124459,
|
| 6756 |
+
124470,
|
| 6757 |
+
124471,
|
| 6758 |
+
124472,
|
| 6759 |
+
124473,
|
| 6760 |
+
124474,
|
| 6761 |
+
124475,
|
| 6762 |
+
124570,
|
| 6763 |
+
124577,
|
| 6764 |
+
124578,
|
| 6765 |
+
124579,
|
| 6766 |
+
124580,
|
| 6767 |
+
124581,
|
| 6768 |
+
124582,
|
| 6769 |
+
124583,
|
| 6770 |
+
124584,
|
| 6771 |
+
124585,
|
| 6772 |
+
124586,
|
| 6773 |
+
124587,
|
| 6774 |
+
124588,
|
| 6775 |
+
124589,
|
| 6776 |
+
124590,
|
| 6777 |
+
124591,
|
| 6778 |
+
124592,
|
| 6779 |
+
124593,
|
| 6780 |
+
124594,
|
| 6781 |
+
124595,
|
| 6782 |
+
124596,
|
| 6783 |
+
124693,
|
| 6784 |
+
124727,
|
| 6785 |
+
124744,
|
| 6786 |
+
124745,
|
| 6787 |
+
124746,
|
| 6788 |
+
124747,
|
| 6789 |
+
124748,
|
| 6790 |
+
124749,
|
| 6791 |
+
124750,
|
| 6792 |
+
124751,
|
| 6793 |
+
124752,
|
| 6794 |
+
124753,
|
| 6795 |
+
124754,
|
| 6796 |
+
124755,
|
| 6797 |
+
124995,
|
| 6798 |
+
124996,
|
| 6799 |
+
124997,
|
| 6800 |
+
124998,
|
| 6801 |
+
124999,
|
| 6802 |
+
125000,
|
| 6803 |
+
125001,
|
| 6804 |
+
125002,
|
| 6805 |
+
125003,
|
| 6806 |
+
125004,
|
| 6807 |
+
125388,
|
| 6808 |
+
125413,
|
| 6809 |
+
125414,
|
| 6810 |
+
125415,
|
| 6811 |
+
125416,
|
| 6812 |
+
125417,
|
| 6813 |
+
125418,
|
| 6814 |
+
125419,
|
| 6815 |
+
125420,
|
| 6816 |
+
125421,
|
| 6817 |
+
125422,
|
| 6818 |
+
125423,
|
| 6819 |
+
125424,
|
| 6820 |
+
125425,
|
| 6821 |
+
125426,
|
| 6822 |
+
125427,
|
| 6823 |
+
125428,
|
| 6824 |
+
125429,
|
| 6825 |
+
125430,
|
| 6826 |
+
125639,
|
| 6827 |
+
125713,
|
| 6828 |
+
126159,
|
| 6829 |
+
126177,
|
| 6830 |
+
126178,
|
| 6831 |
+
126179,
|
| 6832 |
+
126180,
|
| 6833 |
+
126181,
|
| 6834 |
+
126182,
|
| 6835 |
+
126183,
|
| 6836 |
+
126184,
|
| 6837 |
+
126185,
|
| 6838 |
+
126186,
|
| 6839 |
+
126187,
|
| 6840 |
+
126188,
|
| 6841 |
+
126189,
|
| 6842 |
+
126190,
|
| 6843 |
+
126191,
|
| 6844 |
+
126192,
|
| 6845 |
+
126193,
|
| 6846 |
+
126365,
|
| 6847 |
+
126537,
|
| 6848 |
+
127041,
|
| 6849 |
+
127124,
|
| 6850 |
+
127165,
|
| 6851 |
+
127369,
|
| 6852 |
+
127572,
|
| 6853 |
+
127708,
|
| 6854 |
+
127819,
|
| 6855 |
+
127964,
|
| 6856 |
+
128222,
|
| 6857 |
+
128223,
|
| 6858 |
+
128224,
|
| 6859 |
+
128225,
|
| 6860 |
+
128226,
|
| 6861 |
+
128227,
|
| 6862 |
+
128228,
|
| 6863 |
+
128229,
|
| 6864 |
+
128230,
|
| 6865 |
+
128231,
|
| 6866 |
+
128232,
|
| 6867 |
+
128233,
|
| 6868 |
+
128234,
|
| 6869 |
+
128235,
|
| 6870 |
+
128236,
|
| 6871 |
+
128237,
|
| 6872 |
+
128238,
|
| 6873 |
+
128239,
|
| 6874 |
+
128240,
|
| 6875 |
+
128241,
|
| 6876 |
+
128242,
|
| 6877 |
+
129176,
|
| 6878 |
+
130507,
|
| 6879 |
+
130654,
|
| 6880 |
+
132202,
|
| 6881 |
+
132376,
|
| 6882 |
+
133552,
|
| 6883 |
+
134312,
|
| 6884 |
+
134380,
|
| 6885 |
+
134582,
|
| 6886 |
+
135078,
|
| 6887 |
+
136279,
|
| 6888 |
+
136516,
|
| 6889 |
+
136661,
|
| 6890 |
+
136940,
|
| 6891 |
+
136946,
|
| 6892 |
+
137345,
|
| 6893 |
+
137661,
|
| 6894 |
+
137767,
|
| 6895 |
+
137973,
|
| 6896 |
+
138658,
|
| 6897 |
+
138673,
|
| 6898 |
+
139793,
|
| 6899 |
+
139816,
|
| 6900 |
+
140356,
|
| 6901 |
+
141539,
|
| 6902 |
+
142067,
|
| 6903 |
+
142209,
|
| 6904 |
+
142210,
|
| 6905 |
+
142258,
|
| 6906 |
+
142274,
|
| 6907 |
+
142299,
|
| 6908 |
+
142451,
|
| 6909 |
+
142509,
|
| 6910 |
+
142731,
|
| 6911 |
+
142834,
|
| 6912 |
+
143241,
|
| 6913 |
+
143455,
|
| 6914 |
+
143861,
|
| 6915 |
+
143887,
|
| 6916 |
+
145773,
|
| 6917 |
+
146047,
|
| 6918 |
+
146632,
|
| 6919 |
+
148462,
|
| 6920 |
+
148774,
|
| 6921 |
+
148827,
|
| 6922 |
+
148860,
|
| 6923 |
+
148864,
|
| 6924 |
+
148880,
|
| 6925 |
+
149175,
|
| 6926 |
+
149178,
|
| 6927 |
+
149287,
|
| 6928 |
+
149352,
|
| 6929 |
+
149392,
|
| 6930 |
+
149394,
|
| 6931 |
+
149589,
|
| 6932 |
+
149591,
|
| 6933 |
+
149593,
|
| 6934 |
+
149714,
|
| 6935 |
+
149716,
|
| 6936 |
+
149718,
|
| 6937 |
+
149721,
|
| 6938 |
+
149946,
|
| 6939 |
+
149961,
|
| 6940 |
+
149963,
|
| 6941 |
+
149990,
|
| 6942 |
+
150114,
|
| 6943 |
+
150151,
|
| 6944 |
+
150168,
|
| 6945 |
+
150195,
|
| 6946 |
+
150223,
|
| 6947 |
+
150270,
|
| 6948 |
+
150479,
|
| 6949 |
+
150579,
|
| 6950 |
+
150792,
|
| 6951 |
+
150794,
|
| 6952 |
+
150800,
|
| 6953 |
+
150802,
|
| 6954 |
+
150807,
|
| 6955 |
+
150809,
|
| 6956 |
+
150814,
|
| 6957 |
+
150817,
|
| 6958 |
+
150819,
|
| 6959 |
+
150821,
|
| 6960 |
+
150824,
|
| 6961 |
+
150829,
|
| 6962 |
+
150836,
|
| 6963 |
+
151233,
|
| 6964 |
+
151254,
|
| 6965 |
+
151264,
|
| 6966 |
+
151266,
|
| 6967 |
+
151268,
|
| 6968 |
+
151270,
|
| 6969 |
+
151272,
|
| 6970 |
+
151274,
|
| 6971 |
+
151276,
|
| 6972 |
+
151278,
|
| 6973 |
+
151282,
|
| 6974 |
+
151366,
|
| 6975 |
+
151560
|
| 6976 |
+
],
|
| 6977 |
+
"bos_token": "<|im_start|>",
|
| 6978 |
+
"clean_up_tokenization_spaces": false,
|
| 6979 |
+
"eos_token": "<|im_end|>",
|
| 6980 |
+
"errors": "replace",
|
| 6981 |
+
"is_local": true,
|
| 6982 |
+
"model_max_length": 131072,
|
| 6983 |
+
"pad_token": "<|endoftext|>",
|
| 6984 |
+
"processor_class": "MiniCPMOProcessor",
|
| 6985 |
+
"split_special_tokens": false,
|
| 6986 |
+
"tokenizer_class": "Qwen2Tokenizer",
|
| 6987 |
+
"unk_token": "<unk>",
|
| 6988 |
+
"use_fast": true
|
| 6989 |
+
}
|
utils.py
ADDED
|
@@ -0,0 +1,2417 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python
|
| 2 |
+
# -*- coding: utf-8 -*-
|
| 3 |
+
# Copyright 2026 The OpenBMB Team. All rights reserved.
|
| 4 |
+
#
|
| 5 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 6 |
+
# you may not use this file except in compliance with the License.
|
| 7 |
+
# You may obtain a copy of the License at
|
| 8 |
+
#
|
| 9 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 10 |
+
#
|
| 11 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 12 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 13 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 14 |
+
# See the License for the specific language governing permissions and
|
| 15 |
+
# limitations under the License.
|
| 16 |
+
|
| 17 |
+
import logging
|
| 18 |
+
from dataclasses import dataclass
|
| 19 |
+
from typing import Any
|
| 20 |
+
from typing import Dict
|
| 21 |
+
from typing import List
|
| 22 |
+
from typing import Literal
|
| 23 |
+
from typing import Optional
|
| 24 |
+
from typing import Tuple
|
| 25 |
+
from typing import Union
|
| 26 |
+
|
| 27 |
+
import torch
|
| 28 |
+
import torch.nn.functional as F
|
| 29 |
+
import torch.nn.utils.parametrize as P
|
| 30 |
+
from transformers.cache_utils import DynamicCache
|
| 31 |
+
|
| 32 |
+
logger = logging.getLogger(__name__)
|
| 33 |
+
|
| 34 |
+
|
| 35 |
+
# text
|
| 36 |
+
@dataclass
|
| 37 |
+
class GenerateChunkOutput:
|
| 38 |
+
chunk_token_ids: torch.Tensor
|
| 39 |
+
current_inputs_embeds: torch.Tensor
|
| 40 |
+
input_last_hidden_states: Optional[torch.Tensor] # for tts use_speaker_embedding
|
| 41 |
+
last_hidden_states: Optional[torch.Tensor] # for tts input feature (projector_semantic)
|
| 42 |
+
past_key_values: Optional[torch.Tensor]
|
| 43 |
+
finished: bool
|
| 44 |
+
|
| 45 |
+
|
| 46 |
+
class ChunkPrefillChunkGenerate:
|
| 47 |
+
def __init__(self, model, tokenizer, terminators):
|
| 48 |
+
self.tokenizer = tokenizer
|
| 49 |
+
self.model = model
|
| 50 |
+
self.terminators = terminators
|
| 51 |
+
self.terminators_ids = [tokenizer.convert_tokens_to_ids(i) for i in self.terminators]
|
| 52 |
+
self.embedding_layer = self.model.get_input_embeddings()
|
| 53 |
+
|
| 54 |
+
self.forbidden_tokens = [
|
| 55 |
+
":",
|
| 56 |
+
":",
|
| 57 |
+
";",
|
| 58 |
+
"#",
|
| 59 |
+
"“",
|
| 60 |
+
"”",
|
| 61 |
+
"‘",
|
| 62 |
+
"’",
|
| 63 |
+
"@",
|
| 64 |
+
"*",
|
| 65 |
+
"【",
|
| 66 |
+
"】",
|
| 67 |
+
"「",
|
| 68 |
+
"」",
|
| 69 |
+
"(",
|
| 70 |
+
")",
|
| 71 |
+
"(",
|
| 72 |
+
")",
|
| 73 |
+
"[",
|
| 74 |
+
"]",
|
| 75 |
+
"&",
|
| 76 |
+
"/",
|
| 77 |
+
"$",
|
| 78 |
+
]
|
| 79 |
+
|
| 80 |
+
self.forbidden_token_ids = [tokenizer.convert_tokens_to_ids(i) for i in self.forbidden_tokens]
|
| 81 |
+
bad_token_ids = getattr(tokenizer, "bad_token_ids", [])
|
| 82 |
+
if bad_token_ids:
|
| 83 |
+
self.forbidden_token_ids.extend(bad_token_ids)
|
| 84 |
+
|
| 85 |
+
@staticmethod
|
| 86 |
+
def prepare_generation_config(do_sample, max_new_tokens=50, min_new_tokens=0, **kwargs):
|
| 87 |
+
num_beams = kwargs.get("num_beams", 3)
|
| 88 |
+
generation_config = {
|
| 89 |
+
"num_beams": num_beams,
|
| 90 |
+
"top_p": 0.8,
|
| 91 |
+
"top_k": 100,
|
| 92 |
+
"temperature": 0.7,
|
| 93 |
+
"do_sample": True,
|
| 94 |
+
"repetition_penalty": 1.05,
|
| 95 |
+
}
|
| 96 |
+
|
| 97 |
+
if do_sample:
|
| 98 |
+
generation_config.update(
|
| 99 |
+
{
|
| 100 |
+
"top_p": 0.8,
|
| 101 |
+
"top_k": 100,
|
| 102 |
+
"temperature": 0.7,
|
| 103 |
+
"do_sample": True,
|
| 104 |
+
"repetition_penalty": 1.05,
|
| 105 |
+
}
|
| 106 |
+
)
|
| 107 |
+
elif num_beams > 1:
|
| 108 |
+
generation_config.update({"num_beams": num_beams, "repetition_penalty": 1.2, "do_sample": False})
|
| 109 |
+
else:
|
| 110 |
+
generation_config.update({"do_sample": False, "repetition_penalty": 1.05})
|
| 111 |
+
|
| 112 |
+
generation_config.update((k, kwargs[k]) for k in generation_config.keys() & kwargs.keys())
|
| 113 |
+
generation_config["min_new_tokens"] = min_new_tokens
|
| 114 |
+
generation_config["max_new_tokens"] = max_new_tokens
|
| 115 |
+
|
| 116 |
+
return generation_config
|
| 117 |
+
|
| 118 |
+
def chunk_generate(
|
| 119 |
+
self,
|
| 120 |
+
inputs_embeds: torch.Tensor,
|
| 121 |
+
past_key_values,
|
| 122 |
+
is_first_generate_chunk: bool,
|
| 123 |
+
chunk_size: int,
|
| 124 |
+
return_hidden_states: bool,
|
| 125 |
+
do_sample: bool,
|
| 126 |
+
temperature: float,
|
| 127 |
+
top_p: float,
|
| 128 |
+
top_k: int,
|
| 129 |
+
repetition_penalty: float = 1.05,
|
| 130 |
+
length_penalty: float = 1.0,
|
| 131 |
+
all_input_ids: Optional[torch.Tensor] = None,
|
| 132 |
+
) -> GenerateChunkOutput:
|
| 133 |
+
"""
|
| 134 |
+
Args:
|
| 135 |
+
inputs_embeds: [1, seq_len, hidden_dim], Input embeddings of current chunk.
|
| 136 |
+
past_key_values: [num_layers, 2, batch_size, num_heads, seq_len, head_dim], Past key values for llm.
|
| 137 |
+
is_first_generate_chunk: bool, Whether this is the first generate chunk.
|
| 138 |
+
chunk_size: int, The size of the current chunk, default is 10, and it is fixed during training.
|
| 139 |
+
return_hidden_states: bool Whether to return the hidden states, default is True.
|
| 140 |
+
do_sample: bool Whether to sample from the model, default is True.
|
| 141 |
+
temperature: float The temperature for the model, default is 0.7.
|
| 142 |
+
top_p: float The top-p for the model, default is 0.8.
|
| 143 |
+
top_k: int The top-k for the model, default is 100.
|
| 144 |
+
repetition_penalty: float, The repetition penalty for the model, default is 1.05.
|
| 145 |
+
length_penalty: float, The length penalty for the model, default is 1.0. Higher value means more detailed generation.
|
| 146 |
+
all_input_ids: Optional[torch.Tensor], The input ids for the current chunk.
|
| 147 |
+
"""
|
| 148 |
+
|
| 149 |
+
finished = False
|
| 150 |
+
current_inputs_embeds = inputs_embeds.clone()
|
| 151 |
+
input_last_hidden_states = []
|
| 152 |
+
last_hidden_states = []
|
| 153 |
+
generated_tokens = []
|
| 154 |
+
|
| 155 |
+
for token_idx in range(chunk_size):
|
| 156 |
+
if is_first_generate_chunk and token_idx == 0:
|
| 157 |
+
# first generate chunk, prefill inputs_embeds
|
| 158 |
+
model_inputs = {
|
| 159 |
+
"inputs_embeds": current_inputs_embeds,
|
| 160 |
+
"past_key_values": past_key_values,
|
| 161 |
+
"use_cache": True,
|
| 162 |
+
"output_hidden_states": return_hidden_states,
|
| 163 |
+
}
|
| 164 |
+
else: # for all other cases: prefill the latest generated token
|
| 165 |
+
model_inputs = {
|
| 166 |
+
"inputs_embeds": current_inputs_embeds[:, -1:, :],
|
| 167 |
+
"past_key_values": past_key_values,
|
| 168 |
+
"use_cache": True,
|
| 169 |
+
"output_hidden_states": return_hidden_states,
|
| 170 |
+
}
|
| 171 |
+
|
| 172 |
+
with torch.no_grad():
|
| 173 |
+
outputs = self.model(**model_inputs)
|
| 174 |
+
|
| 175 |
+
# last token's logits
|
| 176 |
+
logits = outputs.logits[:, -1, :].to(copy=True, dtype=torch.float32, device=inputs_embeds.device)
|
| 177 |
+
|
| 178 |
+
# forbid specific tokens decoding = model.generate@suppress_tokens
|
| 179 |
+
if self.forbidden_token_ids:
|
| 180 |
+
logits[:, self.forbidden_token_ids] = float("-inf")
|
| 181 |
+
|
| 182 |
+
past_key_values = outputs.past_key_values
|
| 183 |
+
|
| 184 |
+
PENALTY_WINDOW_SIZE = 128
|
| 185 |
+
|
| 186 |
+
# apply repetition penalty
|
| 187 |
+
if repetition_penalty != 1.0:
|
| 188 |
+
# get token ids for repetition penalty
|
| 189 |
+
if all_input_ids is not None:
|
| 190 |
+
# use global input ids (including original input and generated part)
|
| 191 |
+
if len(generated_tokens) > 0:
|
| 192 |
+
generated_token_ids = torch.cat(generated_tokens, dim=1)
|
| 193 |
+
current_sequence = torch.cat(
|
| 194 |
+
[
|
| 195 |
+
all_input_ids[:, -PENALTY_WINDOW_SIZE:],
|
| 196 |
+
generated_token_ids,
|
| 197 |
+
],
|
| 198 |
+
dim=1,
|
| 199 |
+
)
|
| 200 |
+
else:
|
| 201 |
+
current_sequence = all_input_ids[:, -PENALTY_WINDOW_SIZE:]
|
| 202 |
+
unique_token_ids = torch.unique(current_sequence.squeeze(0))
|
| 203 |
+
elif len(generated_tokens) > 0:
|
| 204 |
+
# revert to original logic: only use generated tokens
|
| 205 |
+
generated_token_ids = torch.cat(generated_tokens, dim=1).squeeze(0)
|
| 206 |
+
unique_token_ids = torch.unique(generated_token_ids)
|
| 207 |
+
else:
|
| 208 |
+
unique_token_ids = torch.tensor([], dtype=torch.long, device=logits.device)
|
| 209 |
+
|
| 210 |
+
# apply repetition penalty
|
| 211 |
+
for token_id in unique_token_ids:
|
| 212 |
+
if logits[0, token_id] > 0:
|
| 213 |
+
logits[0, token_id] = logits[0, token_id] / repetition_penalty
|
| 214 |
+
else:
|
| 215 |
+
logits[0, token_id] = logits[0, token_id] * repetition_penalty
|
| 216 |
+
|
| 217 |
+
# apply length penalty, higher value means more detailed generation
|
| 218 |
+
if length_penalty != 1.0:
|
| 219 |
+
for eos_token_id in self.terminators_ids:
|
| 220 |
+
if logits[0, eos_token_id] > 0:
|
| 221 |
+
logits[0, eos_token_id] = logits[0, eos_token_id] / length_penalty
|
| 222 |
+
else:
|
| 223 |
+
logits[0, eos_token_id] = logits[0, eos_token_id] * length_penalty
|
| 224 |
+
|
| 225 |
+
# apply temperature
|
| 226 |
+
if temperature != 1.0:
|
| 227 |
+
logits = logits / temperature
|
| 228 |
+
|
| 229 |
+
if do_sample:
|
| 230 |
+
# Top-k filtering
|
| 231 |
+
if top_k > 0:
|
| 232 |
+
top_k_logits, top_k_indices = torch.topk(logits, min(top_k, logits.size(-1)))
|
| 233 |
+
logits_filtered = torch.full_like(logits, float("-inf"))
|
| 234 |
+
logits_filtered.scatter_(1, top_k_indices, top_k_logits)
|
| 235 |
+
logits = logits_filtered
|
| 236 |
+
|
| 237 |
+
# Top-p filtering
|
| 238 |
+
if top_p < 1.0:
|
| 239 |
+
sorted_logits, sorted_indices = torch.sort(logits, descending=True)
|
| 240 |
+
cumulative_probs = torch.cumsum(F.softmax(sorted_logits, dim=-1), dim=-1)
|
| 241 |
+
|
| 242 |
+
# remove tokens with cumulative probability greater than top_p
|
| 243 |
+
sorted_indices_to_remove = cumulative_probs > top_p
|
| 244 |
+
sorted_indices_to_remove[..., 1:] = sorted_indices_to_remove[..., :-1].clone()
|
| 245 |
+
sorted_indices_to_remove[..., 0] = 0
|
| 246 |
+
|
| 247 |
+
indices_to_remove = sorted_indices_to_remove.scatter(1, sorted_indices, sorted_indices_to_remove)
|
| 248 |
+
logits[indices_to_remove] = float("-inf")
|
| 249 |
+
|
| 250 |
+
# sampling
|
| 251 |
+
probs = F.softmax(logits, dim=-1)
|
| 252 |
+
next_token = torch.multinomial(probs, num_samples=1)
|
| 253 |
+
else:
|
| 254 |
+
next_token = torch.argmax(logits, dim=-1, keepdim=True)
|
| 255 |
+
|
| 256 |
+
if return_hidden_states:
|
| 257 |
+
if is_first_generate_chunk and token_idx == 0:
|
| 258 |
+
input_last_hidden_states.append(outputs.hidden_states[-1])
|
| 259 |
+
else:
|
| 260 |
+
last_hidden_states.append(outputs.hidden_states[-1])
|
| 261 |
+
|
| 262 |
+
# if terminator token, stop generating
|
| 263 |
+
if next_token.item() in self.terminators_ids:
|
| 264 |
+
finished = True
|
| 265 |
+
break
|
| 266 |
+
|
| 267 |
+
generated_tokens.append(next_token)
|
| 268 |
+
|
| 269 |
+
# convert new token to embeddings and concatenate
|
| 270 |
+
next_token_embed = self.embedding_layer(next_token)
|
| 271 |
+
|
| 272 |
+
# update inputs_embeds, add one
|
| 273 |
+
current_inputs_embeds = torch.cat([current_inputs_embeds, next_token_embed], dim=1)
|
| 274 |
+
|
| 275 |
+
if len(generated_tokens) > 0:
|
| 276 |
+
chunk_token_ids = torch.cat(generated_tokens, dim=1)
|
| 277 |
+
else:
|
| 278 |
+
# special case: if last chunk and first predict is eos token, return last token of previous chunk. return a tensor with shape (1, 0)
|
| 279 |
+
if finished:
|
| 280 |
+
chunk_token_ids = torch.zeros((1, 0), dtype=torch.long, device=current_inputs_embeds.device)
|
| 281 |
+
else:
|
| 282 |
+
raise Exception("this should not happen")
|
| 283 |
+
|
| 284 |
+
if len(last_hidden_states) > 0:
|
| 285 |
+
last_hidden_states = torch.cat(last_hidden_states, dim=1)
|
| 286 |
+
else:
|
| 287 |
+
# special case: if last chunk, return last token of previous chunk.
|
| 288 |
+
if finished:
|
| 289 |
+
last_hidden_states = torch.cat(last_hidden_states, dim=1)
|
| 290 |
+
else:
|
| 291 |
+
raise Exception("this should not happen")
|
| 292 |
+
|
| 293 |
+
if len(input_last_hidden_states) > 0:
|
| 294 |
+
input_last_hidden_states = torch.cat(input_last_hidden_states, dim=1)
|
| 295 |
+
else:
|
| 296 |
+
input_last_hidden_states = None
|
| 297 |
+
|
| 298 |
+
return GenerateChunkOutput(
|
| 299 |
+
chunk_token_ids=chunk_token_ids,
|
| 300 |
+
current_inputs_embeds=current_inputs_embeds,
|
| 301 |
+
input_last_hidden_states=input_last_hidden_states,
|
| 302 |
+
last_hidden_states=last_hidden_states,
|
| 303 |
+
past_key_values=past_key_values,
|
| 304 |
+
finished=finished,
|
| 305 |
+
)
|
| 306 |
+
|
| 307 |
+
|
| 308 |
+
def streaming_token_decoder(token_iterator, tokenizer, skip_special_tokens=False):
|
| 309 |
+
"""
|
| 310 |
+
Incrementally decode tokens from an iterator, handling partial multi-byte characters.
|
| 311 |
+
|
| 312 |
+
When streaming tokens, multi-byte characters (like Chinese) may be split across multiple
|
| 313 |
+
tokens. Decoding partial tokens results in replacement characters (U+FFFD). This function
|
| 314 |
+
buffers tokens and only yields complete characters.
|
| 315 |
+
|
| 316 |
+
Args:
|
| 317 |
+
token_iterator: An iterator yielding (token_ids, is_finished) tuples.
|
| 318 |
+
token_ids can be torch.Tensor or any iterable of integers.
|
| 319 |
+
tokenizer: The tokenizer to use for decoding.
|
| 320 |
+
skip_special_tokens: Whether to skip special tokens during decoding.
|
| 321 |
+
|
| 322 |
+
Yields:
|
| 323 |
+
(decoded_text, is_finished) tuples where decoded_text is the new text since last yield.
|
| 324 |
+
"""
|
| 325 |
+
accumulated_token_ids = []
|
| 326 |
+
yielded_text_len = 0
|
| 327 |
+
|
| 328 |
+
for token_ids, is_finished in token_iterator:
|
| 329 |
+
# Accumulate token IDs
|
| 330 |
+
if torch.is_tensor(token_ids):
|
| 331 |
+
accumulated_token_ids.extend(token_ids.reshape(-1).tolist())
|
| 332 |
+
else:
|
| 333 |
+
accumulated_token_ids.extend(list(token_ids) if hasattr(token_ids, "__iter__") else [token_ids])
|
| 334 |
+
|
| 335 |
+
# Decode all accumulated tokens
|
| 336 |
+
full_decoded = tokenizer.decode(accumulated_token_ids, skip_special_tokens=skip_special_tokens)
|
| 337 |
+
|
| 338 |
+
if is_finished:
|
| 339 |
+
# Final chunk - yield all remaining text
|
| 340 |
+
new_text = full_decoded[yielded_text_len:]
|
| 341 |
+
yield new_text, is_finished
|
| 342 |
+
else:
|
| 343 |
+
# Find safe prefix without incomplete multi-byte characters
|
| 344 |
+
# The replacement character '�' (U+FFFD) indicates incomplete decoding
|
| 345 |
+
new_text = full_decoded[yielded_text_len:]
|
| 346 |
+
|
| 347 |
+
# Hold back text ending with replacement character (incomplete UTF-8 sequence)
|
| 348 |
+
safe_end = len(new_text)
|
| 349 |
+
while safe_end > 0 and new_text[safe_end - 1] == "\ufffd":
|
| 350 |
+
safe_end -= 1
|
| 351 |
+
|
| 352 |
+
safe_text = new_text[:safe_end] if safe_end > 0 else ""
|
| 353 |
+
yielded_text_len += len(safe_text)
|
| 354 |
+
yield safe_text, is_finished
|
| 355 |
+
|
| 356 |
+
|
| 357 |
+
def torch_clone_recursive(obj):
|
| 358 |
+
"""Recursively clone nested containers of torch.Tensors.
|
| 359 |
+
|
| 360 |
+
Supported container types: dict, list, tuple. Non-container non-Tensor
|
| 361 |
+
objects are returned as-is.
|
| 362 |
+
"""
|
| 363 |
+
if torch.is_tensor(obj):
|
| 364 |
+
return obj.clone()
|
| 365 |
+
elif isinstance(obj, dict):
|
| 366 |
+
return {k: torch_clone_recursive(v) for k, v in obj.items()}
|
| 367 |
+
elif isinstance(obj, list):
|
| 368 |
+
return [torch_clone_recursive(v) for v in obj]
|
| 369 |
+
elif isinstance(obj, tuple):
|
| 370 |
+
return tuple(torch_clone_recursive(v) for v in obj)
|
| 371 |
+
else:
|
| 372 |
+
raise ValueError(f"Unsupported type: {type(obj)}")
|
| 373 |
+
|
| 374 |
+
|
| 375 |
+
def rotate_half(x: torch.Tensor) -> torch.Tensor:
|
| 376 |
+
"""Rotate half the hidden dims of the input for RoPE."""
|
| 377 |
+
dim = x.shape[-1]
|
| 378 |
+
x1 = x[..., : dim // 2]
|
| 379 |
+
x2 = x[..., dim // 2 :]
|
| 380 |
+
return torch.cat((-x2, x1), dim=-1)
|
| 381 |
+
|
| 382 |
+
|
| 383 |
+
@dataclass
|
| 384 |
+
class SpeculativeSnapshot:
|
| 385 |
+
"""Speculative snapshot for VAD speculative rollback.
|
| 386 |
+
|
| 387 |
+
Used in VAD speculative execution: creates a snapshot after streaming_prefill
|
| 388 |
+
and before streaming_generate. If speculation fails (user continues speaking),
|
| 389 |
+
the state can be restored to continue streaming_prefill.
|
| 390 |
+
|
| 391 |
+
Implementation:
|
| 392 |
+
- LLM KV Cache: only record length, restore by truncation (zero extra VRAM)
|
| 393 |
+
- Audio KV Cache: requires cloning, as generate sets it to None
|
| 394 |
+
- Mel processor: save full state snapshot (including buffer)
|
| 395 |
+
"""
|
| 396 |
+
|
| 397 |
+
# KV Cache length (for truncation recovery)
|
| 398 |
+
llm_cache_length: int
|
| 399 |
+
audio_cache_length: int
|
| 400 |
+
|
| 401 |
+
# session state
|
| 402 |
+
new_user_msg: bool
|
| 403 |
+
llm_generated: bool
|
| 404 |
+
llm_generate_completed: bool
|
| 405 |
+
|
| 406 |
+
# Round management
|
| 407 |
+
next_round_id: int
|
| 408 |
+
pending_round_id: Optional[int]
|
| 409 |
+
omni_chunk_history_length: int
|
| 410 |
+
|
| 411 |
+
# TTS state (requires cloning, but usually small)
|
| 412 |
+
tts_last_turn_tokens: Optional[torch.Tensor]
|
| 413 |
+
|
| 414 |
+
# Streaming processor state
|
| 415 |
+
audio_chunk_idx: int
|
| 416 |
+
|
| 417 |
+
# Mel processor state snapshot (including buffer)
|
| 418 |
+
mel_processor_snapshot: Optional[dict] = None
|
| 419 |
+
|
| 420 |
+
# Audio encoder KV cache (requires cloning to ensure determinism after recovery)
|
| 421 |
+
audio_past_key_values: Optional[tuple] = None
|
| 422 |
+
|
| 423 |
+
# timestamp (for debugging)
|
| 424 |
+
timestamp: float = 0.0
|
| 425 |
+
|
| 426 |
+
# debug field: for verifying correctness of recovery
|
| 427 |
+
llm_cache_checksum: Optional[float] = None # LLM KV Cache first layer K sum
|
| 428 |
+
audio_cache_checksum: Optional[float] = None # Audio KV Cache first layer K sum
|
| 429 |
+
mel_buffer_checksum: Optional[float] = None # Mel buffer sum
|
| 430 |
+
|
| 431 |
+
# RNG state (key: for ensuring determinism of dithering etc. after recovery)
|
| 432 |
+
rng_state_cpu: Optional[torch.Tensor] = None # torch CPU RNG state
|
| 433 |
+
rng_state_cuda: Optional[torch.Tensor] = None # torch CUDA RNG state (if on GPU)
|
| 434 |
+
|
| 435 |
+
def summary(self) -> str:
|
| 436 |
+
mel_buf_len = 0
|
| 437 |
+
if self.mel_processor_snapshot:
|
| 438 |
+
buf = self.mel_processor_snapshot.get("buffer")
|
| 439 |
+
if buf is not None:
|
| 440 |
+
mel_buf_len = len(buf)
|
| 441 |
+
return (
|
| 442 |
+
f"llm_cache={self.llm_cache_length}, "
|
| 443 |
+
f"audio_cache={self.audio_cache_length}, "
|
| 444 |
+
f"audio_chunk_idx={self.audio_chunk_idx}, "
|
| 445 |
+
f"mel_buffer={mel_buf_len}, "
|
| 446 |
+
f"history_len={self.omni_chunk_history_length}, "
|
| 447 |
+
f"new_user_msg={self.new_user_msg}, "
|
| 448 |
+
f"llm_generated={self.llm_generated}"
|
| 449 |
+
)
|
| 450 |
+
|
| 451 |
+
|
| 452 |
+
# tts
|
| 453 |
+
@dataclass
|
| 454 |
+
class TTSSamplingParams:
|
| 455 |
+
top_p: float = 0.85
|
| 456 |
+
min_p: float = 0.01
|
| 457 |
+
top_k: int = 25
|
| 458 |
+
repetition_penalty: float = 1.05
|
| 459 |
+
temperature: float = 0.8
|
| 460 |
+
win_size: int = 16
|
| 461 |
+
tau_r: float = 0.1
|
| 462 |
+
|
| 463 |
+
|
| 464 |
+
class TTSStreamingGenerator:
|
| 465 |
+
"""
|
| 466 |
+
Streaming generator for TTS that processes chunks and yields audio tokens in real-time.
|
| 467 |
+
|
| 468 |
+
Supported attention types:
|
| 469 |
+
- full_attention: Full attention, all tokens can attend to each other
|
| 470 |
+
- sliding_window: Sliding window attention, KV cache is truncated to fixed size (token_window_size)
|
| 471 |
+
- sliding_recompute: Sliding recompute, only keep previous chunk and recompute with current chunk
|
| 472 |
+
- reindex: Keep first chunk as sink, reindex sliding window positions via RoPE rotation
|
| 473 |
+
"""
|
| 474 |
+
|
| 475 |
+
def __init__(
|
| 476 |
+
self,
|
| 477 |
+
model,
|
| 478 |
+
temperature: float,
|
| 479 |
+
eos_token: Union[int, torch.Tensor],
|
| 480 |
+
chunk_size: int = 25, # s3tokenizer 1s = 25token
|
| 481 |
+
tts_last_turn_tokens: torch.Tensor = None,
|
| 482 |
+
logits_processors=None,
|
| 483 |
+
logits_warpers=None,
|
| 484 |
+
):
|
| 485 |
+
self.tts = model
|
| 486 |
+
self.device = model.device
|
| 487 |
+
self.temperature = torch.tensor([temperature], dtype=torch.float, device=self.device)
|
| 488 |
+
self.eos_token = (
|
| 489 |
+
torch.tensor(eos_token, device=self.device) if isinstance(eos_token, int) else eos_token.to(self.device)
|
| 490 |
+
)
|
| 491 |
+
|
| 492 |
+
self.num_vq = model.num_vq
|
| 493 |
+
self.num_audio_tokens = model.num_audio_tokens
|
| 494 |
+
self.recomputed_chunks = model.recomputed_chunks
|
| 495 |
+
self.emb_code = model.emb_code
|
| 496 |
+
self.head_code = model.head_code
|
| 497 |
+
|
| 498 |
+
# Attention type and window sizes
|
| 499 |
+
self.attention_type = model.attention_type # "full_attention", "sliding_window", "sliding_recompute", "reindex"
|
| 500 |
+
self.chunk_window_size = model.chunk_window_size # chunk-level window for sliding_recompute (default 2)
|
| 501 |
+
self.token_window_size = model.token_window_size # token-level window for sliding_window/reindex (default 300)
|
| 502 |
+
|
| 503 |
+
# RoPE config (for reindex mode)
|
| 504 |
+
self.rope_theta = model.model.config.rope_theta
|
| 505 |
+
self.head_dim = model.model.config.hidden_size // model.model.config.num_attention_heads
|
| 506 |
+
|
| 507 |
+
# Logits processors
|
| 508 |
+
self.logits_processors = logits_processors if logits_processors is not None else []
|
| 509 |
+
# Logits warpers (like TopP/TopK), separate from processors
|
| 510 |
+
self.logits_warpers = logits_warpers if logits_warpers is not None else []
|
| 511 |
+
|
| 512 |
+
# initialize state
|
| 513 |
+
self.past_key_values = None
|
| 514 |
+
self.text_start_pos = 0
|
| 515 |
+
self.idx = -1 # start from -1, become 0 when first called
|
| 516 |
+
self.all_conditions = []
|
| 517 |
+
self.all_generated_tokens = []
|
| 518 |
+
self.tts_last_turn_tokens = tts_last_turn_tokens
|
| 519 |
+
self.spk_emb = None
|
| 520 |
+
|
| 521 |
+
audio_bos = [self.tts.audio_bos_token_id]
|
| 522 |
+
audio_bos = torch.Tensor(audio_bos).to(self.tts.emb_text.weight.device, dtype=torch.long)
|
| 523 |
+
|
| 524 |
+
self.audio_bos_embeds = self.tts.emb_text(audio_bos).unsqueeze(0)
|
| 525 |
+
self.text_eos_embed = self.tts.emb_text(
|
| 526 |
+
torch.tensor(
|
| 527 |
+
[self.tts.config.text_eos_token_id],
|
| 528 |
+
device=self.tts.emb_text.weight.device,
|
| 529 |
+
dtype=torch.long,
|
| 530 |
+
)
|
| 531 |
+
).unsqueeze(0)
|
| 532 |
+
|
| 533 |
+
# buffer related, used to fill up chunk_size and yield to outside
|
| 534 |
+
self.chunk_size = chunk_size
|
| 535 |
+
self._token_buffer: List[torch.Tensor] = []
|
| 536 |
+
|
| 537 |
+
# Chunk info tracking for sliding_recompute and reindex
|
| 538 |
+
self._chunk_info: List[dict] = []
|
| 539 |
+
self._total_seq_len = 0
|
| 540 |
+
|
| 541 |
+
# Reindex mode: track sink (first chunk) length
|
| 542 |
+
self._sink_kv_len = 0
|
| 543 |
+
|
| 544 |
+
def _build_recompute_inputs(self, current_condition: torch.Tensor) -> torch.Tensor:
|
| 545 |
+
"""Build recompute inputs for sliding_recompute mode."""
|
| 546 |
+
if len(self._chunk_info) == 0:
|
| 547 |
+
return current_condition
|
| 548 |
+
|
| 549 |
+
prev_chunk = self._chunk_info[-1]
|
| 550 |
+
prev_condition = prev_chunk["condition"]
|
| 551 |
+
prev_audio_tokens = prev_chunk["audio_tokens"]
|
| 552 |
+
|
| 553 |
+
recompute_list = [prev_condition]
|
| 554 |
+
if len(prev_audio_tokens) > 0:
|
| 555 |
+
prev_audio_embeds = torch.cat([self.emb_code[0](tok) for tok in prev_audio_tokens], dim=1)
|
| 556 |
+
recompute_list.append(prev_audio_embeds)
|
| 557 |
+
|
| 558 |
+
recompute_list.append(current_condition)
|
| 559 |
+
return torch.cat(recompute_list, dim=1)
|
| 560 |
+
|
| 561 |
+
def _truncate_kv_cache_sliding_window(self):
|
| 562 |
+
"""Truncate KV cache for sliding_window mode."""
|
| 563 |
+
if self.past_key_values is None:
|
| 564 |
+
return
|
| 565 |
+
|
| 566 |
+
if hasattr(self.past_key_values, "get_seq_length"):
|
| 567 |
+
current_kv_len = self.past_key_values.get_seq_length()
|
| 568 |
+
else:
|
| 569 |
+
current_kv_len = self.past_key_values[0][0].shape[2]
|
| 570 |
+
|
| 571 |
+
if current_kv_len <= self.token_window_size:
|
| 572 |
+
return
|
| 573 |
+
|
| 574 |
+
new_cache = DynamicCache()
|
| 575 |
+
num_layers = (
|
| 576 |
+
len(self.past_key_values.key_cache)
|
| 577 |
+
if hasattr(self.past_key_values, "key_cache")
|
| 578 |
+
else len(self.past_key_values)
|
| 579 |
+
)
|
| 580 |
+
|
| 581 |
+
for layer_idx in range(num_layers):
|
| 582 |
+
if hasattr(self.past_key_values, "key_cache"):
|
| 583 |
+
key = self.past_key_values.key_cache[layer_idx][:, :, -self.token_window_size :, :]
|
| 584 |
+
value = self.past_key_values.value_cache[layer_idx][:, :, -self.token_window_size :, :]
|
| 585 |
+
else:
|
| 586 |
+
key = self.past_key_values[layer_idx][0][:, :, -self.token_window_size :, :]
|
| 587 |
+
value = self.past_key_values[layer_idx][1][:, :, -self.token_window_size :, :]
|
| 588 |
+
new_cache.update(key, value, layer_idx)
|
| 589 |
+
|
| 590 |
+
self.past_key_values = new_cache
|
| 591 |
+
|
| 592 |
+
@staticmethod
|
| 593 |
+
def _apply_rope_rotation(x: torch.Tensor, cos: torch.Tensor, sin: torch.Tensor) -> torch.Tensor:
|
| 594 |
+
"""Apply RoPE rotation to tensor."""
|
| 595 |
+
return x * cos + rotate_half(x) * sin
|
| 596 |
+
|
| 597 |
+
def _compute_rope_cos_sin(self, positions: torch.Tensor, device: torch.device, dtype: torch.dtype):
|
| 598 |
+
"""Compute RoPE cos and sin for given positions."""
|
| 599 |
+
dim_half = self.head_dim // 2
|
| 600 |
+
freq_seq = torch.arange(0, dim_half, dtype=torch.float32, device=device)
|
| 601 |
+
inv_freq = 1.0 / (self.rope_theta ** (freq_seq / dim_half))
|
| 602 |
+
|
| 603 |
+
# positions: [seq_len]
|
| 604 |
+
angles = positions.float().unsqueeze(-1) * inv_freq.unsqueeze(0) # [seq_len, dim_half]
|
| 605 |
+
angles = torch.cat([angles, angles], dim=-1) # [seq_len, head_dim]
|
| 606 |
+
|
| 607 |
+
cos = angles.cos().to(dtype)
|
| 608 |
+
sin = angles.sin().to(dtype)
|
| 609 |
+
return cos, sin
|
| 610 |
+
|
| 611 |
+
def _reindex_kv_cache(self):
|
| 612 |
+
"""
|
| 613 |
+
Reindex KV cache for reindex mode:
|
| 614 |
+
1. Keep first chunk as attention sink
|
| 615 |
+
2. Keep last chunk
|
| 616 |
+
3. Discard middle chunks
|
| 617 |
+
4. Reindex the last chunk's key positions to be right after sink via RoPE rotation
|
| 618 |
+
"""
|
| 619 |
+
if self.past_key_values is None or len(self._chunk_info) < 2:
|
| 620 |
+
return
|
| 621 |
+
|
| 622 |
+
# Get current KV cache length
|
| 623 |
+
if hasattr(self.past_key_values, "get_seq_length"):
|
| 624 |
+
current_kv_len = self.past_key_values.get_seq_length()
|
| 625 |
+
else:
|
| 626 |
+
current_kv_len = self.past_key_values[0][0].shape[2]
|
| 627 |
+
|
| 628 |
+
# Calculate sink length (first chunk)
|
| 629 |
+
sink_len = self._chunk_info[0]["condition_len"] + self._chunk_info[0]["audio_token_count"]
|
| 630 |
+
|
| 631 |
+
# Last chunk length
|
| 632 |
+
last_chunk = self._chunk_info[-1]
|
| 633 |
+
last_chunk_len = last_chunk["condition_len"] + last_chunk["audio_token_count"]
|
| 634 |
+
|
| 635 |
+
keep_len = sink_len + last_chunk_len
|
| 636 |
+
|
| 637 |
+
# Get device and dtype
|
| 638 |
+
device = self.past_key_values.key_cache[0].device
|
| 639 |
+
dtype = self.past_key_values.key_cache[0].dtype
|
| 640 |
+
|
| 641 |
+
if current_kv_len <= keep_len:
|
| 642 |
+
last_chunk_kv_len = current_kv_len - sink_len
|
| 643 |
+
if last_chunk_kv_len <= 0:
|
| 644 |
+
return
|
| 645 |
+
self.text_start_pos = current_kv_len
|
| 646 |
+
return
|
| 647 |
+
|
| 648 |
+
# Step 1: Truncate KV cache - keep sink and last chunk
|
| 649 |
+
new_cache = DynamicCache()
|
| 650 |
+
num_layers = len(self.past_key_values.key_cache)
|
| 651 |
+
|
| 652 |
+
original_start_pos = current_kv_len - last_chunk_len
|
| 653 |
+
new_start_pos = sink_len
|
| 654 |
+
delta = new_start_pos - original_start_pos # This is a scalar constant
|
| 655 |
+
delta_positions = torch.full((last_chunk_len,), delta, dtype=torch.float32, device=device)
|
| 656 |
+
|
| 657 |
+
# Compute rotation cos/sin
|
| 658 |
+
cos, sin = self._compute_rope_cos_sin(delta_positions, device, dtype)
|
| 659 |
+
cos = cos.unsqueeze(0).unsqueeze(0) # [1, 1, seq_len, head_dim]
|
| 660 |
+
sin = sin.unsqueeze(0).unsqueeze(0)
|
| 661 |
+
|
| 662 |
+
for layer_idx in range(num_layers):
|
| 663 |
+
key_full = self.past_key_values.key_cache[layer_idx]
|
| 664 |
+
value_full = self.past_key_values.value_cache[layer_idx]
|
| 665 |
+
|
| 666 |
+
# Extract sink and last chunk
|
| 667 |
+
key_sink = key_full[:, :, :sink_len, :]
|
| 668 |
+
value_sink = value_full[:, :, :sink_len, :]
|
| 669 |
+
key_last = key_full[:, :, -last_chunk_len:, :]
|
| 670 |
+
value_last = value_full[:, :, -last_chunk_len:, :]
|
| 671 |
+
|
| 672 |
+
# Apply RoPE rotation to reindex key positions
|
| 673 |
+
key_last_reindexed = self._apply_rope_rotation(key_last, cos, sin)
|
| 674 |
+
|
| 675 |
+
# Concatenate sink and reindexed last chunk
|
| 676 |
+
key = torch.cat([key_sink, key_last_reindexed], dim=2)
|
| 677 |
+
value = torch.cat([value_sink, value_last], dim=2)
|
| 678 |
+
|
| 679 |
+
new_cache.update(key, value, layer_idx)
|
| 680 |
+
|
| 681 |
+
self.past_key_values = new_cache
|
| 682 |
+
|
| 683 |
+
# Update text_start_pos to reflect new positions
|
| 684 |
+
self.text_start_pos = sink_len + last_chunk_len
|
| 685 |
+
|
| 686 |
+
@torch.inference_mode()
|
| 687 |
+
def generate_with_buffer(
|
| 688 |
+
self,
|
| 689 |
+
condition: torch.Tensor,
|
| 690 |
+
text_finished: bool = False,
|
| 691 |
+
max_new_token: int = 500,
|
| 692 |
+
):
|
| 693 |
+
"""input a condition embedding chunk, generate audio token each time,
|
| 694 |
+
and accumulate to buffer, only yield when buffer satisfies chunk_size.
|
| 695 |
+
|
| 696 |
+
Yields:
|
| 697 |
+
torch.Tensor of shape [chunk_size] (2D: [1, chunk_size])
|
| 698 |
+
"""
|
| 699 |
+
self.idx += 1
|
| 700 |
+
self.device = self.tts.device
|
| 701 |
+
|
| 702 |
+
# if text finished, first concatenate Text EOS
|
| 703 |
+
if text_finished:
|
| 704 |
+
condition = torch.cat([condition, self.text_eos_embed], dim=1)
|
| 705 |
+
|
| 706 |
+
# always concatenate Audio BOS
|
| 707 |
+
condition = torch.cat([condition, self.audio_bos_embeds], dim=1).to(self.device)
|
| 708 |
+
|
| 709 |
+
self.all_conditions.append(condition)
|
| 710 |
+
|
| 711 |
+
# Initialize current chunk info
|
| 712 |
+
current_chunk_info = {
|
| 713 |
+
"condition_len": condition.shape[1],
|
| 714 |
+
"audio_token_count": 0,
|
| 715 |
+
"condition": condition.clone(),
|
| 716 |
+
"audio_tokens": [],
|
| 717 |
+
}
|
| 718 |
+
|
| 719 |
+
# Handle different attention types
|
| 720 |
+
if self.attention_type == "sliding_recompute" and self.idx >= 1:
|
| 721 |
+
# sliding_recompute: discard KV cache, recompute with previous + current chunk
|
| 722 |
+
self.past_key_values = None
|
| 723 |
+
current_condition = self._build_recompute_inputs(condition)
|
| 724 |
+
self.text_start_pos = 0
|
| 725 |
+
elif self.attention_type == "reindex" and self.idx >= 1:
|
| 726 |
+
# reindex: truncate KV cache keeping sink + last chunk, reindex positions via RoPE
|
| 727 |
+
self._reindex_kv_cache()
|
| 728 |
+
current_condition = condition
|
| 729 |
+
# Always update text_start_pos based on actual KV cache length (like reference code)
|
| 730 |
+
if self.past_key_values is not None:
|
| 731 |
+
if hasattr(self.past_key_values, "get_seq_length"):
|
| 732 |
+
kv_len = self.past_key_values.get_seq_length()
|
| 733 |
+
else:
|
| 734 |
+
kv_len = self.past_key_values[0][0].shape[2]
|
| 735 |
+
self.text_start_pos = kv_len
|
| 736 |
+
else:
|
| 737 |
+
current_condition = condition
|
| 738 |
+
|
| 739 |
+
condition_length = current_condition.shape[1]
|
| 740 |
+
prefill_len = condition_length
|
| 741 |
+
finished = torch.zeros(1, dtype=torch.bool, device=self.device)
|
| 742 |
+
chunk_generated_tokens = []
|
| 743 |
+
|
| 744 |
+
for t in range(max_new_token):
|
| 745 |
+
if t == 0:
|
| 746 |
+
inputs_embeds = current_condition
|
| 747 |
+
pos_ids = torch.arange(
|
| 748 |
+
self.text_start_pos,
|
| 749 |
+
self.text_start_pos + condition_length,
|
| 750 |
+
dtype=torch.long,
|
| 751 |
+
device=self.device,
|
| 752 |
+
).unsqueeze(0)
|
| 753 |
+
else:
|
| 754 |
+
last = self.all_generated_tokens[-1]
|
| 755 |
+
# last: [1,1], directly as code id
|
| 756 |
+
inputs_embeds = self.emb_code[0](last)
|
| 757 |
+
pos_ids = torch.tensor(
|
| 758 |
+
[self.text_start_pos + prefill_len + t - 1],
|
| 759 |
+
dtype=torch.long,
|
| 760 |
+
device=self.device,
|
| 761 |
+
).unsqueeze(0)
|
| 762 |
+
|
| 763 |
+
outputs = self.tts.model(
|
| 764 |
+
position_ids=pos_ids,
|
| 765 |
+
past_key_values=self.past_key_values,
|
| 766 |
+
inputs_embeds=inputs_embeds,
|
| 767 |
+
use_cache=True,
|
| 768 |
+
)
|
| 769 |
+
hidden_states = outputs.last_hidden_state
|
| 770 |
+
|
| 771 |
+
# Handle KV cache based on attention type
|
| 772 |
+
if self.attention_type == "sliding_window":
|
| 773 |
+
self.past_key_values = outputs.past_key_values
|
| 774 |
+
self._truncate_kv_cache_sliding_window()
|
| 775 |
+
else:
|
| 776 |
+
self.past_key_values = outputs.past_key_values
|
| 777 |
+
|
| 778 |
+
with P.cached():
|
| 779 |
+
logits = torch.empty(
|
| 780 |
+
hidden_states.size(0),
|
| 781 |
+
hidden_states.size(1),
|
| 782 |
+
self.num_audio_tokens,
|
| 783 |
+
self.num_vq,
|
| 784 |
+
dtype=torch.float,
|
| 785 |
+
device=self.device,
|
| 786 |
+
)
|
| 787 |
+
for num_vq_iter in range(self.num_vq):
|
| 788 |
+
x: torch.Tensor = self.head_code[num_vq_iter](hidden_states)
|
| 789 |
+
logits[..., num_vq_iter] = x
|
| 790 |
+
del x
|
| 791 |
+
|
| 792 |
+
del hidden_states
|
| 793 |
+
|
| 794 |
+
logits = logits[:, -1].float()
|
| 795 |
+
|
| 796 |
+
logits = logits.permute(0, 2, 1)
|
| 797 |
+
logits = logits.reshape(-1, logits.size(2))
|
| 798 |
+
|
| 799 |
+
logits /= self.temperature
|
| 800 |
+
|
| 801 |
+
audio_bos = len(self.all_generated_tokens) == 0 and t == 0
|
| 802 |
+
|
| 803 |
+
if not audio_bos:
|
| 804 |
+
# use generated tokens (current chunk) as input for processor/warper (align with modeling_minicpmo)
|
| 805 |
+
all_generated_tokens = torch.cat(self.all_generated_tokens, dim=1).to(self.device) # [1, T]
|
| 806 |
+
for processor in self.logits_processors:
|
| 807 |
+
logits = processor(all_generated_tokens, logits)
|
| 808 |
+
|
| 809 |
+
for warper in self.logits_warpers:
|
| 810 |
+
logits = warper(all_generated_tokens, logits)
|
| 811 |
+
del all_generated_tokens
|
| 812 |
+
|
| 813 |
+
# sample next token (only use first codebook, same as generate)
|
| 814 |
+
scores = F.softmax(logits, dim=-1)
|
| 815 |
+
idx_next = torch.multinomial(scores, num_samples=1) # [(B*num_vq), 1]
|
| 816 |
+
next_id = idx_next.view(-1, self.num_vq)[:, 0:1] # only take first codebook → [B, 1]
|
| 817 |
+
del scores
|
| 818 |
+
|
| 819 |
+
if next_id.eq(
|
| 820 |
+
self.eos_token
|
| 821 |
+
).any(): # generated audio eos token, means this chunk is finished, no longer generate new tokens
|
| 822 |
+
finished[:] = True
|
| 823 |
+
else: # eos token cannot be added to buffer, he does not speak.
|
| 824 |
+
# convert next_id to correct shape [1, 1], no num_vq dimension
|
| 825 |
+
if next_id.dim() == 0: # if scalar
|
| 826 |
+
next_tok = next_id.unsqueeze(0).unsqueeze(0) # [1, 1]
|
| 827 |
+
elif next_id.dim() == 1: # if 1D [1]
|
| 828 |
+
next_tok = next_id.unsqueeze(0) # [1, 1]
|
| 829 |
+
else:
|
| 830 |
+
next_tok = next_id
|
| 831 |
+
|
| 832 |
+
self.all_generated_tokens.append(next_tok)
|
| 833 |
+
chunk_generated_tokens.append(next_tok)
|
| 834 |
+
|
| 835 |
+
# Update chunk info for sliding_recompute
|
| 836 |
+
current_chunk_info["audio_tokens"].append(next_tok.clone())
|
| 837 |
+
current_chunk_info["audio_token_count"] += 1
|
| 838 |
+
|
| 839 |
+
self._token_buffer.append(next_tok)
|
| 840 |
+
|
| 841 |
+
if len(self._token_buffer) == 0:
|
| 842 |
+
# case 1: if last text chunk, yield None
|
| 843 |
+
if text_finished:
|
| 844 |
+
yield torch.empty(1, 0, dtype=torch.long, device=self.device), True
|
| 845 |
+
break
|
| 846 |
+
# case 2: if not last text chunk, break directly
|
| 847 |
+
else:
|
| 848 |
+
break
|
| 849 |
+
else: # buffer has something
|
| 850 |
+
# case 1: if buffer is larger/equal to chunk_size, yield out
|
| 851 |
+
if len(self._token_buffer) >= self.chunk_size:
|
| 852 |
+
batch = torch.cat(self._token_buffer[: self.chunk_size], dim=1) # [1, chunk_size]
|
| 853 |
+
yield batch, False # → [1, chunk_size]
|
| 854 |
+
# discard yielded part
|
| 855 |
+
self._token_buffer = self._token_buffer[self.chunk_size :]
|
| 856 |
+
|
| 857 |
+
# case 2: if buffer is smaller than chunk_size
|
| 858 |
+
else:
|
| 859 |
+
# if generation finished, and is the last text chunk, yield all remaining tokens, then break
|
| 860 |
+
if finished.all():
|
| 861 |
+
if text_finished:
|
| 862 |
+
batch = torch.cat(self._token_buffer, dim=1) # [1, chunk_size]
|
| 863 |
+
yield batch, True # → [1, chunk_size]
|
| 864 |
+
self._token_buffer = []
|
| 865 |
+
break
|
| 866 |
+
else:
|
| 867 |
+
# not the last text chunk, need to wait for next text chunk to fill up buffer, then this call ends
|
| 868 |
+
break
|
| 869 |
+
else: # generation of this audio chunk is not finished, continue generating
|
| 870 |
+
continue
|
| 871 |
+
|
| 872 |
+
# Save current chunk info for sliding_recompute and reindex
|
| 873 |
+
self._chunk_info.append(current_chunk_info)
|
| 874 |
+
self._total_seq_len += condition.shape[1] + len(chunk_generated_tokens)
|
| 875 |
+
|
| 876 |
+
# Update text_start_pos based on attention type
|
| 877 |
+
if self.attention_type == "sliding_recompute":
|
| 878 |
+
# sliding_recompute: will be reset at next chunk start, update normally here
|
| 879 |
+
self.text_start_pos += prefill_len + len(chunk_generated_tokens)
|
| 880 |
+
elif self.attention_type == "reindex":
|
| 881 |
+
# reindex: position based on actual KV cache length (positions have been reindexed to be continuous)
|
| 882 |
+
if self.past_key_values is not None:
|
| 883 |
+
if hasattr(self.past_key_values, "get_seq_length"):
|
| 884 |
+
self.text_start_pos = self.past_key_values.get_seq_length()
|
| 885 |
+
else:
|
| 886 |
+
self.text_start_pos = self.past_key_values[0][0].shape[2]
|
| 887 |
+
else:
|
| 888 |
+
self.text_start_pos += condition.shape[1] + len(chunk_generated_tokens)
|
| 889 |
+
else:
|
| 890 |
+
self.text_start_pos += condition.shape[1] + len(chunk_generated_tokens)
|
| 891 |
+
# note: remaining tokens in buffer will be kept, and accumulated next time
|
| 892 |
+
|
| 893 |
+
|
| 894 |
+
# sliding window
|
| 895 |
+
@dataclass
|
| 896 |
+
class StreamingWindowConfig:
|
| 897 |
+
text_window_high_tokens: int = 8000
|
| 898 |
+
text_window_low_tokens: int = 6000
|
| 899 |
+
|
| 900 |
+
|
| 901 |
+
@dataclass
|
| 902 |
+
class DuplexWindowConfig:
|
| 903 |
+
"""duplex sliding window configuration
|
| 904 |
+
|
| 905 |
+
sliding window mode:
|
| 906 |
+
- "off": disable sliding window
|
| 907 |
+
- "basic": basic sliding window (trigger by cache length)
|
| 908 |
+
- "context": sliding window with context (trigger by unit number, preserve generated text to previous)
|
| 909 |
+
"""
|
| 910 |
+
|
| 911 |
+
# sliding window mode
|
| 912 |
+
sliding_window_mode: str = "off" # "off" / "basic" / "context"
|
| 913 |
+
|
| 914 |
+
# basic sliding window parameters
|
| 915 |
+
basic_window_high_tokens: int = 8000 # high watermark: trigger sliding window when exceeded
|
| 916 |
+
basic_window_low_tokens: int = 6000 # low watermark: keep to this value after sliding window
|
| 917 |
+
|
| 918 |
+
# context sliding window parameters
|
| 919 |
+
context_previous_max_tokens: int = 500 # previous maximum token number
|
| 920 |
+
context_max_units: int = 24 # maximum unit number (trigger sliding window when exceeded)
|
| 921 |
+
|
| 922 |
+
# verification mode (for comparison test)
|
| 923 |
+
verify_mode: bool = False # whether to enable verification log
|
| 924 |
+
|
| 925 |
+
|
| 926 |
+
def as_dynamic_cache(past_key_values):
|
| 927 |
+
"""Convert legacy tuple cache to DynamicCache if needed."""
|
| 928 |
+
if isinstance(past_key_values, DynamicCache):
|
| 929 |
+
return past_key_values
|
| 930 |
+
|
| 931 |
+
if isinstance(past_key_values, tuple):
|
| 932 |
+
return DynamicCache.from_legacy_cache(past_key_values)
|
| 933 |
+
|
| 934 |
+
return past_key_values
|
| 935 |
+
|
| 936 |
+
|
| 937 |
+
def get_kv_cache_length(cache) -> int:
|
| 938 |
+
"""Get the sequence length of a KV cache.
|
| 939 |
+
|
| 940 |
+
Args:
|
| 941 |
+
cache: DynamicCache or tuple-based cache
|
| 942 |
+
|
| 943 |
+
Returns:
|
| 944 |
+
The number of tokens in the cache
|
| 945 |
+
"""
|
| 946 |
+
if cache is None:
|
| 947 |
+
return 0
|
| 948 |
+
|
| 949 |
+
if isinstance(cache, DynamicCache):
|
| 950 |
+
if not cache.key_cache or not cache.key_cache[0].numel():
|
| 951 |
+
return 0
|
| 952 |
+
return cache.key_cache[0].shape[-2]
|
| 953 |
+
|
| 954 |
+
if isinstance(cache, tuple):
|
| 955 |
+
return cache[0][0].shape[2]
|
| 956 |
+
|
| 957 |
+
return 0
|
| 958 |
+
|
| 959 |
+
|
| 960 |
+
def get_rotary_cos_sin(
|
| 961 |
+
head_dim: int,
|
| 962 |
+
positions: torch.Tensor,
|
| 963 |
+
device: torch.device,
|
| 964 |
+
dtype: torch.dtype,
|
| 965 |
+
rope_theta: float = 10000.0,
|
| 966 |
+
inv_freq_cache: Optional[Dict[Tuple, torch.Tensor]] = None,
|
| 967 |
+
) -> Tuple[torch.Tensor, torch.Tensor]:
|
| 968 |
+
"""Compute RoPE cos and sin components for given positions.
|
| 969 |
+
|
| 970 |
+
Args:
|
| 971 |
+
head_dim: Dimension of each attention head
|
| 972 |
+
positions: Position indices tensor
|
| 973 |
+
device: Target device
|
| 974 |
+
dtype: Target dtype
|
| 975 |
+
rope_theta: RoPE base frequency (default 10000.0)
|
| 976 |
+
inv_freq_cache: Optional cache dict for inverse frequencies
|
| 977 |
+
|
| 978 |
+
Returns:
|
| 979 |
+
Tuple of (cos, sin) tensors with shape [1, 1, seq_len, head_dim]
|
| 980 |
+
"""
|
| 981 |
+
cache_key = (head_dim, device)
|
| 982 |
+
|
| 983 |
+
inv_freq = inv_freq_cache.get(cache_key) if inv_freq_cache is not None else None
|
| 984 |
+
if inv_freq is None or inv_freq.device != device or inv_freq.shape[0] != head_dim // 2:
|
| 985 |
+
exponent = torch.arange(0, head_dim, 2, device=device, dtype=torch.float32) / head_dim
|
| 986 |
+
inv_freq = 1.0 / (rope_theta**exponent)
|
| 987 |
+
if inv_freq_cache is not None:
|
| 988 |
+
inv_freq_cache[cache_key] = inv_freq
|
| 989 |
+
|
| 990 |
+
positions = positions.to(device=device, dtype=torch.float32)
|
| 991 |
+
angles = torch.einsum("i,j->ij", positions, inv_freq)
|
| 992 |
+
cos = torch.cos(angles)
|
| 993 |
+
sin = torch.sin(angles)
|
| 994 |
+
|
| 995 |
+
# Use cat instead of repeat_interleave, consistent with model's original RotaryEmbedding
|
| 996 |
+
# Original: emb = torch.cat((freqs, freqs), dim=-1) -> [f0, f1, ..., f_{d/2}, f0, f1, ..., f_{d/2}]
|
| 997 |
+
cos_full = torch.cat([cos, cos], dim=-1).to(dtype=dtype)
|
| 998 |
+
sin_full = torch.cat([sin, sin], dim=-1).to(dtype=dtype)
|
| 999 |
+
cos_full = cos_full.unsqueeze(0).unsqueeze(0)
|
| 1000 |
+
sin_full = sin_full.unsqueeze(0).unsqueeze(0)
|
| 1001 |
+
return cos_full, sin_full
|
| 1002 |
+
|
| 1003 |
+
|
| 1004 |
+
def realign_rotary_suffix(
|
| 1005 |
+
suffix_keys: torch.Tensor,
|
| 1006 |
+
old_positions: torch.Tensor,
|
| 1007 |
+
new_positions: torch.Tensor,
|
| 1008 |
+
rope_theta: float = 10000.0,
|
| 1009 |
+
inv_freq_cache: Optional[Dict[Tuple, torch.Tensor]] = None,
|
| 1010 |
+
) -> torch.Tensor:
|
| 1011 |
+
"""Realign RoPE position encoding after cache eviction.
|
| 1012 |
+
|
| 1013 |
+
When tokens are dropped from the middle of a cache, the suffix tokens
|
| 1014 |
+
need their RoPE embeddings recalculated with new position indices.
|
| 1015 |
+
|
| 1016 |
+
Args:
|
| 1017 |
+
suffix_keys: Key tensor to realign, shape [batch, heads, seq_len, head_dim]
|
| 1018 |
+
old_positions: Original position indices
|
| 1019 |
+
new_positions: New position indices after eviction
|
| 1020 |
+
rope_theta: RoPE base frequency
|
| 1021 |
+
inv_freq_cache: Optional cache dict for inverse frequencies
|
| 1022 |
+
|
| 1023 |
+
Returns:
|
| 1024 |
+
Realigned key tensor with same shape as input
|
| 1025 |
+
"""
|
| 1026 |
+
if suffix_keys.numel() == 0:
|
| 1027 |
+
return suffix_keys
|
| 1028 |
+
|
| 1029 |
+
head_dim = suffix_keys.shape[-1]
|
| 1030 |
+
device = suffix_keys.device
|
| 1031 |
+
dtype = suffix_keys.dtype
|
| 1032 |
+
|
| 1033 |
+
# Compute old position cos/sin
|
| 1034 |
+
cos_old, sin_old = get_rotary_cos_sin(head_dim, old_positions, device, dtype, rope_theta, inv_freq_cache)
|
| 1035 |
+
|
| 1036 |
+
# Inverse transform: recover original key
|
| 1037 |
+
base = cos_old * suffix_keys - sin_old * rotate_half(suffix_keys)
|
| 1038 |
+
|
| 1039 |
+
# Compute new position cos/sin
|
| 1040 |
+
cos_new, sin_new = get_rotary_cos_sin(head_dim, new_positions, device, dtype, rope_theta, inv_freq_cache)
|
| 1041 |
+
|
| 1042 |
+
# Forward transform: re-encode with new positions
|
| 1043 |
+
return cos_new * base + sin_new * rotate_half(base)
|
| 1044 |
+
|
| 1045 |
+
|
| 1046 |
+
def drop_tokens_from_cache(
|
| 1047 |
+
cache: Optional[DynamicCache | Tuple],
|
| 1048 |
+
length: int,
|
| 1049 |
+
preserve: int,
|
| 1050 |
+
position_offset: int,
|
| 1051 |
+
rope_theta: float = 10000.0,
|
| 1052 |
+
inv_freq_cache: Optional[Dict[Tuple, torch.Tensor]] = None,
|
| 1053 |
+
) -> Tuple[Optional[DynamicCache], int, bool]:
|
| 1054 |
+
"""Drop tokens from a KV cache while preserving system prompt.
|
| 1055 |
+
|
| 1056 |
+
Removes tokens in the range [preserve, preserve + length) from the cache,
|
| 1057 |
+
realigning RoPE embeddings for the suffix.
|
| 1058 |
+
|
| 1059 |
+
Args:
|
| 1060 |
+
cache: DynamicCache or tuple-based cache (will be converted to DynamicCache)
|
| 1061 |
+
length: Number of tokens to drop
|
| 1062 |
+
preserve: Number of tokens to preserve at the start (system prompt)
|
| 1063 |
+
position_offset: Current position offset for RoPE calculation
|
| 1064 |
+
rope_theta: RoPE base frequency
|
| 1065 |
+
inv_freq_cache: Optional cache dict for inverse frequencies
|
| 1066 |
+
|
| 1067 |
+
Returns:
|
| 1068 |
+
Tuple of (cache, new_position_offset, success)
|
| 1069 |
+
Note: Tuple cache will be converted to DynamicCache. Modification is in-place.
|
| 1070 |
+
"""
|
| 1071 |
+
if cache is None or length <= 0:
|
| 1072 |
+
return cache, position_offset, False
|
| 1073 |
+
|
| 1074 |
+
cache = as_dynamic_cache(cache)
|
| 1075 |
+
|
| 1076 |
+
total_len = get_kv_cache_length(cache)
|
| 1077 |
+
if total_len <= 0:
|
| 1078 |
+
return cache, position_offset, False
|
| 1079 |
+
|
| 1080 |
+
preserve = min(preserve, total_len)
|
| 1081 |
+
available = total_len - preserve
|
| 1082 |
+
|
| 1083 |
+
if available < length:
|
| 1084 |
+
logger.warning(
|
| 1085 |
+
"Cannot drop %d tokens: only %d available (total=%d, preserve=%d)",
|
| 1086 |
+
length,
|
| 1087 |
+
available,
|
| 1088 |
+
total_len,
|
| 1089 |
+
preserve,
|
| 1090 |
+
)
|
| 1091 |
+
return cache, position_offset, False
|
| 1092 |
+
|
| 1093 |
+
suffix_len = total_len - preserve - length
|
| 1094 |
+
# note: after RoPE reindex, the position of cache has been compressed (from preserve start)
|
| 1095 |
+
# so here should not add position_offset, but use the actual layout of current cache
|
| 1096 |
+
suffix_offset = preserve + length # suffix current position in cache
|
| 1097 |
+
prefix_offset = preserve # suffix new position (follow preserve)
|
| 1098 |
+
|
| 1099 |
+
# Prepare position tensors for RoPE realignment
|
| 1100 |
+
old_positions = None
|
| 1101 |
+
new_positions = None
|
| 1102 |
+
if suffix_len > 0:
|
| 1103 |
+
device = cache.key_cache[0].device
|
| 1104 |
+
old_positions = torch.arange(
|
| 1105 |
+
suffix_offset,
|
| 1106 |
+
suffix_offset + suffix_len,
|
| 1107 |
+
device=device,
|
| 1108 |
+
dtype=torch.long,
|
| 1109 |
+
)
|
| 1110 |
+
new_positions = torch.arange(
|
| 1111 |
+
prefix_offset,
|
| 1112 |
+
prefix_offset + suffix_len,
|
| 1113 |
+
device=device,
|
| 1114 |
+
dtype=torch.long,
|
| 1115 |
+
)
|
| 1116 |
+
|
| 1117 |
+
keep_len = total_len - length
|
| 1118 |
+
|
| 1119 |
+
# Process each layer (in-place modification)
|
| 1120 |
+
for layer_idx in range(len(cache.key_cache)):
|
| 1121 |
+
key_tensor = cache.key_cache[layer_idx]
|
| 1122 |
+
value_tensor = cache.value_cache[layer_idx]
|
| 1123 |
+
|
| 1124 |
+
if not key_tensor.numel():
|
| 1125 |
+
continue
|
| 1126 |
+
|
| 1127 |
+
# Preserve prefix (system prompt)
|
| 1128 |
+
prefix_keys = key_tensor[:, :, :preserve, :]
|
| 1129 |
+
prefix_values = value_tensor[:, :, :preserve, :]
|
| 1130 |
+
|
| 1131 |
+
if suffix_len > 0:
|
| 1132 |
+
# Keep and realign suffix
|
| 1133 |
+
suffix_keys = key_tensor[:, :, preserve + length :, :]
|
| 1134 |
+
suffix_values = value_tensor[:, :, preserve + length :, :]
|
| 1135 |
+
|
| 1136 |
+
if old_positions is not None and new_positions is not None and suffix_keys.numel():
|
| 1137 |
+
suffix_keys = realign_rotary_suffix(
|
| 1138 |
+
suffix_keys,
|
| 1139 |
+
old_positions,
|
| 1140 |
+
new_positions,
|
| 1141 |
+
rope_theta,
|
| 1142 |
+
inv_freq_cache,
|
| 1143 |
+
)
|
| 1144 |
+
|
| 1145 |
+
cache.key_cache[layer_idx] = torch.cat([prefix_keys, suffix_keys], dim=-2).contiguous()
|
| 1146 |
+
cache.value_cache[layer_idx] = torch.cat([prefix_values, suffix_values], dim=-2).contiguous()
|
| 1147 |
+
else:
|
| 1148 |
+
cache.key_cache[layer_idx] = prefix_keys.contiguous()
|
| 1149 |
+
cache.value_cache[layer_idx] = prefix_values.contiguous()
|
| 1150 |
+
|
| 1151 |
+
cache.crop(keep_len)
|
| 1152 |
+
cache._seen_tokens = max(keep_len, 0)
|
| 1153 |
+
|
| 1154 |
+
new_offset = position_offset + length
|
| 1155 |
+
logger.debug("Dropped %d tokens from cache, new length=%d", length, keep_len)
|
| 1156 |
+
|
| 1157 |
+
return cache, new_offset, True
|
| 1158 |
+
|
| 1159 |
+
|
| 1160 |
+
# stream decoder
|
| 1161 |
+
def top_k_top_p_filtering(logits, top_k=0, top_p=0.0, filter_value=-float("inf")):
|
| 1162 |
+
logits = logits.clone()
|
| 1163 |
+
|
| 1164 |
+
# Top-k filtering
|
| 1165 |
+
if top_k > 0:
|
| 1166 |
+
top_k = min(top_k, logits.size(-1))
|
| 1167 |
+
indices_to_remove = logits < torch.topk(logits, top_k)[0][..., -1, None]
|
| 1168 |
+
logits[indices_to_remove] = filter_value
|
| 1169 |
+
|
| 1170 |
+
# Top-p (nucleus) filtering
|
| 1171 |
+
if top_p > 0.0:
|
| 1172 |
+
sorted_logits, sorted_indices = torch.sort(logits, descending=True)
|
| 1173 |
+
probs = F.softmax(sorted_logits, dim=-1)
|
| 1174 |
+
cumulative_probs = torch.cumsum(probs, dim=-1)
|
| 1175 |
+
|
| 1176 |
+
sorted_indices_to_remove = cumulative_probs > top_p
|
| 1177 |
+
# keep the first token that exceeds top_p
|
| 1178 |
+
sorted_indices_to_remove[..., 1:] = sorted_indices_to_remove[..., :-1].clone()
|
| 1179 |
+
sorted_indices_to_remove[..., 0] = 0
|
| 1180 |
+
|
| 1181 |
+
indices_to_remove = sorted_indices[sorted_indices_to_remove]
|
| 1182 |
+
logits[0, indices_to_remove] = filter_value
|
| 1183 |
+
|
| 1184 |
+
return logits
|
| 1185 |
+
|
| 1186 |
+
|
| 1187 |
+
class StreamDecoder:
|
| 1188 |
+
def __init__(self, llm, tokenizer, special_token_ids=None, forbidden_token_ids=None):
|
| 1189 |
+
self.m = llm
|
| 1190 |
+
self.tokenizer = tokenizer
|
| 1191 |
+
self.listen_id = self.tokenizer.eos_token_id
|
| 1192 |
+
|
| 1193 |
+
self.chunk_eos_id = self.tokenizer.convert_tokens_to_ids("<|chunk_eos|>")
|
| 1194 |
+
self.chunk_tts_eos_id = self.tokenizer.convert_tokens_to_ids("<|chunk_tts_eos|>")
|
| 1195 |
+
self.turn_eos_id = self.tokenizer.convert_tokens_to_ids("<|turn_eos|>")
|
| 1196 |
+
self.speak_id = self.tokenizer.convert_tokens_to_ids("<|speak|>")
|
| 1197 |
+
|
| 1198 |
+
self.special_token_ids = special_token_ids if special_token_ids is not None else []
|
| 1199 |
+
|
| 1200 |
+
# cache special tokens (used for context sliding window filtering)
|
| 1201 |
+
self._all_special_ids = set()
|
| 1202 |
+
self._all_special_tokens_text = set()
|
| 1203 |
+
if self.tokenizer:
|
| 1204 |
+
if hasattr(self.tokenizer, "all_special_ids"):
|
| 1205 |
+
self._all_special_ids = set(self.tokenizer.all_special_ids)
|
| 1206 |
+
if hasattr(self.tokenizer, "all_special_tokens"):
|
| 1207 |
+
self._all_special_tokens_text = set(self.tokenizer.all_special_tokens)
|
| 1208 |
+
|
| 1209 |
+
custom_special_tokens = [
|
| 1210 |
+
"<unit>",
|
| 1211 |
+
"</unit>",
|
| 1212 |
+
"<image>",
|
| 1213 |
+
"</image>",
|
| 1214 |
+
"<slice>",
|
| 1215 |
+
"</slice>",
|
| 1216 |
+
"<|listen|>",
|
| 1217 |
+
"<|speak|>",
|
| 1218 |
+
"<|tts_bos|>",
|
| 1219 |
+
"<|tts_eos|>",
|
| 1220 |
+
"<|audio_start|>",
|
| 1221 |
+
"<|audio_end|>",
|
| 1222 |
+
"<|chunk_eos|>",
|
| 1223 |
+
"<|chunk_tts_eos|>",
|
| 1224 |
+
"<|turn_eos|>",
|
| 1225 |
+
"<|audio_start|>",
|
| 1226 |
+
"<|audio_end|>",
|
| 1227 |
+
]
|
| 1228 |
+
self._all_special_tokens_text.update(custom_special_tokens)
|
| 1229 |
+
for token in custom_special_tokens:
|
| 1230 |
+
token_id = self.tokenizer.convert_tokens_to_ids(token)
|
| 1231 |
+
if token_id is not None and token_id != self.tokenizer.unk_token_id:
|
| 1232 |
+
self._all_special_ids.add(token_id)
|
| 1233 |
+
|
| 1234 |
+
if forbidden_token_ids is None:
|
| 1235 |
+
self.forbidden_token_ids = []
|
| 1236 |
+
elif isinstance(forbidden_token_ids, int):
|
| 1237 |
+
self.forbidden_token_ids = [self.forbidden_token_ids]
|
| 1238 |
+
else:
|
| 1239 |
+
self.forbidden_token_ids = forbidden_token_ids
|
| 1240 |
+
self.forbidden_token_ids.append(self.chunk_eos_id)
|
| 1241 |
+
|
| 1242 |
+
assert isinstance(self.forbidden_token_ids, list)
|
| 1243 |
+
|
| 1244 |
+
self.cache = None
|
| 1245 |
+
self.context = ""
|
| 1246 |
+
self.generated_tokens = [] # track generated tokens
|
| 1247 |
+
self.generated_special_tokens = [] # track generated special tokens
|
| 1248 |
+
self.reset()
|
| 1249 |
+
self.embeds = None
|
| 1250 |
+
self.system_embeds = None
|
| 1251 |
+
|
| 1252 |
+
# sliding window related states
|
| 1253 |
+
self._unit_history: List[Dict[str, Any]] = []
|
| 1254 |
+
self._next_unit_id: int = 0
|
| 1255 |
+
self._pending_unit_id: Optional[int] = None
|
| 1256 |
+
self._pending_unit_start_cache_len: int = 0
|
| 1257 |
+
self._system_preserve_length: int = 0
|
| 1258 |
+
self._position_offset: int = 0
|
| 1259 |
+
self._window_config = DuplexWindowConfig()
|
| 1260 |
+
self._window_enabled: bool = True
|
| 1261 |
+
self._rope_inv_freq_cache: Dict[Tuple, torch.Tensor] = {}
|
| 1262 |
+
|
| 1263 |
+
# context preserving sliding window states
|
| 1264 |
+
# initial cache layout: [prefix] [suffix] [units...]
|
| 1265 |
+
# after first sliding window: [prefix] [previous_marker + content] [suffix] [units...]
|
| 1266 |
+
# fixed dynamic sliding region fixed
|
| 1267 |
+
self._preserve_prefix_length: int = 0 # original prefix length (fixed)
|
| 1268 |
+
self._previous_content_length: int = 0 # previous content length (dynamic, including marker)
|
| 1269 |
+
self._suffix_token_ids: List[int] = [] # suffix token ids (e.g. <|im_end|>)
|
| 1270 |
+
|
| 1271 |
+
# previous marker (added dynamically after first sliding window)
|
| 1272 |
+
self._previous_marker: str = "\n\nprevious: " # fixed prefix marker
|
| 1273 |
+
self._previous_marker_token_ids: List[int] = [] # marker token ids (initialized)
|
| 1274 |
+
self._has_previous: bool = False # whether previous marker has been added
|
| 1275 |
+
|
| 1276 |
+
# previous content
|
| 1277 |
+
self._previous_text: str = "" # accumulated generated text (without marker)
|
| 1278 |
+
self._previous_token_ids: List[int] = [] # previous full token ids (including marker)
|
| 1279 |
+
|
| 1280 |
+
# validation statistics
|
| 1281 |
+
self._sliding_event_count: int = 0 # sliding window trigger count
|
| 1282 |
+
self._total_dropped_tokens: int = 0 # total dropped token count
|
| 1283 |
+
self._total_dropped_units: int = 0 # total dropped unit count
|
| 1284 |
+
|
| 1285 |
+
def sliding_embeds(self):
|
| 1286 |
+
# tmp = system_embeds
|
| 1287 |
+
# tmp +-》 embeds after 5s
|
| 1288 |
+
# reset
|
| 1289 |
+
# feed
|
| 1290 |
+
pass
|
| 1291 |
+
|
| 1292 |
+
def reset(self):
|
| 1293 |
+
self.context = ""
|
| 1294 |
+
self.cache = None
|
| 1295 |
+
self.generated_tokens = []
|
| 1296 |
+
self.generated_special_tokens = []
|
| 1297 |
+
self.embeds = None
|
| 1298 |
+
self.system_embeds = None
|
| 1299 |
+
|
| 1300 |
+
# sliding window state reset
|
| 1301 |
+
old_unit_count = len(self._unit_history) if hasattr(self, "_unit_history") else 0
|
| 1302 |
+
self._unit_history = []
|
| 1303 |
+
self._next_unit_id = 0
|
| 1304 |
+
self._pending_unit_id = None
|
| 1305 |
+
self._pending_unit_start_cache_len = 0
|
| 1306 |
+
self._system_preserve_length = 0
|
| 1307 |
+
self._position_offset = 0
|
| 1308 |
+
self._rope_inv_freq_cache = {}
|
| 1309 |
+
|
| 1310 |
+
# context preserving sliding window state reset
|
| 1311 |
+
self._preserve_prefix_length = 0
|
| 1312 |
+
self._previous_content_length = 0
|
| 1313 |
+
self._suffix_token_ids = []
|
| 1314 |
+
self._previous_marker = "\n\nprevious: "
|
| 1315 |
+
self._previous_marker_token_ids = []
|
| 1316 |
+
self._has_previous = False
|
| 1317 |
+
self._previous_text = ""
|
| 1318 |
+
self._previous_token_ids = []
|
| 1319 |
+
|
| 1320 |
+
# validation statistics
|
| 1321 |
+
self._sliding_event_count = 0 # sliding window trigger count
|
| 1322 |
+
self._total_dropped_tokens = 0 # total dropped token count
|
| 1323 |
+
self._total_dropped_units = 0 # total dropped unit count
|
| 1324 |
+
|
| 1325 |
+
def get_cache_length(self) -> int:
|
| 1326 |
+
if self.cache is None:
|
| 1327 |
+
return 0
|
| 1328 |
+
if isinstance(self.cache, DynamicCache):
|
| 1329 |
+
if len(self.cache.key_cache) > 0 and self.cache.key_cache[0].numel() > 0:
|
| 1330 |
+
return self.cache.key_cache[0].shape[2]
|
| 1331 |
+
return 0
|
| 1332 |
+
# Tuple cache format
|
| 1333 |
+
return self.cache[0][0].shape[2]
|
| 1334 |
+
|
| 1335 |
+
def get_total_generated_tokens(self) -> int:
|
| 1336 |
+
return sum(len(u.get("generated_tokens", [])) for u in self._unit_history)
|
| 1337 |
+
|
| 1338 |
+
def register_unit_start(self) -> int:
|
| 1339 |
+
self._pending_unit_id = self._next_unit_id
|
| 1340 |
+
self._pending_unit_start_cache_len = self.get_cache_length()
|
| 1341 |
+
return self._pending_unit_id
|
| 1342 |
+
|
| 1343 |
+
def register_unit_end(
|
| 1344 |
+
self,
|
| 1345 |
+
input_type: str,
|
| 1346 |
+
generated_tokens: Optional[List[int]] = None,
|
| 1347 |
+
is_listen: bool = False,
|
| 1348 |
+
generated_text: Optional[str] = None,
|
| 1349 |
+
):
|
| 1350 |
+
"""Call when unit ends, record unit information
|
| 1351 |
+
|
| 1352 |
+
Should be called after feeding </unit> token
|
| 1353 |
+
|
| 1354 |
+
Args:
|
| 1355 |
+
input_type: "audio" / "video" / "omni" / "system"
|
| 1356 |
+
generated_tokens: tokens generated by the unit (token ids)
|
| 1357 |
+
is_listen: whether the unit is in listen state
|
| 1358 |
+
generated_text: text generated by the unit (used for context preserving mode)
|
| 1359 |
+
"""
|
| 1360 |
+
if self._pending_unit_id is None:
|
| 1361 |
+
logger.warning("register_unit_end called without register_unit_start")
|
| 1362 |
+
return
|
| 1363 |
+
|
| 1364 |
+
# calculate the length of the unit
|
| 1365 |
+
current_cache_len = self.get_cache_length()
|
| 1366 |
+
unit_len = current_cache_len - self._pending_unit_start_cache_len
|
| 1367 |
+
|
| 1368 |
+
if unit_len > 0:
|
| 1369 |
+
entry = {
|
| 1370 |
+
"unit_id": self._pending_unit_id,
|
| 1371 |
+
"length": unit_len,
|
| 1372 |
+
"type": input_type,
|
| 1373 |
+
"generated_tokens": generated_tokens or [],
|
| 1374 |
+
"generated_text": generated_text or "", # used for context preserving mode
|
| 1375 |
+
"is_listen": is_listen,
|
| 1376 |
+
}
|
| 1377 |
+
self._unit_history.append(entry)
|
| 1378 |
+
|
| 1379 |
+
self._pending_unit_id = None
|
| 1380 |
+
self._pending_unit_start_cache_len = 0
|
| 1381 |
+
self._next_unit_id += 1
|
| 1382 |
+
|
| 1383 |
+
def register_system_prompt(self):
|
| 1384 |
+
"""Call after system prompt prefill, record preserve length"""
|
| 1385 |
+
self._system_preserve_length = self.get_cache_length()
|
| 1386 |
+
|
| 1387 |
+
# sliding window core methods
|
| 1388 |
+
|
| 1389 |
+
def _get_rope_theta(self) -> float:
|
| 1390 |
+
"""get model rope_theta configuration"""
|
| 1391 |
+
return float(getattr(self.m.config, "rope_theta", 10000.0))
|
| 1392 |
+
|
| 1393 |
+
def _drop_tokens_from_cache(self, length: int) -> bool:
|
| 1394 |
+
"""remove specified number of tokens from cache (protect system prompt)
|
| 1395 |
+
|
| 1396 |
+
remove tokens in the range [preserve, preserve + length)
|
| 1397 |
+
supports DynamicCache and tuple cache formats
|
| 1398 |
+
"""
|
| 1399 |
+
if self.cache is None or length <= 0:
|
| 1400 |
+
return False
|
| 1401 |
+
|
| 1402 |
+
cache_type = "DynamicCache" if isinstance(self.cache, DynamicCache) else "TupleCache"
|
| 1403 |
+
cache_len_before = self.get_cache_length()
|
| 1404 |
+
offset_before = self._position_offset
|
| 1405 |
+
|
| 1406 |
+
new_cache, new_offset, success = drop_tokens_from_cache(
|
| 1407 |
+
cache=self.cache,
|
| 1408 |
+
length=length,
|
| 1409 |
+
preserve=self._system_preserve_length,
|
| 1410 |
+
position_offset=self._position_offset,
|
| 1411 |
+
rope_theta=self._get_rope_theta(),
|
| 1412 |
+
inv_freq_cache=self._rope_inv_freq_cache,
|
| 1413 |
+
)
|
| 1414 |
+
if success:
|
| 1415 |
+
self.cache = new_cache # For DynamicCache this is the same object (in-place)
|
| 1416 |
+
self._position_offset = new_offset
|
| 1417 |
+
|
| 1418 |
+
return success
|
| 1419 |
+
|
| 1420 |
+
def _drop_unit(self, unit_id: int) -> bool:
|
| 1421 |
+
"""remove specified unit"""
|
| 1422 |
+
entries = [u for u in self._unit_history if u["unit_id"] == unit_id]
|
| 1423 |
+
if not entries:
|
| 1424 |
+
return False
|
| 1425 |
+
|
| 1426 |
+
total_len = sum(e["length"] for e in entries)
|
| 1427 |
+
if total_len <= 0:
|
| 1428 |
+
for e in entries:
|
| 1429 |
+
self._unit_history.remove(e)
|
| 1430 |
+
return False
|
| 1431 |
+
|
| 1432 |
+
if not self._drop_tokens_from_cache(total_len):
|
| 1433 |
+
return False
|
| 1434 |
+
|
| 1435 |
+
for e in entries:
|
| 1436 |
+
self._unit_history.remove(e)
|
| 1437 |
+
|
| 1438 |
+
return True
|
| 1439 |
+
|
| 1440 |
+
def _drop_next_unit(self) -> bool:
|
| 1441 |
+
"""remove the earliest non-system unit"""
|
| 1442 |
+
for entry in self._unit_history:
|
| 1443 |
+
unit_id = entry.get("unit_id")
|
| 1444 |
+
if unit_id is None:
|
| 1445 |
+
continue
|
| 1446 |
+
# skip system type
|
| 1447 |
+
if entry.get("type") == "system":
|
| 1448 |
+
continue
|
| 1449 |
+
if self._drop_unit(unit_id):
|
| 1450 |
+
return True
|
| 1451 |
+
return False
|
| 1452 |
+
|
| 1453 |
+
def enforce_window(self) -> bool:
|
| 1454 |
+
"""enforce sliding window strategy (same as single-mode, only look at cache length)
|
| 1455 |
+
|
| 1456 |
+
when cache length exceeds high water line, loop to remove the earliest unit,
|
| 1457 |
+
until cache length drops below the low water line.
|
| 1458 |
+
"""
|
| 1459 |
+
if not self._window_enabled:
|
| 1460 |
+
return False
|
| 1461 |
+
|
| 1462 |
+
cfg = self._window_config
|
| 1463 |
+
cache_len_before = self.get_cache_length()
|
| 1464 |
+
|
| 1465 |
+
if cache_len_before <= cfg.basic_window_high_tokens:
|
| 1466 |
+
return False # not above high water line, no trigger
|
| 1467 |
+
|
| 1468 |
+
dropped_count = 0
|
| 1469 |
+
cache_len = cache_len_before
|
| 1470 |
+
while cache_len > cfg.basic_window_low_tokens:
|
| 1471 |
+
if not self._drop_next_unit():
|
| 1472 |
+
break
|
| 1473 |
+
dropped_count += 1
|
| 1474 |
+
cache_len = self.get_cache_length()
|
| 1475 |
+
|
| 1476 |
+
if dropped_count > 0:
|
| 1477 |
+
# update statistics counters
|
| 1478 |
+
self._sliding_event_count += 1
|
| 1479 |
+
self._total_dropped_tokens += cache_len_before - cache_len
|
| 1480 |
+
self._total_dropped_units += dropped_count
|
| 1481 |
+
|
| 1482 |
+
# consistency check
|
| 1483 |
+
expected = self._system_preserve_length + sum(u["length"] for u in self._unit_history)
|
| 1484 |
+
is_consistent = expected == cache_len
|
| 1485 |
+
if not is_consistent:
|
| 1486 |
+
logger.error(
|
| 1487 |
+
"CONSISTENCY ERROR! preserve=%d + sum(units)=%d != cache=%d, offset=%d",
|
| 1488 |
+
self._system_preserve_length,
|
| 1489 |
+
sum(u["length"] for u in self._unit_history),
|
| 1490 |
+
cache_len,
|
| 1491 |
+
self._position_offset,
|
| 1492 |
+
)
|
| 1493 |
+
|
| 1494 |
+
return dropped_count > 0
|
| 1495 |
+
|
| 1496 |
+
# context preserving sliding window methods
|
| 1497 |
+
|
| 1498 |
+
def register_system_prompt_with_context(
|
| 1499 |
+
self,
|
| 1500 |
+
suffix_token_ids: Optional[List[int]] = None,
|
| 1501 |
+
context_previous_marker: str = "\n\nprevious: ",
|
| 1502 |
+
):
|
| 1503 |
+
"""register system prompt (with context preserving mode)
|
| 1504 |
+
|
| 1505 |
+
initial cache layout: [prefix] [suffix] [units...]
|
| 1506 |
+
after first sliding window: [prefix] [context_previous_marker + content] [suffix] [units...]
|
| 1507 |
+
|
| 1508 |
+
when calling this method, cache should only have prefix (without previous marker)
|
| 1509 |
+
suffix will be fed in later
|
| 1510 |
+
|
| 1511 |
+
Args:
|
| 1512 |
+
suffix_token_ids: suffix token ids (e.g. id of <|im_end|>)
|
| 1513 |
+
context_previous_marker: previous marker prefix, e.g. "\\n\\nprevious: "
|
| 1514 |
+
"""
|
| 1515 |
+
# prefix = current cache content (fixed, without previous marker)
|
| 1516 |
+
self._preserve_prefix_length = self.get_cache_length()
|
| 1517 |
+
self._previous_content_length = 0 # initially no previous content
|
| 1518 |
+
self._suffix_token_ids = suffix_token_ids or []
|
| 1519 |
+
# total preserve length = prefix + suffix (initially no previous)
|
| 1520 |
+
self._system_preserve_length = self._preserve_prefix_length + len(self._suffix_token_ids)
|
| 1521 |
+
|
| 1522 |
+
# initialize previous related states
|
| 1523 |
+
self._previous_marker = context_previous_marker
|
| 1524 |
+
self._previous_marker_token_ids = (
|
| 1525 |
+
self.tokenizer.encode(context_previous_marker, add_special_tokens=False) if self.tokenizer else []
|
| 1526 |
+
)
|
| 1527 |
+
self._has_previous = False
|
| 1528 |
+
self._previous_text = ""
|
| 1529 |
+
self._previous_token_ids = []
|
| 1530 |
+
|
| 1531 |
+
def _extract_generated_text(self, units: List[Dict[str, Any]]) -> Tuple[str, List[int]]:
|
| 1532 |
+
"""extract generated text and token ids from units
|
| 1533 |
+
|
| 1534 |
+
Args:
|
| 1535 |
+
units: list of units to extract
|
| 1536 |
+
|
| 1537 |
+
Returns:
|
| 1538 |
+
(text, token_ids): concatenated text and token ids (filtered out special tokens)
|
| 1539 |
+
"""
|
| 1540 |
+
text_parts = []
|
| 1541 |
+
token_ids = []
|
| 1542 |
+
|
| 1543 |
+
for u in units:
|
| 1544 |
+
# only keep generated content of non-listen units
|
| 1545 |
+
if u.get("is_listen", False):
|
| 1546 |
+
continue
|
| 1547 |
+
gen_text = u.get("generated_text", "")
|
| 1548 |
+
gen_tokens = u.get("generated_tokens", [])
|
| 1549 |
+
|
| 1550 |
+
# filter out special tokens from text
|
| 1551 |
+
if gen_text:
|
| 1552 |
+
clean_text = gen_text
|
| 1553 |
+
for st in self._all_special_tokens_text:
|
| 1554 |
+
clean_text = clean_text.replace(st, "")
|
| 1555 |
+
if clean_text.strip():
|
| 1556 |
+
text_parts.append(clean_text)
|
| 1557 |
+
|
| 1558 |
+
# filter out special tokens
|
| 1559 |
+
if gen_tokens:
|
| 1560 |
+
filtered_tokens = [t for t in gen_tokens if t not in self._all_special_ids]
|
| 1561 |
+
token_ids.extend(filtered_tokens)
|
| 1562 |
+
|
| 1563 |
+
return "".join(text_parts), token_ids
|
| 1564 |
+
|
| 1565 |
+
def _rebuild_cache_with_previous(
|
| 1566 |
+
self,
|
| 1567 |
+
new_previous_tokens: List[int],
|
| 1568 |
+
units_to_keep_len: Optional[int] = None,
|
| 1569 |
+
) -> bool:
|
| 1570 |
+
"""rebuild cache, insert new previous content between prefix and suffix
|
| 1571 |
+
|
| 1572 |
+
cache layout change:
|
| 1573 |
+
[prefix] [old_prev] [suffix] [old_units] → [prefix] [new_prev] [suffix] [remaining_units]
|
| 1574 |
+
|
| 1575 |
+
Args:
|
| 1576 |
+
new_previous_tokens: new previous token ids
|
| 1577 |
+
units_to_keep_len: length of units to keep (from cache end backwards)
|
| 1578 |
+
if None, calculate based on unit_history
|
| 1579 |
+
|
| 1580 |
+
Returns:
|
| 1581 |
+
whether successful rebuild
|
| 1582 |
+
"""
|
| 1583 |
+
if self.cache is None:
|
| 1584 |
+
return False
|
| 1585 |
+
|
| 1586 |
+
old_previous_len = self._previous_content_length
|
| 1587 |
+
new_previous_len = len(new_previous_tokens)
|
| 1588 |
+
suffix_len = len(self._suffix_token_ids)
|
| 1589 |
+
total_cache_len = self.get_cache_length()
|
| 1590 |
+
|
| 1591 |
+
# calculate length of units to keep
|
| 1592 |
+
if units_to_keep_len is None:
|
| 1593 |
+
units_to_keep_len = sum(u["length"] for u in self._unit_history)
|
| 1594 |
+
|
| 1595 |
+
# special case: if previous is unchanged (new and old are empty), no need to rebuild prefix+suffix part of cache
|
| 1596 |
+
# but still need to reindex units RoPE (because a unit was deleted, position changed)
|
| 1597 |
+
if new_previous_len == 0 and old_previous_len == 0:
|
| 1598 |
+
# cache layout: [prefix(7)] [suffix(1)] [units...]
|
| 1599 |
+
# only keep prefix + suffix + remaining_units
|
| 1600 |
+
preserve_len = self._preserve_prefix_length + suffix_len
|
| 1601 |
+
|
| 1602 |
+
# simply slice cache: [prefix+suffix] + [remaining_units]
|
| 1603 |
+
# remaining_units in cache end
|
| 1604 |
+
if units_to_keep_len > 0:
|
| 1605 |
+
# [0:preserve_len] + [total-units_to_keep_len:total]
|
| 1606 |
+
prefix_suffix_cache = self._slice_cache(0, preserve_len)
|
| 1607 |
+
units_cache = self._slice_cache(total_cache_len - units_to_keep_len, None)
|
| 1608 |
+
|
| 1609 |
+
# calculate number of dropped tokens
|
| 1610 |
+
dropped_tokens = total_cache_len - preserve_len - units_to_keep_len
|
| 1611 |
+
|
| 1612 |
+
# reindex units RoPE: position from (preserve_len + dropped_tokens) to preserve_len
|
| 1613 |
+
# note: no position_offset, because cache position has been compressed (from 0 start)
|
| 1614 |
+
if dropped_tokens > 0:
|
| 1615 |
+
old_start = preserve_len + dropped_tokens
|
| 1616 |
+
new_start = preserve_len
|
| 1617 |
+
units_cache = self._reindex_rope_for_cache(units_cache, old_start, new_start, units_to_keep_len)
|
| 1618 |
+
|
| 1619 |
+
self.cache = self._concat_caches(prefix_suffix_cache, units_cache)
|
| 1620 |
+
else:
|
| 1621 |
+
self.cache = self._slice_cache(0, preserve_len)
|
| 1622 |
+
|
| 1623 |
+
return True
|
| 1624 |
+
|
| 1625 |
+
# 1. get prefix cache (fixed)
|
| 1626 |
+
prefix_end = self._preserve_prefix_length
|
| 1627 |
+
prefix_cache = self._slice_cache(0, prefix_end)
|
| 1628 |
+
|
| 1629 |
+
# 2. get units cache to keep (from end)
|
| 1630 |
+
units_start_in_old_cache = total_cache_len - units_to_keep_len
|
| 1631 |
+
units_cache = None
|
| 1632 |
+
if units_to_keep_len > 0:
|
| 1633 |
+
units_cache = self._slice_cache(units_start_in_old_cache, None)
|
| 1634 |
+
|
| 1635 |
+
# 3. calculate new previous + suffix cache (needs forward)
|
| 1636 |
+
# merge previous tokens and suffix tokens
|
| 1637 |
+
prev_suffix_tokens = new_previous_tokens + self._suffix_token_ids
|
| 1638 |
+
prev_suffix_len = len(prev_suffix_tokens)
|
| 1639 |
+
|
| 1640 |
+
new_prefix_prev_suffix_cache = prefix_cache
|
| 1641 |
+
if prev_suffix_len > 0:
|
| 1642 |
+
# Embed tokens
|
| 1643 |
+
prev_suffix_embeds = self.embed_tokens(prev_suffix_tokens)
|
| 1644 |
+
# calculate start position (after prefix)
|
| 1645 |
+
start_pos = self._preserve_prefix_length + self._position_offset
|
| 1646 |
+
|
| 1647 |
+
# forward calculate KV cache
|
| 1648 |
+
with torch.no_grad():
|
| 1649 |
+
device = prev_suffix_embeds.device
|
| 1650 |
+
position_ids = torch.arange(
|
| 1651 |
+
start_pos,
|
| 1652 |
+
start_pos + prev_suffix_len,
|
| 1653 |
+
device=device,
|
| 1654 |
+
).unsqueeze(0)
|
| 1655 |
+
|
| 1656 |
+
# use prefix cache as past_key_values
|
| 1657 |
+
outputs = self.m(
|
| 1658 |
+
inputs_embeds=(
|
| 1659 |
+
prev_suffix_embeds.unsqueeze(0) if prev_suffix_embeds.dim() == 2 else prev_suffix_embeds
|
| 1660 |
+
),
|
| 1661 |
+
position_ids=position_ids,
|
| 1662 |
+
past_key_values=prefix_cache,
|
| 1663 |
+
use_cache=True,
|
| 1664 |
+
return_dict=True,
|
| 1665 |
+
)
|
| 1666 |
+
# new cache contains prefix + new_previous + suffix
|
| 1667 |
+
new_prefix_prev_suffix_cache = outputs.past_key_values
|
| 1668 |
+
|
| 1669 |
+
# 4. adjust units cache RoPE
|
| 1670 |
+
# new layout: [prefix] [new_prev] [suffix] [units]
|
| 1671 |
+
# note: no position_offset, because cache position has been compressed (from 0 start)
|
| 1672 |
+
new_system_total = prefix_end + new_previous_len + suffix_len
|
| 1673 |
+
if units_cache is not None and self._get_cache_len(units_cache) > 0:
|
| 1674 |
+
old_start = units_start_in_old_cache
|
| 1675 |
+
new_start = new_system_total
|
| 1676 |
+
|
| 1677 |
+
if old_start != new_start:
|
| 1678 |
+
units_cache = self._reindex_rope_for_cache(units_cache, old_start, new_start, units_to_keep_len)
|
| 1679 |
+
|
| 1680 |
+
# 5. concatenate new cache
|
| 1681 |
+
if units_cache is not None and self._get_cache_len(units_cache) > 0:
|
| 1682 |
+
self.cache = self._concat_caches(new_prefix_prev_suffix_cache, units_cache)
|
| 1683 |
+
else:
|
| 1684 |
+
self.cache = new_prefix_prev_suffix_cache
|
| 1685 |
+
|
| 1686 |
+
# 6. update length
|
| 1687 |
+
self._previous_content_length = new_previous_len
|
| 1688 |
+
# total preserve length = prefix + previous + suffix
|
| 1689 |
+
self._system_preserve_length = prefix_end + new_previous_len + suffix_len
|
| 1690 |
+
|
| 1691 |
+
# print detailed cache layout information
|
| 1692 |
+
prev_text_preview = self._previous_text[:50] + "..." if len(self._previous_text) > 50 else self._previous_text
|
| 1693 |
+
suffix_preview = self.tokenizer.decode(self._suffix_token_ids) if self._suffix_token_ids else ""
|
| 1694 |
+
return True
|
| 1695 |
+
|
| 1696 |
+
def _slice_cache(self, start: int, end: Optional[int], clone: bool = True):
|
| 1697 |
+
"""slice cache
|
| 1698 |
+
|
| 1699 |
+
Args:
|
| 1700 |
+
start: start position
|
| 1701 |
+
end: end position (None means to end)
|
| 1702 |
+
clone: whether to clone (default True, to prevent shared memory issues)
|
| 1703 |
+
"""
|
| 1704 |
+
if self.cache is None:
|
| 1705 |
+
return None
|
| 1706 |
+
if isinstance(self.cache, DynamicCache):
|
| 1707 |
+
# DynamicCache
|
| 1708 |
+
new_key_cache = [
|
| 1709 |
+
k[:, :, start:end, :].clone() if clone else k[:, :, start:end, :] for k in self.cache.key_cache
|
| 1710 |
+
]
|
| 1711 |
+
new_value_cache = [
|
| 1712 |
+
v[:, :, start:end, :].clone() if clone else v[:, :, start:end, :] for v in self.cache.value_cache
|
| 1713 |
+
]
|
| 1714 |
+
new_cache = DynamicCache()
|
| 1715 |
+
new_cache.key_cache = new_key_cache
|
| 1716 |
+
new_cache.value_cache = new_value_cache
|
| 1717 |
+
return new_cache
|
| 1718 |
+
else:
|
| 1719 |
+
# Tuple cache
|
| 1720 |
+
if clone:
|
| 1721 |
+
return tuple(
|
| 1722 |
+
(layer[0][:, :, start:end, :].clone(), layer[1][:, :, start:end, :].clone()) for layer in self.cache
|
| 1723 |
+
)
|
| 1724 |
+
else:
|
| 1725 |
+
return tuple((layer[0][:, :, start:end, :], layer[1][:, :, start:end, :]) for layer in self.cache)
|
| 1726 |
+
|
| 1727 |
+
@staticmethod
|
| 1728 |
+
def _get_cache_len(cache) -> int:
|
| 1729 |
+
if cache is None:
|
| 1730 |
+
return 0
|
| 1731 |
+
if isinstance(cache, DynamicCache):
|
| 1732 |
+
if len(cache.key_cache) > 0 and cache.key_cache[0].numel() > 0:
|
| 1733 |
+
return cache.key_cache[0].shape[2]
|
| 1734 |
+
return 0
|
| 1735 |
+
|
| 1736 |
+
if cache and cache[0] and cache[0][0] is not None:
|
| 1737 |
+
return cache[0][0].shape[2]
|
| 1738 |
+
return 0
|
| 1739 |
+
|
| 1740 |
+
@staticmethod
|
| 1741 |
+
def _concat_caches(cache1, cache2):
|
| 1742 |
+
if cache1 is None:
|
| 1743 |
+
return cache2
|
| 1744 |
+
if cache2 is None:
|
| 1745 |
+
return cache1
|
| 1746 |
+
|
| 1747 |
+
if isinstance(cache1, DynamicCache):
|
| 1748 |
+
new_cache = DynamicCache()
|
| 1749 |
+
new_cache.key_cache = [torch.cat([k1, k2], dim=2) for k1, k2 in zip(cache1.key_cache, cache2.key_cache)]
|
| 1750 |
+
new_cache.value_cache = [
|
| 1751 |
+
torch.cat([v1, v2], dim=2) for v1, v2 in zip(cache1.value_cache, cache2.value_cache)
|
| 1752 |
+
]
|
| 1753 |
+
return new_cache
|
| 1754 |
+
else:
|
| 1755 |
+
return tuple(
|
| 1756 |
+
(
|
| 1757 |
+
torch.cat([layer1[0], layer2[0]], dim=2),
|
| 1758 |
+
torch.cat([layer1[1], layer2[1]], dim=2),
|
| 1759 |
+
)
|
| 1760 |
+
for layer1, layer2 in zip(cache1, cache2)
|
| 1761 |
+
)
|
| 1762 |
+
|
| 1763 |
+
def _reindex_rope_for_cache(self, cache, old_start: int, new_start: int, length: int):
|
| 1764 |
+
"""reindex RoPE position for cache"""
|
| 1765 |
+
if cache is None or length <= 0:
|
| 1766 |
+
return cache
|
| 1767 |
+
|
| 1768 |
+
if isinstance(cache, DynamicCache):
|
| 1769 |
+
device = cache.key_cache[0].device if cache.key_cache else None
|
| 1770 |
+
else:
|
| 1771 |
+
device = cache[0][0].device if cache and cache[0] else None
|
| 1772 |
+
|
| 1773 |
+
if device is None:
|
| 1774 |
+
return cache
|
| 1775 |
+
|
| 1776 |
+
old_positions = torch.arange(old_start, old_start + length, device=device, dtype=torch.long)
|
| 1777 |
+
new_positions = torch.arange(new_start, new_start + length, device=device, dtype=torch.long)
|
| 1778 |
+
|
| 1779 |
+
rope_theta = self._get_rope_theta()
|
| 1780 |
+
|
| 1781 |
+
if isinstance(cache, DynamicCache):
|
| 1782 |
+
new_key_cache = []
|
| 1783 |
+
for k in cache.key_cache:
|
| 1784 |
+
new_k = realign_rotary_suffix(k, old_positions, new_positions, rope_theta, self._rope_inv_freq_cache)
|
| 1785 |
+
new_key_cache.append(new_k)
|
| 1786 |
+
cache.key_cache = new_key_cache
|
| 1787 |
+
return cache
|
| 1788 |
+
else:
|
| 1789 |
+
new_cache = []
|
| 1790 |
+
for layer in cache:
|
| 1791 |
+
new_k = realign_rotary_suffix(
|
| 1792 |
+
layer[0], old_positions, new_positions, rope_theta, self._rope_inv_freq_cache
|
| 1793 |
+
)
|
| 1794 |
+
new_cache.append((new_k, layer[1]))
|
| 1795 |
+
return tuple(new_cache)
|
| 1796 |
+
|
| 1797 |
+
def _update_previous(
|
| 1798 |
+
self,
|
| 1799 |
+
new_text: str,
|
| 1800 |
+
new_tokens: List[int],
|
| 1801 |
+
max_tokens: int,
|
| 1802 |
+
) -> None:
|
| 1803 |
+
"""update previous context (also update cache)
|
| 1804 |
+
|
| 1805 |
+
when first sliding window, dynamically add marker + text, subsequent sliding window append text
|
| 1806 |
+
when content exceeds max_tokens, truncate content (keep marker)
|
| 1807 |
+
rebuild cache to maintain consistency
|
| 1808 |
+
|
| 1809 |
+
Args:
|
| 1810 |
+
new_text: new text
|
| 1811 |
+
new_tokens: new token ids
|
| 1812 |
+
max_tokens: previous content maximum token count (without marker)
|
| 1813 |
+
"""
|
| 1814 |
+
marker_len = len(self._previous_marker_token_ids)
|
| 1815 |
+
tokens_to_drop = 0
|
| 1816 |
+
|
| 1817 |
+
# if no new content, do not add marker, but still need to rebuild cache
|
| 1818 |
+
if not new_tokens and not new_text:
|
| 1819 |
+
# still need to rebuild cache (because a unit was deleted)
|
| 1820 |
+
self._rebuild_cache_with_previous(self._previous_token_ids)
|
| 1821 |
+
return
|
| 1822 |
+
|
| 1823 |
+
if not self._has_previous:
|
| 1824 |
+
# when first has actual content: add marker + text
|
| 1825 |
+
self._previous_text = new_text
|
| 1826 |
+
self._previous_token_ids = self._previous_marker_token_ids.copy() + new_tokens
|
| 1827 |
+
self._has_previous = True
|
| 1828 |
+
else:
|
| 1829 |
+
# subsequent sliding window: append text to previous
|
| 1830 |
+
self._previous_text += new_text
|
| 1831 |
+
self._previous_token_ids.extend(new_tokens)
|
| 1832 |
+
|
| 1833 |
+
# calculate token count of content (without marker)
|
| 1834 |
+
content_token_count = len(self._previous_token_ids) - marker_len
|
| 1835 |
+
|
| 1836 |
+
# check if need to truncate content (keep marker)
|
| 1837 |
+
if content_token_count > max_tokens:
|
| 1838 |
+
# truncate left content, keep marker + latest max_tokens content
|
| 1839 |
+
tokens_to_drop = content_token_count - max_tokens
|
| 1840 |
+
old_text = self._previous_text
|
| 1841 |
+
# keep marker + truncated content
|
| 1842 |
+
content_tokens = self._previous_token_ids[marker_len + tokens_to_drop :]
|
| 1843 |
+
self._previous_token_ids = self._previous_marker_token_ids.copy() + content_tokens
|
| 1844 |
+
# redecode text (only decode content part)
|
| 1845 |
+
try:
|
| 1846 |
+
self._previous_text = self.tokenizer.decode(
|
| 1847 |
+
content_tokens,
|
| 1848 |
+
skip_special_tokens=True,
|
| 1849 |
+
)
|
| 1850 |
+
except Exception as e:
|
| 1851 |
+
logger.warning("_update_previous: decode failed: %s", e)
|
| 1852 |
+
|
| 1853 |
+
# rebuild cache
|
| 1854 |
+
self._rebuild_cache_with_previous(self._previous_token_ids)
|
| 1855 |
+
|
| 1856 |
+
def _drop_unit_with_context(
|
| 1857 |
+
self,
|
| 1858 |
+
unit_id: int,
|
| 1859 |
+
max_previous_tokens: int,
|
| 1860 |
+
) -> Tuple[bool, str, List[int]]:
|
| 1861 |
+
"""remove specified unit and return its generated content (for context preserving)
|
| 1862 |
+
|
| 1863 |
+
process:
|
| 1864 |
+
1. extract generated content of unit
|
| 1865 |
+
2. remove unit from cache (without prefix+previous)
|
| 1866 |
+
3. append generated content to previous
|
| 1867 |
+
4. rebuild cache (in _update_previous)
|
| 1868 |
+
|
| 1869 |
+
Args:
|
| 1870 |
+
unit_id: unit ID to remove
|
| 1871 |
+
max_previous_tokens: previous maximum token count
|
| 1872 |
+
|
| 1873 |
+
Returns:
|
| 1874 |
+
(success, extracted_text, extracted_tokens): whether successful, extracted text and tokens
|
| 1875 |
+
"""
|
| 1876 |
+
entries = [u for u in self._unit_history if u["unit_id"] == unit_id]
|
| 1877 |
+
if not entries:
|
| 1878 |
+
return False, "", []
|
| 1879 |
+
|
| 1880 |
+
# extract generated content
|
| 1881 |
+
extracted_text, extracted_tokens = self._extract_generated_text(entries)
|
| 1882 |
+
|
| 1883 |
+
# calculate total length
|
| 1884 |
+
total_len = sum(e["length"] for e in entries)
|
| 1885 |
+
if total_len <= 0:
|
| 1886 |
+
for e in entries:
|
| 1887 |
+
self._unit_history.remove(e)
|
| 1888 |
+
return False, extracted_text, extracted_tokens
|
| 1889 |
+
|
| 1890 |
+
cache_before = self.get_cache_length()
|
| 1891 |
+
|
| 1892 |
+
# remove from unit_history (record for later processing)
|
| 1893 |
+
for e in entries:
|
| 1894 |
+
self._unit_history.remove(e)
|
| 1895 |
+
|
| 1896 |
+
# note: here no longer call _drop_tokens_from_cache
|
| 1897 |
+
# because _update_previous will rebuild the entire cache
|
| 1898 |
+
|
| 1899 |
+
# update previous (also rebuild cache)
|
| 1900 |
+
self._update_previous(extracted_text, extracted_tokens, max_previous_tokens)
|
| 1901 |
+
|
| 1902 |
+
return True, extracted_text, extracted_tokens
|
| 1903 |
+
|
| 1904 |
+
def _drop_next_unit_with_context(self, max_previous_tokens: int) -> bool:
|
| 1905 |
+
"""remove the earliest non-system unit (with context preserving)"""
|
| 1906 |
+
for entry in self._unit_history:
|
| 1907 |
+
unit_id = entry.get("unit_id")
|
| 1908 |
+
if unit_id is None:
|
| 1909 |
+
continue
|
| 1910 |
+
if entry.get("type") == "system":
|
| 1911 |
+
continue
|
| 1912 |
+
success, _, _ = self._drop_unit_with_context(unit_id, max_previous_tokens)
|
| 1913 |
+
if success:
|
| 1914 |
+
return True
|
| 1915 |
+
return False
|
| 1916 |
+
|
| 1917 |
+
def enforce_window_with_context(self) -> bool:
|
| 1918 |
+
"""context preserving sliding window execution
|
| 1919 |
+
|
| 1920 |
+
when unit count exceeds max_units, remove the earliest unit,
|
| 1921 |
+
and accumulate its generated content to previous.
|
| 1922 |
+
Cache will be automatically rebuilt in _update_previous.
|
| 1923 |
+
|
| 1924 |
+
Returns:
|
| 1925 |
+
whether sliding window is executed
|
| 1926 |
+
"""
|
| 1927 |
+
if not self._window_enabled:
|
| 1928 |
+
return False
|
| 1929 |
+
|
| 1930 |
+
cfg = self._window_config
|
| 1931 |
+
|
| 1932 |
+
if cfg.sliding_window_mode != "context":
|
| 1933 |
+
# if not context mode, fallback to basic sliding window
|
| 1934 |
+
return self.enforce_window()
|
| 1935 |
+
|
| 1936 |
+
cache_len_before = self.get_cache_length()
|
| 1937 |
+
units_before = len(self._unit_history)
|
| 1938 |
+
|
| 1939 |
+
# context preserving mode: only check if unit count exceeds limit
|
| 1940 |
+
# (previous exceeds limit in _update_previous will automatically truncate left)
|
| 1941 |
+
if units_before <= cfg.context_max_units:
|
| 1942 |
+
return False
|
| 1943 |
+
|
| 1944 |
+
# sliding window loop: remove unit until count ≤ max_units
|
| 1945 |
+
dropped_count = 0
|
| 1946 |
+
while len(self._unit_history) > cfg.context_max_units:
|
| 1947 |
+
if not self._drop_next_unit_with_context(cfg.context_previous_max_tokens):
|
| 1948 |
+
break
|
| 1949 |
+
|
| 1950 |
+
dropped_count += 1
|
| 1951 |
+
|
| 1952 |
+
cache_len_after = self.get_cache_length()
|
| 1953 |
+
|
| 1954 |
+
if dropped_count > 0:
|
| 1955 |
+
# update statistics counter
|
| 1956 |
+
self._sliding_event_count += 1
|
| 1957 |
+
self._total_dropped_tokens += cache_len_before - cache_len_after
|
| 1958 |
+
self._total_dropped_units += dropped_count
|
| 1959 |
+
|
| 1960 |
+
# consistency check
|
| 1961 |
+
expected = self._system_preserve_length + sum(u["length"] for u in self._unit_history)
|
| 1962 |
+
|
| 1963 |
+
return dropped_count > 0
|
| 1964 |
+
|
| 1965 |
+
def get_previous_context(self) -> Tuple[str, List[int]]:
|
| 1966 |
+
"""get current accumulated previous context
|
| 1967 |
+
|
| 1968 |
+
Returns:
|
| 1969 |
+
(previous_text, previous_token_ids): current accumulated text and token ids
|
| 1970 |
+
"""
|
| 1971 |
+
return self._previous_text, self._previous_token_ids.copy()
|
| 1972 |
+
|
| 1973 |
+
def get_window_stats(self) -> Dict[str, Any]:
|
| 1974 |
+
"""get sliding window statistics"""
|
| 1975 |
+
unit_lengths = [u["length"] for u in self._unit_history]
|
| 1976 |
+
return {
|
| 1977 |
+
"cache_length": self.get_cache_length(),
|
| 1978 |
+
"unit_count": len(self._unit_history),
|
| 1979 |
+
"unit_lengths": unit_lengths,
|
| 1980 |
+
"unit_total_length": sum(unit_lengths),
|
| 1981 |
+
"system_preserve_length": self._system_preserve_length,
|
| 1982 |
+
"position_offset": self._position_offset,
|
| 1983 |
+
"window_enabled": self._window_enabled,
|
| 1984 |
+
"total_generated_tokens": self.get_total_generated_tokens(),
|
| 1985 |
+
"pending_unit_id": self._pending_unit_id,
|
| 1986 |
+
"next_unit_id": self._next_unit_id,
|
| 1987 |
+
"config": {
|
| 1988 |
+
"sliding_window_mode": self._window_config.sliding_window_mode,
|
| 1989 |
+
"basic_window_high_tokens": self._window_config.basic_window_high_tokens,
|
| 1990 |
+
"basic_window_low_tokens": self._window_config.basic_window_low_tokens,
|
| 1991 |
+
"context_previous_max_tokens": self._window_config.context_previous_max_tokens,
|
| 1992 |
+
"context_max_units": self._window_config.context_max_units,
|
| 1993 |
+
},
|
| 1994 |
+
# context preserving related
|
| 1995 |
+
"preserve_prefix_length": self._preserve_prefix_length,
|
| 1996 |
+
"previous_content_length": self._previous_content_length,
|
| 1997 |
+
"suffix_token_count": len(self._suffix_token_ids),
|
| 1998 |
+
"previous_text_length": len(self._previous_text),
|
| 1999 |
+
"previous_token_count": len(self._previous_token_ids),
|
| 2000 |
+
"has_system_template": self._system_prompt_template is not None,
|
| 2001 |
+
}
|
| 2002 |
+
|
| 2003 |
+
def _verify_consistency(self) -> bool:
|
| 2004 |
+
"""verify unit history and cache length consistency"""
|
| 2005 |
+
expected = self._system_preserve_length + sum(u["length"] for u in self._unit_history)
|
| 2006 |
+
actual = self.get_cache_length()
|
| 2007 |
+
return expected == actual
|
| 2008 |
+
|
| 2009 |
+
def print_verification_summary(self) -> Dict[str, Any]:
|
| 2010 |
+
"""print verification summary (for comparing off/basic/context mode)
|
| 2011 |
+
|
| 2012 |
+
Returns:
|
| 2013 |
+
dictionary containing key verification data
|
| 2014 |
+
"""
|
| 2015 |
+
cfg = self._window_config
|
| 2016 |
+
|
| 2017 |
+
# collect all generated text
|
| 2018 |
+
all_generated_text = []
|
| 2019 |
+
all_generated_tokens = []
|
| 2020 |
+
for u in self._unit_history:
|
| 2021 |
+
if not u.get("is_listen", False):
|
| 2022 |
+
gen_text = u.get("generated_text", "")
|
| 2023 |
+
gen_tokens = u.get("generated_tokens", [])
|
| 2024 |
+
if gen_text:
|
| 2025 |
+
all_generated_text.append(gen_text)
|
| 2026 |
+
if gen_tokens:
|
| 2027 |
+
all_generated_tokens.extend(gen_tokens)
|
| 2028 |
+
|
| 2029 |
+
combined_text = "".join(all_generated_text)
|
| 2030 |
+
|
| 2031 |
+
summary = {
|
| 2032 |
+
"mode": cfg.sliding_window_mode,
|
| 2033 |
+
"final_cache_length": self.get_cache_length(),
|
| 2034 |
+
"final_unit_count": len(self._unit_history),
|
| 2035 |
+
"sliding_event_count": self._sliding_event_count,
|
| 2036 |
+
"total_dropped_tokens": self._total_dropped_tokens,
|
| 2037 |
+
"total_dropped_units": self._total_dropped_units,
|
| 2038 |
+
"total_generated_tokens": len(all_generated_tokens),
|
| 2039 |
+
"generated_text": combined_text,
|
| 2040 |
+
"previous_text": self._previous_text,
|
| 2041 |
+
"previous_token_count": len(self._previous_token_ids),
|
| 2042 |
+
"position_offset": self._position_offset,
|
| 2043 |
+
"system_preserve_length": self._system_preserve_length,
|
| 2044 |
+
}
|
| 2045 |
+
|
| 2046 |
+
return summary
|
| 2047 |
+
|
| 2048 |
+
def set_window_config(self, config: DuplexWindowConfig) -> None:
|
| 2049 |
+
"""set sliding window configuration"""
|
| 2050 |
+
self._window_config = config
|
| 2051 |
+
|
| 2052 |
+
def set_window_enabled(self, enabled: bool) -> None:
|
| 2053 |
+
"""enable/disable sliding window"""
|
| 2054 |
+
old_enabled = self._window_enabled
|
| 2055 |
+
self._window_enabled = enabled
|
| 2056 |
+
|
| 2057 |
+
def get_context(self):
|
| 2058 |
+
return self.context
|
| 2059 |
+
|
| 2060 |
+
def embed_token(self, tid):
|
| 2061 |
+
if isinstance(tid, int):
|
| 2062 |
+
tid = torch.tensor([tid], device=self.m.device)
|
| 2063 |
+
return self.m.model.embed_tokens(tid)
|
| 2064 |
+
|
| 2065 |
+
def embed_tokens(self, token_ids: List[int]) -> torch.Tensor:
|
| 2066 |
+
"""batch embed multiple tokens
|
| 2067 |
+
|
| 2068 |
+
Args:
|
| 2069 |
+
token_ids: list of token ids
|
| 2070 |
+
|
| 2071 |
+
Returns:
|
| 2072 |
+
embeddings tensor [L, H]
|
| 2073 |
+
"""
|
| 2074 |
+
if not token_ids:
|
| 2075 |
+
return torch.empty(0, self.m.config.hidden_size, device=self.m.device)
|
| 2076 |
+
tids = torch.tensor(token_ids, device=self.m.device)
|
| 2077 |
+
return self.m.model.embed_tokens(tids)
|
| 2078 |
+
|
| 2079 |
+
@torch.no_grad()
|
| 2080 |
+
def feed(self, embeds: torch.Tensor, return_logits: bool = False):
|
| 2081 |
+
"""
|
| 2082 |
+
embeds : [L, H] —— new embedding sequence fed into model at once
|
| 2083 |
+
"""
|
| 2084 |
+
L = embeds.size(0)
|
| 2085 |
+
device = embeds.device
|
| 2086 |
+
|
| 2087 |
+
past_len = self.get_cache_length()
|
| 2088 |
+
pos_ids = torch.arange(past_len, past_len + L, device=device).unsqueeze(0) # [1, L]
|
| 2089 |
+
|
| 2090 |
+
out = self.m(
|
| 2091 |
+
inputs_embeds=embeds.unsqueeze(0), # [1, L, H]
|
| 2092 |
+
position_ids=pos_ids,
|
| 2093 |
+
past_key_values=self.cache,
|
| 2094 |
+
# use_cache = True,
|
| 2095 |
+
return_dict=True,
|
| 2096 |
+
output_hidden_states=True,
|
| 2097 |
+
# attention_mask=attention_mask
|
| 2098 |
+
)
|
| 2099 |
+
self.cache = out.past_key_values
|
| 2100 |
+
|
| 2101 |
+
if return_logits:
|
| 2102 |
+
logits = self.m.lm_head(out.hidden_states[-1])[:, -1] # [1, vocab]
|
| 2103 |
+
return logits, out.hidden_states[-1]
|
| 2104 |
+
|
| 2105 |
+
@torch.no_grad()
|
| 2106 |
+
def decode(
|
| 2107 |
+
self,
|
| 2108 |
+
logits,
|
| 2109 |
+
mode: Literal["sampling", "greedy"] = "sampling",
|
| 2110 |
+
temperature=0.7,
|
| 2111 |
+
top_k=20,
|
| 2112 |
+
top_p=0.8,
|
| 2113 |
+
listen_top_k=None,
|
| 2114 |
+
listen_prob_scale=1.0,
|
| 2115 |
+
text_repetition_penalty=1.05,
|
| 2116 |
+
text_repetition_window_size=512,
|
| 2117 |
+
):
|
| 2118 |
+
"""
|
| 2119 |
+
Args:
|
| 2120 |
+
logits:
|
| 2121 |
+
mode: sampling or greedy
|
| 2122 |
+
temperature:
|
| 2123 |
+
top_k:
|
| 2124 |
+
top_p:
|
| 2125 |
+
listen_top_k: force listen_id to be in top-k to keep
|
| 2126 |
+
listen_prob_scale: multiply listen_id probability by a weight (<1 means decrease, >1 means increase)
|
| 2127 |
+
text_repetition_penalty: repetition penalty coefficient, >1.0 means decrease repetition, <1.0 means increase repetition
|
| 2128 |
+
text_repetition_window_size: repetition penalty window size
|
| 2129 |
+
|
| 2130 |
+
Sampling strategy:
|
| 2131 |
+
1. first sample all tokens with original logits (apply temperature)
|
| 2132 |
+
2. if sampled chunk_eos, return directly (keep the original model's decision of when to stop)
|
| 2133 |
+
3. if not sampled chunk_eos, mask it (set logit to -inf), continue sampling text tokens
|
| 2134 |
+
4. apply repetition penalty, top-k, top-p, etc. to the text tokens for the final sampling
|
| 2135 |
+
"""
|
| 2136 |
+
|
| 2137 |
+
logits = logits.clone()
|
| 2138 |
+
|
| 2139 |
+
# 0. independently check chunk_eos before sampling
|
| 2140 |
+
eos_id = self.chunk_eos_id
|
| 2141 |
+
|
| 2142 |
+
with torch.no_grad():
|
| 2143 |
+
if mode == "greedy":
|
| 2144 |
+
sampled_token = torch.argmax(logits[0]).item()
|
| 2145 |
+
else:
|
| 2146 |
+
original_probs = F.softmax(logits[0], dim=-1)
|
| 2147 |
+
sampled_token = torch.multinomial(original_probs, num_samples=1).item()
|
| 2148 |
+
|
| 2149 |
+
# if sampled chunk_eos, return directly
|
| 2150 |
+
if sampled_token == eos_id:
|
| 2151 |
+
next_token_id = torch.tensor([eos_id], device=logits.device)
|
| 2152 |
+
next_token_str = self.tokenizer.decode(next_token_id)
|
| 2153 |
+
|
| 2154 |
+
return next_token_id
|
| 2155 |
+
|
| 2156 |
+
# if not sampled chunk_eos, set its logit to -inf
|
| 2157 |
+
if self.forbidden_token_ids:
|
| 2158 |
+
logits[:, self.forbidden_token_ids] = float("-inf")
|
| 2159 |
+
|
| 2160 |
+
# 1. apply repetition penalty
|
| 2161 |
+
if text_repetition_penalty != 1.0 and len(self.generated_tokens) > 0:
|
| 2162 |
+
# get recent tokens (within window size) considering special tokens and normal tokens
|
| 2163 |
+
recent_tokens = self.generated_tokens[-text_repetition_window_size:]
|
| 2164 |
+
|
| 2165 |
+
# make it unique
|
| 2166 |
+
recent_tokens = list(set(recent_tokens))
|
| 2167 |
+
|
| 2168 |
+
# apply penalty to repeated tokens
|
| 2169 |
+
for token_id in recent_tokens:
|
| 2170 |
+
if token_id < logits.size(-1): # ensure token_id is in vocabulary range
|
| 2171 |
+
if text_repetition_penalty > 1.0:
|
| 2172 |
+
# penalize repetition: decrease logits
|
| 2173 |
+
logits[0, token_id] /= text_repetition_penalty
|
| 2174 |
+
else:
|
| 2175 |
+
# encourage repetition: increase logits
|
| 2176 |
+
logits[0, token_id] *= 1.0 / text_repetition_penalty
|
| 2177 |
+
|
| 2178 |
+
if listen_prob_scale != 1.0: # modify listen token logit separately
|
| 2179 |
+
logits[0, self.listen_id] *= listen_prob_scale
|
| 2180 |
+
|
| 2181 |
+
listen_rank = (logits[0] > logits[0, self.listen_id]).sum().item()
|
| 2182 |
+
|
| 2183 |
+
if listen_top_k is not None and listen_rank < listen_top_k: # listen_id is in top-k, return directly
|
| 2184 |
+
next_token_id = torch.tensor([self.listen_id], device=logits.device)
|
| 2185 |
+
next_token_str = self.tokenizer.decode(next_token_id)
|
| 2186 |
+
|
| 2187 |
+
if next_token_str == "<|listen|>":
|
| 2188 |
+
self.context += " "
|
| 2189 |
+
else:
|
| 2190 |
+
self.context += next_token_str
|
| 2191 |
+
|
| 2192 |
+
return next_token_id
|
| 2193 |
+
|
| 2194 |
+
if mode == "greedy":
|
| 2195 |
+
next_token_id = torch.argmax(logits, dim=-1)
|
| 2196 |
+
elif mode == "sampling":
|
| 2197 |
+
logits = logits / temperature
|
| 2198 |
+
logits = top_k_top_p_filtering(logits, top_k=top_k, top_p=top_p)
|
| 2199 |
+
probs = F.softmax(logits, dim=-1)
|
| 2200 |
+
next_token_id = torch.multinomial(probs, num_samples=1).squeeze(1)
|
| 2201 |
+
else:
|
| 2202 |
+
raise ValueError(f"Unsupported decode mode: {mode}")
|
| 2203 |
+
|
| 2204 |
+
if next_token_id.item() not in self.special_token_ids:
|
| 2205 |
+
self.generated_tokens.append(next_token_id.item())
|
| 2206 |
+
else:
|
| 2207 |
+
self.generated_special_tokens.append(next_token_id.item())
|
| 2208 |
+
|
| 2209 |
+
return next_token_id
|
| 2210 |
+
|
| 2211 |
+
|
| 2212 |
+
def _download_url_to_tempfile(url: str, suffix: str = "", timeout: int = 60) -> str:
|
| 2213 |
+
"""
|
| 2214 |
+
Download a URL to a temporary file and return the path.
|
| 2215 |
+
|
| 2216 |
+
Args:
|
| 2217 |
+
url: HTTP/HTTPS URL to download
|
| 2218 |
+
suffix: File suffix (e.g., ".jpg", ".wav", ".mp4")
|
| 2219 |
+
timeout: Download timeout in seconds
|
| 2220 |
+
|
| 2221 |
+
Returns:
|
| 2222 |
+
Path to the downloaded temporary file
|
| 2223 |
+
"""
|
| 2224 |
+
import tempfile
|
| 2225 |
+
|
| 2226 |
+
import requests
|
| 2227 |
+
|
| 2228 |
+
response = requests.get(url, timeout=timeout)
|
| 2229 |
+
response.raise_for_status()
|
| 2230 |
+
|
| 2231 |
+
with tempfile.NamedTemporaryFile(suffix=suffix, delete=False) as f:
|
| 2232 |
+
f.write(response.content)
|
| 2233 |
+
return f.name
|
| 2234 |
+
|
| 2235 |
+
|
| 2236 |
+
def _is_url(path: str) -> bool:
|
| 2237 |
+
return path.startswith(("http://", "https://"))
|
| 2238 |
+
|
| 2239 |
+
|
| 2240 |
+
def normalize_content_item(item) -> Union[str, Any, List[Any]]:
|
| 2241 |
+
"""Normalize structured content item to native format.
|
| 2242 |
+
|
| 2243 |
+
Supports:
|
| 2244 |
+
- Native format: str, PIL.Image, np.ndarray (pass through)
|
| 2245 |
+
- OpenAI structured format:
|
| 2246 |
+
- {"type": "text", "text": "..."} -> str
|
| 2247 |
+
- {"type": "image_url", "image_url": {"url": "..."}} -> PIL.Image
|
| 2248 |
+
- {"type": "audio_url", "audio_url": {"url": "..."}} -> np.ndarray
|
| 2249 |
+
- {"type": "video_url", "video_url": {"url": "...", ...}} -> List[Image, ndarray, ...]
|
| 2250 |
+
|
| 2251 |
+
URL formats supported:
|
| 2252 |
+
- Local file path: "/path/to/file.jpg"
|
| 2253 |
+
- HTTP/HTTPS URL: "https://example.com/image.jpg"
|
| 2254 |
+
|
| 2255 |
+
Args:
|
| 2256 |
+
item: Content item to normalize
|
| 2257 |
+
|
| 2258 |
+
Returns:
|
| 2259 |
+
Normalized item. For video_url, returns a tuple ("__video_contents__", list)
|
| 2260 |
+
that will be flattened by normalize_content().
|
| 2261 |
+
|
| 2262 |
+
Raises:
|
| 2263 |
+
ValueError: If content type is unknown or unsupported
|
| 2264 |
+
"""
|
| 2265 |
+
import os
|
| 2266 |
+
|
| 2267 |
+
import numpy as np
|
| 2268 |
+
from PIL import Image
|
| 2269 |
+
|
| 2270 |
+
if isinstance(item, str):
|
| 2271 |
+
return item
|
| 2272 |
+
if isinstance(item, Image.Image):
|
| 2273 |
+
return item
|
| 2274 |
+
if isinstance(item, np.ndarray):
|
| 2275 |
+
return item
|
| 2276 |
+
|
| 2277 |
+
if isinstance(item, dict):
|
| 2278 |
+
item_type = item.get("type")
|
| 2279 |
+
|
| 2280 |
+
if item_type == "text":
|
| 2281 |
+
return item.get("text", "")
|
| 2282 |
+
|
| 2283 |
+
elif item_type == "image_url":
|
| 2284 |
+
image_url_obj = item.get("image_url", {})
|
| 2285 |
+
url = image_url_obj.get("url", "") if isinstance(image_url_obj, dict) else image_url_obj
|
| 2286 |
+
|
| 2287 |
+
if _is_url(url):
|
| 2288 |
+
# Download to temp file
|
| 2289 |
+
temp_path = _download_url_to_tempfile(url, suffix=".jpg", timeout=30)
|
| 2290 |
+
img = Image.open(temp_path)
|
| 2291 |
+
os.unlink(temp_path)
|
| 2292 |
+
return img
|
| 2293 |
+
else:
|
| 2294 |
+
return Image.open(url)
|
| 2295 |
+
elif item_type == "audio_url":
|
| 2296 |
+
import librosa
|
| 2297 |
+
|
| 2298 |
+
audio_url_obj = item.get("audio_url", {})
|
| 2299 |
+
url = audio_url_obj.get("url", "") if isinstance(audio_url_obj, dict) else audio_url_obj
|
| 2300 |
+
|
| 2301 |
+
if _is_url(url):
|
| 2302 |
+
# Download to temp file
|
| 2303 |
+
temp_path = _download_url_to_tempfile(url, suffix=".wav", timeout=60)
|
| 2304 |
+
audio_np, _ = librosa.load(temp_path, sr=16000, mono=True)
|
| 2305 |
+
os.unlink(temp_path)
|
| 2306 |
+
return audio_np
|
| 2307 |
+
else:
|
| 2308 |
+
audio_np, _ = librosa.load(url, sr=16000, mono=True)
|
| 2309 |
+
return audio_np
|
| 2310 |
+
elif item_type == "video_url":
|
| 2311 |
+
# Video processing - returns a LIST of items (frames + audio segments)
|
| 2312 |
+
# Note: Unlike image_url/audio_url which return single items,
|
| 2313 |
+
# video_url returns a list that will be flattened into the content
|
| 2314 |
+
from minicpmo.utils import get_video_frame_audio_segments
|
| 2315 |
+
|
| 2316 |
+
video_url_obj = item.get("video_url", {})
|
| 2317 |
+
if isinstance(video_url_obj, dict):
|
| 2318 |
+
video_url = video_url_obj.get("url", "")
|
| 2319 |
+
# Get optional parameters from video_url object (OpenAI style)
|
| 2320 |
+
stack_frames = video_url_obj.get("stack_frames", 1)
|
| 2321 |
+
use_ffmpeg = video_url_obj.get("use_ffmpeg", False)
|
| 2322 |
+
use_audio = video_url_obj.get("use_audio", True)
|
| 2323 |
+
else:
|
| 2324 |
+
video_url = video_url_obj
|
| 2325 |
+
stack_frames = 1
|
| 2326 |
+
use_ffmpeg = False
|
| 2327 |
+
use_audio = True
|
| 2328 |
+
|
| 2329 |
+
# Handle HTTP/HTTPS URL - download to temp file
|
| 2330 |
+
temp_video_path = None
|
| 2331 |
+
if _is_url(video_url):
|
| 2332 |
+
temp_video_path = _download_url_to_tempfile(video_url, suffix=".mp4", timeout=120)
|
| 2333 |
+
video_path = temp_video_path
|
| 2334 |
+
else:
|
| 2335 |
+
video_path = video_url
|
| 2336 |
+
|
| 2337 |
+
# Extract frames and audio segments
|
| 2338 |
+
video_frames, audio_segments, stacked_frames = get_video_frame_audio_segments(
|
| 2339 |
+
video_path,
|
| 2340 |
+
stack_frames=stack_frames,
|
| 2341 |
+
use_ffmpeg=use_ffmpeg,
|
| 2342 |
+
use_audio=use_audio
|
| 2343 |
+
)
|
| 2344 |
+
|
| 2345 |
+
# Clean up temp file if downloaded
|
| 2346 |
+
if temp_video_path is not None:
|
| 2347 |
+
os.unlink(temp_video_path)
|
| 2348 |
+
|
| 2349 |
+
# Build omni_contents (interleaved frames and audio, or frames only)
|
| 2350 |
+
omni_contents = []
|
| 2351 |
+
for i in range(len(video_frames)):
|
| 2352 |
+
omni_contents.append(video_frames[i])
|
| 2353 |
+
if use_audio and audio_segments is not None:
|
| 2354 |
+
omni_contents.append(audio_segments[i])
|
| 2355 |
+
if stacked_frames is not None and i < len(stacked_frames) and stacked_frames[i] is not None:
|
| 2356 |
+
omni_contents.append(stacked_frames[i])
|
| 2357 |
+
|
| 2358 |
+
# Return as a special marker to be flattened later
|
| 2359 |
+
return "__video_contents__", omni_contents
|
| 2360 |
+
else:
|
| 2361 |
+
raise ValueError(f"Unknown content type: {item_type}")
|
| 2362 |
+
|
| 2363 |
+
raise ValueError(f"Cannot normalize content item of type: {type(item)}")
|
| 2364 |
+
|
| 2365 |
+
|
| 2366 |
+
def normalize_content(content) -> list:
|
| 2367 |
+
"""Normalize message content to list of native items.
|
| 2368 |
+
|
| 2369 |
+
Input formats:
|
| 2370 |
+
- str: "hello" -> ["hello"]
|
| 2371 |
+
- list of native items: [str, Image, np.ndarray] -> pass through with normalization
|
| 2372 |
+
- list of structured items: [{"type": "text", ...}] -> normalize each
|
| 2373 |
+
- video type: automatically expanded to omni_contents
|
| 2374 |
+
- mixed: works too
|
| 2375 |
+
|
| 2376 |
+
Args:
|
| 2377 |
+
content: Message content in any supported format
|
| 2378 |
+
|
| 2379 |
+
Returns:
|
| 2380 |
+
List of native items (str, PIL.Image, np.ndarray)
|
| 2381 |
+
|
| 2382 |
+
Examples:
|
| 2383 |
+
>>> normalize_content("hello")
|
| 2384 |
+
["hello"]
|
| 2385 |
+
|
| 2386 |
+
>>> normalize_content([{"type": "text", "text": "hi"}])
|
| 2387 |
+
["hi"]
|
| 2388 |
+
|
| 2389 |
+
>>> normalize_content([{"type": "video", "video": "/path/to/video.mp4"}])
|
| 2390 |
+
[<PIL.Image>, <np.ndarray>, <PIL.Image>, <np.ndarray>, ...]
|
| 2391 |
+
"""
|
| 2392 |
+
import numpy as np
|
| 2393 |
+
from PIL import Image
|
| 2394 |
+
|
| 2395 |
+
if isinstance(content, str):
|
| 2396 |
+
return [content]
|
| 2397 |
+
|
| 2398 |
+
if isinstance(content, list):
|
| 2399 |
+
result = []
|
| 2400 |
+
for item in content:
|
| 2401 |
+
normalized = normalize_content_item(item)
|
| 2402 |
+
# Handle video content (returns tuple with marker)
|
| 2403 |
+
if isinstance(normalized, tuple) and len(normalized) == 2 and normalized[0] == "__video_contents__":
|
| 2404 |
+
# Flatten video contents into result
|
| 2405 |
+
result.extend(normalized[1])
|
| 2406 |
+
else:
|
| 2407 |
+
result.append(normalized)
|
| 2408 |
+
return result
|
| 2409 |
+
|
| 2410 |
+
# Single non-list item (Image or np.ndarray)
|
| 2411 |
+
if isinstance(content, (Image.Image, np.ndarray)):
|
| 2412 |
+
return [content]
|
| 2413 |
+
|
| 2414 |
+
normalized = normalize_content_item(content)
|
| 2415 |
+
if isinstance(normalized, tuple) and len(normalized) == 2 and normalized[0] == "__video_contents__":
|
| 2416 |
+
return normalized[1]
|
| 2417 |
+
return [normalized]
|
vocab.json
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|