Add files using upload-large-folder tool
Browse files- LTA_openwebtext_dualt/logs/lta_lm1b_classic_dirichlet_len512_gbs512_8gpu_20k_save1k_20260523_watcher.pid +1 -0
- LTA_openwebtext_dualt/logs/lta_owt_gpt2cached_len1024_p05_b64_ckpt_fixed_bench4gpu_20260513_153110.log +191 -0
- LTA_openwebtext_dualt/logs/lta_owt_gpt2cached_len1024_rollout1_p05_b64_mlpckpt_bench4gpu_20260513_161317.log +230 -0
- LTA_openwebtext_dualt/logs/owt_fully_path_anchor_refine_step118k_n8.log +0 -0
- LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/numpy/lib/arrayterator.py +219 -0
- LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/numpy/lib/arrayterator.pyi +49 -0
- LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/numpy/lib/format.py +976 -0
- LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/numpy/lib/nanfunctions.pyi +38 -0
- LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/numpy/lib/shape_base.pyi +220 -0
- LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/numpy/lib/utils.py +1211 -0
- LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/transformers/models/barthez/__init__.py +26 -0
- LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/transformers/models/barthez/tokenization_barthez.py +144 -0
- LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/transformers/models/bert/__init__.py +28 -0
- LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/transformers/models/bert/configuration_bert.py +66 -0
- LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/transformers/models/bert/modeling_bert.py +1394 -0
- LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/transformers/models/bert/tokenization_bert.py +140 -0
- LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/transformers/models/bert/tokenization_bert_legacy.py +476 -0
- LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/transformers/models/qwen3_vl/__init__.py +29 -0
- LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/transformers/models/qwen3_vl/configuration_qwen3_vl.py +150 -0
- LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/transformers/models/qwen3_vl/modeling_qwen3_vl.py +1683 -0
LTA_openwebtext_dualt/logs/lta_lm1b_classic_dirichlet_len512_gbs512_8gpu_20k_save1k_20260523_watcher.pid
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
10234
|
LTA_openwebtext_dualt/logs/lta_owt_gpt2cached_len1024_p05_b64_ckpt_fixed_bench4gpu_20260513_153110.log
ADDED
|
@@ -0,0 +1,191 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
|
| 2 |
+
*****************************************
|
| 3 |
+
Setting OMP_NUM_THREADS environment variable for each process to be 1 in default, to avoid your system being overloaded, please further tune the variable for optimal performance in your application as needed.
|
| 4 |
+
*****************************************
|
| 5 |
+
NCCL version 2.25.1+cuda12.8
|
| 6 |
+
{
|
| 7 |
+
"device": "cuda:0",
|
| 8 |
+
"rank": 0,
|
| 9 |
+
"world_size": 4,
|
| 10 |
+
"samples": "owt_cached_chunks:8734897",
|
| 11 |
+
"vocab_size": 50257,
|
| 12 |
+
"tokenizer_vocab_size": 50257,
|
| 13 |
+
"save_dir": "runs/lta_owt_gpt2cached_len1024_p05_b64_ckpt_fixed_bench4gpu_20260513_153110",
|
| 14 |
+
"batch_size": 64,
|
| 15 |
+
"grad_accum": 2,
|
| 16 |
+
"effective_batch_size": 512,
|
| 17 |
+
"global_batch_size": 512,
|
| 18 |
+
"lr_schedule": "cosine",
|
| 19 |
+
"optimizer": "adamw",
|
| 20 |
+
"warmup_steps": 2,
|
| 21 |
+
"min_lr": 6e-05,
|
| 22 |
+
"weight_decay": 0.1,
|
| 23 |
+
"adamw_param_groups": "nanogpt",
|
| 24 |
+
"adam_beta1": 0.9,
|
| 25 |
+
"adam_beta2": 0.95,
|
| 26 |
+
"adam_eps": 1e-08,
|
| 27 |
+
"muon_momentum": 0.95,
|
| 28 |
+
"muon_ns_steps": 5,
|
| 29 |
+
"muon_update_scale": 1.0,
|
| 30 |
+
"ema_decay": 0.0,
|
| 31 |
+
"ema_start_step": 0,
|
| 32 |
+
"model_type": "ddit",
|
| 33 |
+
"dual_t": true,
|
| 34 |
+
"corrupt_t_mode": "same",
|
| 35 |
+
"corrupt_min_t": 0.0,
|
| 36 |
+
"corrupt_max_t": 1.0,
|
| 37 |
+
"prefix_block_prob": 0.0,
|
| 38 |
+
"prefix_block_len": 128,
|
| 39 |
+
"dirichlet_endpoint_mode": "categorical_dual_t",
|
| 40 |
+
"dirichlet_semantic_t_mode": "same",
|
| 41 |
+
"dirichlet_semantic_t_value": 0.0,
|
| 42 |
+
"categorical_wrong_from_full_vocab": true,
|
| 43 |
+
"categorical_wrong_from_batch_valid_tokens": false,
|
| 44 |
+
"mask_mixture_original_prob": 0.0,
|
| 45 |
+
"mask_mixture_lowk_prob": 0.0,
|
| 46 |
+
"mask_mixture_lowcorrupt_prob": 0.0,
|
| 47 |
+
"mask_mixture_block_prob": 0.0,
|
| 48 |
+
"mask_mixture_all_prob": 0.0,
|
| 49 |
+
"mask_mixture_lowk_clean_tokens": "1,2,4,8,16,32,64",
|
| 50 |
+
"mask_mixture_lowcorrupt_tokens": "1,2,4,8,16,32,64",
|
| 51 |
+
"mask_mixture_block_tokens": "64,128",
|
| 52 |
+
"simplex_bridge_sampler": "dirichlet",
|
| 53 |
+
"logistic_normal_sigma_min": 0.18,
|
| 54 |
+
"logistic_normal_sigma_max": 2.2,
|
| 55 |
+
"logistic_normal_tau_min": 0.65,
|
| 56 |
+
"logistic_normal_tau_max": 1.15,
|
| 57 |
+
"torch_compile": false,
|
| 58 |
+
"compile_mode": "max-autotune",
|
| 59 |
+
"state_format": "prob",
|
| 60 |
+
"target_loss": "hard_ce",
|
| 61 |
+
"meanflow_weight": 0.0,
|
| 62 |
+
"rollout_train_prob": 0.5,
|
| 63 |
+
"rollout_train_steps": 1,
|
| 64 |
+
"rollout_train_infer_steps": 64,
|
| 65 |
+
"rollout_train_temp": 1.45,
|
| 66 |
+
"rollout_train_max_gamma": 1.0,
|
| 67 |
+
"rollout_train_corrupt_only": true,
|
| 68 |
+
"rollout_train_samplewise": false,
|
| 69 |
+
"rollout_train_compute_always": false,
|
| 70 |
+
"bridge_noise_init": "logistic_normal",
|
| 71 |
+
"noise_sigma": -1.0,
|
| 72 |
+
"allow_tf32": true,
|
| 73 |
+
"activation_checkpointing": true,
|
| 74 |
+
"activation_checkpoint_interval": 1,
|
| 75 |
+
"ddp_static_graph": false,
|
| 76 |
+
"ddp_gradient_as_bucket_view": true,
|
| 77 |
+
"blocking_data_transfer": false,
|
| 78 |
+
"dataloader_prefetch_factor": 4,
|
| 79 |
+
"full_train_stats": false,
|
| 80 |
+
"record_pad_truncate": false,
|
| 81 |
+
"record_add_eos": false,
|
| 82 |
+
"record_add_special_tokens": false,
|
| 83 |
+
"record_pad_token": "pad",
|
| 84 |
+
"record_shuffle_buffer": 10000,
|
| 85 |
+
"wrap": true,
|
| 86 |
+
"wrap_mode": "stream",
|
| 87 |
+
"wrap_record_buffer_size": 200,
|
| 88 |
+
"owt_cached_chunks": true,
|
| 89 |
+
"owt_chunk_cache_dir": "/e2e-data/evad-tech-vla/wanghan58/data/small_benchmarks/langflow_2604_11748/openwebtext_lta_cached_chunks/gpt2_len1024_train_minus_100k",
|
| 90 |
+
"owt_chunk_cache_rebuild": false,
|
| 91 |
+
"owt_chunk_cache_write_batch": 4096,
|
| 92 |
+
"owt_exact_repeat_per_chunk": 0,
|
| 93 |
+
"online_chunk_shuffle": false,
|
| 94 |
+
"online_chunk_shuffle_buffer": 10000,
|
| 95 |
+
"openwebtext_split": "train_minus_100k",
|
| 96 |
+
"detokenizer": "auto",
|
| 97 |
+
"resolved_detokenizer": null,
|
| 98 |
+
"num_workers": 8,
|
| 99 |
+
"latest_every": 100000,
|
| 100 |
+
"resume_path": ""
|
| 101 |
+
}
|
| 102 |
+
[rank0]: Traceback (most recent call last):
|
| 103 |
+
[rank0]: File "/e2e-data/evad-tech-vla/wanghan58/workspace/LTA_openwebtext_dualt/train.py", line 1540, in <module>
|
| 104 |
+
[rank0]: main()
|
| 105 |
+
[rank0]: File "/e2e-data/evad-tech-vla/wanghan58/workspace/LTA_openwebtext_dualt/train.py", line 1459, in main
|
| 106 |
+
[rank0]: loss.backward()
|
| 107 |
+
[rank0]: File "/usr/local/lib/python3.12/dist-packages/torch/_tensor.py", line 648, in backward
|
| 108 |
+
[rank0]: torch.autograd.backward(
|
| 109 |
+
[rank0]: File "/usr/local/lib/python3.12/dist-packages/torch/autograd/__init__.py", line 347, in backward
|
| 110 |
+
[rank0]: _engine_run_backward(
|
| 111 |
+
[rank0]: File "/usr/local/lib/python3.12/dist-packages/torch/autograd/graph.py", line 823, in _engine_run_backward
|
| 112 |
+
[rank0]: return Variable._execution_engine.run_backward( # Calls into the C++ engine to run the backward pass
|
| 113 |
+
[rank0]: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| 114 |
+
[rank0]: RuntimeError: t() expects a tensor with <= 2 dimensions, but self is 3D
|
| 115 |
+
[rank1]: Traceback (most recent call last):
|
| 116 |
+
[rank1]: File "/e2e-data/evad-tech-vla/wanghan58/workspace/LTA_openwebtext_dualt/train.py", line 1540, in <module>
|
| 117 |
+
[rank1]: main()
|
| 118 |
+
[rank1]: File "/e2e-data/evad-tech-vla/wanghan58/workspace/LTA_openwebtext_dualt/train.py", line 1459, in main
|
| 119 |
+
[rank1]: loss.backward()
|
| 120 |
+
[rank1]: File "/usr/local/lib/python3.12/dist-packages/torch/_tensor.py", line 648, in backward
|
| 121 |
+
[rank1]: torch.autograd.backward(
|
| 122 |
+
[rank1]: File "/usr/local/lib/python3.12/dist-packages/torch/autograd/__init__.py", line 347, in backward
|
| 123 |
+
[rank1]: _engine_run_backward(
|
| 124 |
+
[rank1]: File "/usr/local/lib/python3.12/dist-packages/torch/autograd/graph.py", line 823, in _engine_run_backward
|
| 125 |
+
[rank1]: return Variable._execution_engine.run_backward( # Calls into the C++ engine to run the backward pass
|
| 126 |
+
[rank1]: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| 127 |
+
[rank1]: RuntimeError: t() expects a tensor with <= 2 dimensions, but self is 3D
|
| 128 |
+
[rank3]: Traceback (most recent call last):
|
| 129 |
+
[rank3]: File "/e2e-data/evad-tech-vla/wanghan58/workspace/LTA_openwebtext_dualt/train.py", line 1540, in <module>
|
| 130 |
+
[rank3]: main()
|
| 131 |
+
[rank3]: File "/e2e-data/evad-tech-vla/wanghan58/workspace/LTA_openwebtext_dualt/train.py", line 1459, in main
|
| 132 |
+
[rank3]: loss.backward()
|
| 133 |
+
[rank3]: File "/usr/local/lib/python3.12/dist-packages/torch/_tensor.py", line 648, in backward
|
| 134 |
+
[rank3]: torch.autograd.backward(
|
| 135 |
+
[rank3]: File "/usr/local/lib/python3.12/dist-packages/torch/autograd/__init__.py", line 347, in backward
|
| 136 |
+
[rank3]: _engine_run_backward(
|
| 137 |
+
[rank3]: File "/usr/local/lib/python3.12/dist-packages/torch/autograd/graph.py", line 823, in _engine_run_backward
|
| 138 |
+
[rank3]: return Variable._execution_engine.run_backward( # Calls into the C++ engine to run the backward pass
|
| 139 |
+
[rank3]: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| 140 |
+
[rank3]: RuntimeError: t() expects a tensor with <= 2 dimensions, but self is 3D
|
| 141 |
+
[rank2]: Traceback (most recent call last):
|
| 142 |
+
[rank2]: File "/e2e-data/evad-tech-vla/wanghan58/workspace/LTA_openwebtext_dualt/train.py", line 1540, in <module>
|
| 143 |
+
[rank2]: main()
|
| 144 |
+
[rank2]: File "/e2e-data/evad-tech-vla/wanghan58/workspace/LTA_openwebtext_dualt/train.py", line 1459, in main
|
| 145 |
+
[rank2]: loss.backward()
|
| 146 |
+
[rank2]: File "/usr/local/lib/python3.12/dist-packages/torch/_tensor.py", line 648, in backward
|
| 147 |
+
[rank2]: torch.autograd.backward(
|
| 148 |
+
[rank2]: File "/usr/local/lib/python3.12/dist-packages/torch/autograd/__init__.py", line 347, in backward
|
| 149 |
+
[rank2]: _engine_run_backward(
|
| 150 |
+
[rank2]: File "/usr/local/lib/python3.12/dist-packages/torch/autograd/graph.py", line 823, in _engine_run_backward
|
| 151 |
+
[rank2]: return Variable._execution_engine.run_backward( # Calls into the C++ engine to run the backward pass
|
| 152 |
+
[rank2]: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| 153 |
+
[rank2]: RuntimeError: t() expects a tensor with <= 2 dimensions, but self is 3D
|
| 154 |
+
[rank0]:[W513 15:31:59.534670818 ProcessGroupNCCL.cpp:1487] Warning: WARNING: destroy_process_group() was not called before program exit, which can leak resources. For more info, please see https://pytorch.org/docs/stable/distributed.html#shutdown (function operator())
|
| 155 |
+
W0513 15:32:00.079000 638480 torch/distributed/elastic/multiprocessing/api.py:898] Sending process 638547 closing signal SIGTERM
|
| 156 |
+
W0513 15:32:00.080000 638480 torch/distributed/elastic/multiprocessing/api.py:898] Sending process 638549 closing signal SIGTERM
|
| 157 |
+
W0513 15:32:00.080000 638480 torch/distributed/elastic/multiprocessing/api.py:898] Sending process 638550 closing signal SIGTERM
|
| 158 |
+
E0513 15:32:00.446000 638480 torch/distributed/elastic/multiprocessing/api.py:870] failed (exitcode: 1) local_rank: 1 (pid: 638548) of binary: /usr/bin/python
|
| 159 |
+
Traceback (most recent call last):
|
| 160 |
+
File "<frozen runpy>", line 198, in _run_module_as_main
|
| 161 |
+
File "<frozen runpy>", line 88, in _run_code
|
| 162 |
+
File "/usr/local/lib/python3.12/dist-packages/torch/distributed/run.py", line 922, in <module>
|
| 163 |
+
main()
|
| 164 |
+
File "/usr/local/lib/python3.12/dist-packages/torch/distributed/elastic/multiprocessing/errors/__init__.py", line 355, in wrapper
|
| 165 |
+
return f(*args, **kwargs)
|
| 166 |
+
^^^^^^^^^^^^^^^^^^
|
| 167 |
+
File "/usr/local/lib/python3.12/dist-packages/torch/distributed/run.py", line 918, in main
|
| 168 |
+
run(args)
|
| 169 |
+
File "/usr/local/lib/python3.12/dist-packages/torch/distributed/run.py", line 909, in run
|
| 170 |
+
elastic_launch(
|
| 171 |
+
File "/usr/local/lib/python3.12/dist-packages/torch/distributed/launcher/api.py", line 139, in __call__
|
| 172 |
+
return launch_agent(self._config, self._entrypoint, list(args))
|
| 173 |
+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| 174 |
+
File "/usr/local/lib/python3.12/dist-packages/torch/distributed/launcher/api.py", line 270, in launch_agent
|
| 175 |
+
raise ChildFailedError(
|
| 176 |
+
torch.distributed.elastic.multiprocessing.errors.ChildFailedError:
|
| 177 |
+
============================================================
|
| 178 |
+
train.py FAILED
|
| 179 |
+
------------------------------------------------------------
|
| 180 |
+
Failures:
|
| 181 |
+
<NO_OTHER_FAILURES>
|
| 182 |
+
------------------------------------------------------------
|
| 183 |
+
Root Cause (first observed failure):
|
| 184 |
+
[0]:
|
| 185 |
+
time : 2026-05-13_15:32:00
|
| 186 |
+
host : localhost
|
| 187 |
+
rank : 1 (local_rank: 1)
|
| 188 |
+
exitcode : 1 (pid: 638548)
|
| 189 |
+
error_file: <N/A>
|
| 190 |
+
traceback : To enable traceback see: https://pytorch.org/docs/stable/elastic/errors.html
|
| 191 |
+
============================================================
|
LTA_openwebtext_dualt/logs/lta_owt_gpt2cached_len1024_rollout1_p05_b64_mlpckpt_bench4gpu_20260513_161317.log
ADDED
|
@@ -0,0 +1,230 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
NCCL version 2.25.1+cuda12.8
|
| 2 |
+
{
|
| 3 |
+
"device": "cuda:0",
|
| 4 |
+
"rank": 0,
|
| 5 |
+
"world_size": 4,
|
| 6 |
+
"samples": "owt_cached_chunks:8734897",
|
| 7 |
+
"vocab_size": 50257,
|
| 8 |
+
"tokenizer_vocab_size": 50257,
|
| 9 |
+
"save_dir": "runs/lta_owt_gpt2cached_len1024_rollout1_p05_b64_mlpckpt_bench4gpu_20260513_161317",
|
| 10 |
+
"batch_size": 64,
|
| 11 |
+
"grad_accum": 1,
|
| 12 |
+
"effective_batch_size": 256,
|
| 13 |
+
"global_batch_size": 256,
|
| 14 |
+
"lr_schedule": "cosine",
|
| 15 |
+
"optimizer": "adamw",
|
| 16 |
+
"warmup_steps": 2,
|
| 17 |
+
"min_lr": 6e-05,
|
| 18 |
+
"weight_decay": 0.1,
|
| 19 |
+
"adamw_param_groups": "nanogpt",
|
| 20 |
+
"adam_beta1": 0.9,
|
| 21 |
+
"adam_beta2": 0.95,
|
| 22 |
+
"adam_eps": 1e-08,
|
| 23 |
+
"muon_momentum": 0.95,
|
| 24 |
+
"muon_ns_steps": 5,
|
| 25 |
+
"muon_update_scale": 1.0,
|
| 26 |
+
"ema_decay": 0.0,
|
| 27 |
+
"ema_start_step": 0,
|
| 28 |
+
"model_type": "ddit",
|
| 29 |
+
"dual_t": true,
|
| 30 |
+
"corrupt_t_mode": "same",
|
| 31 |
+
"corrupt_min_t": 0.0,
|
| 32 |
+
"corrupt_max_t": 1.0,
|
| 33 |
+
"prefix_block_prob": 0.0,
|
| 34 |
+
"prefix_block_len": 128,
|
| 35 |
+
"dirichlet_endpoint_mode": "categorical_dual_t",
|
| 36 |
+
"dirichlet_semantic_t_mode": "same",
|
| 37 |
+
"dirichlet_semantic_t_value": 0.0,
|
| 38 |
+
"categorical_wrong_from_full_vocab": true,
|
| 39 |
+
"categorical_wrong_from_batch_valid_tokens": false,
|
| 40 |
+
"mask_mixture_original_prob": 0.0,
|
| 41 |
+
"mask_mixture_lowk_prob": 0.0,
|
| 42 |
+
"mask_mixture_lowcorrupt_prob": 0.0,
|
| 43 |
+
"mask_mixture_block_prob": 0.0,
|
| 44 |
+
"mask_mixture_all_prob": 0.0,
|
| 45 |
+
"mask_mixture_lowk_clean_tokens": "1,2,4,8,16,32,64",
|
| 46 |
+
"mask_mixture_lowcorrupt_tokens": "1,2,4,8,16,32,64",
|
| 47 |
+
"mask_mixture_block_tokens": "64,128",
|
| 48 |
+
"simplex_bridge_sampler": "dirichlet",
|
| 49 |
+
"logistic_normal_sigma_min": 0.18,
|
| 50 |
+
"logistic_normal_sigma_max": 2.2,
|
| 51 |
+
"logistic_normal_tau_min": 0.65,
|
| 52 |
+
"logistic_normal_tau_max": 1.15,
|
| 53 |
+
"torch_compile": false,
|
| 54 |
+
"compile_mode": "max-autotune",
|
| 55 |
+
"state_format": "prob",
|
| 56 |
+
"target_loss": "hard_ce",
|
| 57 |
+
"meanflow_weight": 0.0,
|
| 58 |
+
"rollout_train_prob": 0.5,
|
| 59 |
+
"rollout_train_steps": 1,
|
| 60 |
+
"rollout_train_infer_steps": 64,
|
| 61 |
+
"rollout_train_temp": 1.45,
|
| 62 |
+
"rollout_train_max_gamma": 1.0,
|
| 63 |
+
"rollout_train_corrupt_only": true,
|
| 64 |
+
"rollout_train_samplewise": false,
|
| 65 |
+
"rollout_train_compute_always": false,
|
| 66 |
+
"bridge_noise_init": "logistic_normal",
|
| 67 |
+
"noise_sigma": -1.0,
|
| 68 |
+
"allow_tf32": true,
|
| 69 |
+
"activation_checkpointing": true,
|
| 70 |
+
"activation_checkpoint_interval": 1,
|
| 71 |
+
"activation_checkpoint_scope": "mlp",
|
| 72 |
+
"ddp_static_graph": false,
|
| 73 |
+
"ddp_gradient_as_bucket_view": true,
|
| 74 |
+
"blocking_data_transfer": false,
|
| 75 |
+
"dataloader_prefetch_factor": 4,
|
| 76 |
+
"full_train_stats": false,
|
| 77 |
+
"record_pad_truncate": false,
|
| 78 |
+
"record_add_eos": false,
|
| 79 |
+
"record_add_special_tokens": false,
|
| 80 |
+
"record_pad_token": "pad",
|
| 81 |
+
"record_shuffle_buffer": 10000,
|
| 82 |
+
"wrap": true,
|
| 83 |
+
"wrap_mode": "stream",
|
| 84 |
+
"wrap_record_buffer_size": 200,
|
| 85 |
+
"owt_cached_chunks": true,
|
| 86 |
+
"owt_chunk_cache_dir": "/e2e-data/evad-tech-vla/wanghan58/data/small_benchmarks/langflow_2604_11748/openwebtext_lta_cached_chunks/gpt2_len1024_train_minus_100k",
|
| 87 |
+
"owt_chunk_cache_rebuild": false,
|
| 88 |
+
"owt_chunk_cache_write_batch": 4096,
|
| 89 |
+
"owt_exact_repeat_per_chunk": 0,
|
| 90 |
+
"online_chunk_shuffle": false,
|
| 91 |
+
"online_chunk_shuffle_buffer": 10000,
|
| 92 |
+
"openwebtext_split": "train_minus_100k",
|
| 93 |
+
"detokenizer": "auto",
|
| 94 |
+
"resolved_detokenizer": null,
|
| 95 |
+
"num_workers": 8,
|
| 96 |
+
"latest_every": 0,
|
| 97 |
+
"resume_path": ""
|
| 98 |
+
}
|
| 99 |
+
[rank3]: Traceback (most recent call last):
|
| 100 |
+
[rank3]: File "/e2e-data/evad-tech-vla/wanghan58/workspace/LTA_openwebtext_dualt/train.py", line 1546, in <module>
|
| 101 |
+
[rank3]: main()
|
| 102 |
+
[rank3]: File "/e2e-data/evad-tech-vla/wanghan58/workspace/LTA_openwebtext_dualt/train.py", line 1465, in main
|
| 103 |
+
[rank3]: loss.backward()
|
| 104 |
+
[rank3]: File "/usr/local/lib/python3.12/dist-packages/torch/_tensor.py", line 648, in backward
|
| 105 |
+
[rank3]: torch.autograd.backward(
|
| 106 |
+
[rank3]: File "/usr/local/lib/python3.12/dist-packages/torch/autograd/__init__.py", line 347, in backward
|
| 107 |
+
[rank3]: _engine_run_backward(
|
| 108 |
+
[rank3]: File "/usr/local/lib/python3.12/dist-packages/torch/autograd/graph.py", line 823, in _engine_run_backward
|
| 109 |
+
[rank3]: return Variable._execution_engine.run_backward( # Calls into the C++ engine to run the backward pass
|
| 110 |
+
[rank3]: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| 111 |
+
[rank3]: RuntimeError: CUDA error: CUBLAS_STATUS_ALLOC_FAILED when calling `cublasCreate(handle)`
|
| 112 |
+
[rank0]: Traceback (most recent call last):
|
| 113 |
+
[rank0]: File "/e2e-data/evad-tech-vla/wanghan58/workspace/LTA_openwebtext_dualt/train.py", line 1546, in <module>
|
| 114 |
+
[rank0]: main()
|
| 115 |
+
[rank0]: File "/e2e-data/evad-tech-vla/wanghan58/workspace/LTA_openwebtext_dualt/train.py", line 1465, in main
|
| 116 |
+
[rank0]: loss.backward()
|
| 117 |
+
[rank0]: File "/usr/local/lib/python3.12/dist-packages/torch/_tensor.py", line 648, in backward
|
| 118 |
+
[rank0]: torch.autograd.backward(
|
| 119 |
+
[rank0]: File "/usr/local/lib/python3.12/dist-packages/torch/autograd/__init__.py", line 347, in backward
|
| 120 |
+
[rank0]: _engine_run_backward(
|
| 121 |
+
[rank0]: File "/usr/local/lib/python3.12/dist-packages/torch/autograd/graph.py", line 823, in _engine_run_backward
|
| 122 |
+
[rank0]: return Variable._execution_engine.run_backward( # Calls into the C++ engine to run the backward pass
|
| 123 |
+
[rank0]: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| 124 |
+
[rank0]: File "/usr/local/lib/python3.12/dist-packages/torch/utils/checkpoint.py", line 1128, in unpack_hook
|
| 125 |
+
[rank0]: frame.check_recomputed_tensors_match(gid)
|
| 126 |
+
[rank0]: File "/usr/local/lib/python3.12/dist-packages/torch/utils/checkpoint.py", line 902, in check_recomputed_tensors_match
|
| 127 |
+
[rank0]: raise CheckpointError(
|
| 128 |
+
[rank0]: torch.utils.checkpoint.CheckpointError: torch.utils.checkpoint: Recomputed values for the following tensors have different metadata than during the forward pass.
|
| 129 |
+
[rank0]: tensor at position 0:
|
| 130 |
+
[rank0]: saved metadata: {'shape': torch.Size([768, 3072]), 'dtype': torch.bfloat16, 'device': device(type='cuda', index=0)}
|
| 131 |
+
[rank0]: recomputed metadata: {'shape': torch.Size([65536, 768]), 'dtype': torch.bfloat16, 'device': device(type='cuda', index=0)}
|
| 132 |
+
[rank0]: tensor at position 1:
|
| 133 |
+
[rank0]: saved metadata: {'shape': torch.Size([64, 1024, 3072]), 'dtype': torch.bfloat16, 'device': device(type='cuda', index=0)}
|
| 134 |
+
[rank0]: recomputed metadata: {'shape': torch.Size([768, 3072]), 'dtype': torch.bfloat16, 'device': device(type='cuda', index=0)}
|
| 135 |
+
[rank0]: tensor at position 2:
|
| 136 |
+
[rank0]: saved metadata: {'shape': torch.Size([3072, 768]), 'dtype': torch.bfloat16, 'device': device(type='cuda', index=0)}
|
| 137 |
+
[rank0]: recomputed metadata: {'shape': torch.Size([64, 1024, 3072]), 'dtype': torch.bfloat16, 'device': device(type='cuda', index=0)}
|
| 138 |
+
|
| 139 |
+
[rank2]: Traceback (most recent call last):
|
| 140 |
+
[rank2]: File "/e2e-data/evad-tech-vla/wanghan58/workspace/LTA_openwebtext_dualt/train.py", line 1546, in <module>
|
| 141 |
+
[rank2]: main()
|
| 142 |
+
[rank2]: File "/e2e-data/evad-tech-vla/wanghan58/workspace/LTA_openwebtext_dualt/train.py", line 1465, in main
|
| 143 |
+
[rank2]: loss.backward()
|
| 144 |
+
[rank2]: File "/usr/local/lib/python3.12/dist-packages/torch/_tensor.py", line 648, in backward
|
| 145 |
+
[rank2]: torch.autograd.backward(
|
| 146 |
+
[rank2]: File "/usr/local/lib/python3.12/dist-packages/torch/autograd/__init__.py", line 347, in backward
|
| 147 |
+
[rank2]: _engine_run_backward(
|
| 148 |
+
[rank2]: File "/usr/local/lib/python3.12/dist-packages/torch/autograd/graph.py", line 823, in _engine_run_backward
|
| 149 |
+
[rank2]: return Variable._execution_engine.run_backward( # Calls into the C++ engine to run the backward pass
|
| 150 |
+
[rank2]: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| 151 |
+
[rank2]: File "/usr/local/lib/python3.12/dist-packages/torch/utils/checkpoint.py", line 1128, in unpack_hook
|
| 152 |
+
[rank2]: frame.check_recomputed_tensors_match(gid)
|
| 153 |
+
[rank2]: File "/usr/local/lib/python3.12/dist-packages/torch/utils/checkpoint.py", line 902, in check_recomputed_tensors_match
|
| 154 |
+
[rank2]: raise CheckpointError(
|
| 155 |
+
[rank2]: torch.utils.checkpoint.CheckpointError: torch.utils.checkpoint: Recomputed values for the following tensors have different metadata than during the forward pass.
|
| 156 |
+
[rank2]: tensor at position 0:
|
| 157 |
+
[rank2]: saved metadata: {'shape': torch.Size([768, 3072]), 'dtype': torch.bfloat16, 'device': device(type='cuda', index=2)}
|
| 158 |
+
[rank2]: recomputed metadata: {'shape': torch.Size([65536, 768]), 'dtype': torch.bfloat16, 'device': device(type='cuda', index=2)}
|
| 159 |
+
[rank2]: tensor at position 1:
|
| 160 |
+
[rank2]: saved metadata: {'shape': torch.Size([64, 1024, 3072]), 'dtype': torch.bfloat16, 'device': device(type='cuda', index=2)}
|
| 161 |
+
[rank2]: recomputed metadata: {'shape': torch.Size([768, 3072]), 'dtype': torch.bfloat16, 'device': device(type='cuda', index=2)}
|
| 162 |
+
[rank2]: tensor at position 2:
|
| 163 |
+
[rank2]: saved metadata: {'shape': torch.Size([3072, 768]), 'dtype': torch.bfloat16, 'device': device(type='cuda', index=2)}
|
| 164 |
+
[rank2]: recomputed metadata: {'shape': torch.Size([64, 1024, 3072]), 'dtype': torch.bfloat16, 'device': device(type='cuda', index=2)}
|
| 165 |
+
|
| 166 |
+
[rank1]: Traceback (most recent call last):
|
| 167 |
+
[rank1]: File "/e2e-data/evad-tech-vla/wanghan58/workspace/LTA_openwebtext_dualt/train.py", line 1546, in <module>
|
| 168 |
+
[rank1]: main()
|
| 169 |
+
[rank1]: File "/e2e-data/evad-tech-vla/wanghan58/workspace/LTA_openwebtext_dualt/train.py", line 1465, in main
|
| 170 |
+
[rank1]: loss.backward()
|
| 171 |
+
[rank1]: File "/usr/local/lib/python3.12/dist-packages/torch/_tensor.py", line 648, in backward
|
| 172 |
+
[rank1]: torch.autograd.backward(
|
| 173 |
+
[rank1]: File "/usr/local/lib/python3.12/dist-packages/torch/autograd/__init__.py", line 347, in backward
|
| 174 |
+
[rank1]: _engine_run_backward(
|
| 175 |
+
[rank1]: File "/usr/local/lib/python3.12/dist-packages/torch/autograd/graph.py", line 823, in _engine_run_backward
|
| 176 |
+
[rank1]: return Variable._execution_engine.run_backward( # Calls into the C++ engine to run the backward pass
|
| 177 |
+
[rank1]: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| 178 |
+
[rank1]: File "/usr/local/lib/python3.12/dist-packages/torch/utils/checkpoint.py", line 1128, in unpack_hook
|
| 179 |
+
[rank1]: frame.check_recomputed_tensors_match(gid)
|
| 180 |
+
[rank1]: File "/usr/local/lib/python3.12/dist-packages/torch/utils/checkpoint.py", line 902, in check_recomputed_tensors_match
|
| 181 |
+
[rank1]: raise CheckpointError(
|
| 182 |
+
[rank1]: torch.utils.checkpoint.CheckpointError: torch.utils.checkpoint: Recomputed values for the following tensors have different metadata than during the forward pass.
|
| 183 |
+
[rank1]: tensor at position 0:
|
| 184 |
+
[rank1]: saved metadata: {'shape': torch.Size([768, 3072]), 'dtype': torch.bfloat16, 'device': device(type='cuda', index=1)}
|
| 185 |
+
[rank1]: recomputed metadata: {'shape': torch.Size([65536, 768]), 'dtype': torch.bfloat16, 'device': device(type='cuda', index=1)}
|
| 186 |
+
[rank1]: tensor at position 1:
|
| 187 |
+
[rank1]: saved metadata: {'shape': torch.Size([64, 1024, 3072]), 'dtype': torch.bfloat16, 'device': device(type='cuda', index=1)}
|
| 188 |
+
[rank1]: recomputed metadata: {'shape': torch.Size([768, 3072]), 'dtype': torch.bfloat16, 'device': device(type='cuda', index=1)}
|
| 189 |
+
[rank1]: tensor at position 2:
|
| 190 |
+
[rank1]: saved metadata: {'shape': torch.Size([3072, 768]), 'dtype': torch.bfloat16, 'device': device(type='cuda', index=1)}
|
| 191 |
+
[rank1]: recomputed metadata: {'shape': torch.Size([64, 1024, 3072]), 'dtype': torch.bfloat16, 'device': device(type='cuda', index=1)}
|
| 192 |
+
|
| 193 |
+
[rank0]:[W513 16:14:07.285091833 ProcessGroupNCCL.cpp:1487] Warning: WARNING: destroy_process_group() was not called before program exit, which can leak resources. For more info, please see https://pytorch.org/docs/stable/distributed.html#shutdown (function operator())
|
| 194 |
+
W0513 16:14:08.602000 659091 torch/distributed/elastic/multiprocessing/api.py:898] Sending process 659096 closing signal SIGTERM
|
| 195 |
+
W0513 16:14:08.603000 659091 torch/distributed/elastic/multiprocessing/api.py:898] Sending process 659097 closing signal SIGTERM
|
| 196 |
+
W0513 16:14:08.603000 659091 torch/distributed/elastic/multiprocessing/api.py:898] Sending process 659098 closing signal SIGTERM
|
| 197 |
+
E0513 16:14:09.447000 659091 torch/distributed/elastic/multiprocessing/api.py:870] failed (exitcode: 1) local_rank: 0 (pid: 659095) of binary: /usr/bin/python
|
| 198 |
+
Traceback (most recent call last):
|
| 199 |
+
File "<frozen runpy>", line 198, in _run_module_as_main
|
| 200 |
+
File "<frozen runpy>", line 88, in _run_code
|
| 201 |
+
File "/usr/local/lib/python3.12/dist-packages/torch/distributed/run.py", line 922, in <module>
|
| 202 |
+
main()
|
| 203 |
+
File "/usr/local/lib/python3.12/dist-packages/torch/distributed/elastic/multiprocessing/errors/__init__.py", line 355, in wrapper
|
| 204 |
+
return f(*args, **kwargs)
|
| 205 |
+
^^^^^^^^^^^^^^^^^^
|
| 206 |
+
File "/usr/local/lib/python3.12/dist-packages/torch/distributed/run.py", line 918, in main
|
| 207 |
+
run(args)
|
| 208 |
+
File "/usr/local/lib/python3.12/dist-packages/torch/distributed/run.py", line 909, in run
|
| 209 |
+
elastic_launch(
|
| 210 |
+
File "/usr/local/lib/python3.12/dist-packages/torch/distributed/launcher/api.py", line 139, in __call__
|
| 211 |
+
return launch_agent(self._config, self._entrypoint, list(args))
|
| 212 |
+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| 213 |
+
File "/usr/local/lib/python3.12/dist-packages/torch/distributed/launcher/api.py", line 270, in launch_agent
|
| 214 |
+
raise ChildFailedError(
|
| 215 |
+
torch.distributed.elastic.multiprocessing.errors.ChildFailedError:
|
| 216 |
+
============================================================
|
| 217 |
+
train.py FAILED
|
| 218 |
+
------------------------------------------------------------
|
| 219 |
+
Failures:
|
| 220 |
+
<NO_OTHER_FAILURES>
|
| 221 |
+
------------------------------------------------------------
|
| 222 |
+
Root Cause (first observed failure):
|
| 223 |
+
[0]:
|
| 224 |
+
time : 2026-05-13_16:14:08
|
| 225 |
+
host : localhost
|
| 226 |
+
rank : 0 (local_rank: 0)
|
| 227 |
+
exitcode : 1 (pid: 659095)
|
| 228 |
+
error_file: <N/A>
|
| 229 |
+
traceback : To enable traceback see: https://pytorch.org/docs/stable/elastic/errors.html
|
| 230 |
+
============================================================
|
LTA_openwebtext_dualt/logs/owt_fully_path_anchor_refine_step118k_n8.log
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/numpy/lib/arrayterator.py
ADDED
|
@@ -0,0 +1,219 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""
|
| 2 |
+
A buffered iterator for big arrays.
|
| 3 |
+
|
| 4 |
+
This module solves the problem of iterating over a big file-based array
|
| 5 |
+
without having to read it into memory. The `Arrayterator` class wraps
|
| 6 |
+
an array object, and when iterated it will return sub-arrays with at most
|
| 7 |
+
a user-specified number of elements.
|
| 8 |
+
|
| 9 |
+
"""
|
| 10 |
+
from operator import mul
|
| 11 |
+
from functools import reduce
|
| 12 |
+
|
| 13 |
+
__all__ = ['Arrayterator']
|
| 14 |
+
|
| 15 |
+
|
| 16 |
+
class Arrayterator:
|
| 17 |
+
"""
|
| 18 |
+
Buffered iterator for big arrays.
|
| 19 |
+
|
| 20 |
+
`Arrayterator` creates a buffered iterator for reading big arrays in small
|
| 21 |
+
contiguous blocks. The class is useful for objects stored in the
|
| 22 |
+
file system. It allows iteration over the object *without* reading
|
| 23 |
+
everything in memory; instead, small blocks are read and iterated over.
|
| 24 |
+
|
| 25 |
+
`Arrayterator` can be used with any object that supports multidimensional
|
| 26 |
+
slices. This includes NumPy arrays, but also variables from
|
| 27 |
+
Scientific.IO.NetCDF or pynetcdf for example.
|
| 28 |
+
|
| 29 |
+
Parameters
|
| 30 |
+
----------
|
| 31 |
+
var : array_like
|
| 32 |
+
The object to iterate over.
|
| 33 |
+
buf_size : int, optional
|
| 34 |
+
The buffer size. If `buf_size` is supplied, the maximum amount of
|
| 35 |
+
data that will be read into memory is `buf_size` elements.
|
| 36 |
+
Default is None, which will read as many element as possible
|
| 37 |
+
into memory.
|
| 38 |
+
|
| 39 |
+
Attributes
|
| 40 |
+
----------
|
| 41 |
+
var
|
| 42 |
+
buf_size
|
| 43 |
+
start
|
| 44 |
+
stop
|
| 45 |
+
step
|
| 46 |
+
shape
|
| 47 |
+
flat
|
| 48 |
+
|
| 49 |
+
See Also
|
| 50 |
+
--------
|
| 51 |
+
ndenumerate : Multidimensional array iterator.
|
| 52 |
+
flatiter : Flat array iterator.
|
| 53 |
+
memmap : Create a memory-map to an array stored in a binary file on disk.
|
| 54 |
+
|
| 55 |
+
Notes
|
| 56 |
+
-----
|
| 57 |
+
The algorithm works by first finding a "running dimension", along which
|
| 58 |
+
the blocks will be extracted. Given an array of dimensions
|
| 59 |
+
``(d1, d2, ..., dn)``, e.g. if `buf_size` is smaller than ``d1``, the
|
| 60 |
+
first dimension will be used. If, on the other hand,
|
| 61 |
+
``d1 < buf_size < d1*d2`` the second dimension will be used, and so on.
|
| 62 |
+
Blocks are extracted along this dimension, and when the last block is
|
| 63 |
+
returned the process continues from the next dimension, until all
|
| 64 |
+
elements have been read.
|
| 65 |
+
|
| 66 |
+
Examples
|
| 67 |
+
--------
|
| 68 |
+
>>> a = np.arange(3 * 4 * 5 * 6).reshape(3, 4, 5, 6)
|
| 69 |
+
>>> a_itor = np.lib.Arrayterator(a, 2)
|
| 70 |
+
>>> a_itor.shape
|
| 71 |
+
(3, 4, 5, 6)
|
| 72 |
+
|
| 73 |
+
Now we can iterate over ``a_itor``, and it will return arrays of size
|
| 74 |
+
two. Since `buf_size` was smaller than any dimension, the first
|
| 75 |
+
dimension will be iterated over first:
|
| 76 |
+
|
| 77 |
+
>>> for subarr in a_itor:
|
| 78 |
+
... if not subarr.all():
|
| 79 |
+
... print(subarr, subarr.shape) # doctest: +SKIP
|
| 80 |
+
>>> # [[[[0 1]]]] (1, 1, 1, 2)
|
| 81 |
+
|
| 82 |
+
"""
|
| 83 |
+
|
| 84 |
+
def __init__(self, var, buf_size=None):
|
| 85 |
+
self.var = var
|
| 86 |
+
self.buf_size = buf_size
|
| 87 |
+
|
| 88 |
+
self.start = [0 for dim in var.shape]
|
| 89 |
+
self.stop = [dim for dim in var.shape]
|
| 90 |
+
self.step = [1 for dim in var.shape]
|
| 91 |
+
|
| 92 |
+
def __getattr__(self, attr):
|
| 93 |
+
return getattr(self.var, attr)
|
| 94 |
+
|
| 95 |
+
def __getitem__(self, index):
|
| 96 |
+
"""
|
| 97 |
+
Return a new arrayterator.
|
| 98 |
+
|
| 99 |
+
"""
|
| 100 |
+
# Fix index, handling ellipsis and incomplete slices.
|
| 101 |
+
if not isinstance(index, tuple):
|
| 102 |
+
index = (index,)
|
| 103 |
+
fixed = []
|
| 104 |
+
length, dims = len(index), self.ndim
|
| 105 |
+
for slice_ in index:
|
| 106 |
+
if slice_ is Ellipsis:
|
| 107 |
+
fixed.extend([slice(None)] * (dims-length+1))
|
| 108 |
+
length = len(fixed)
|
| 109 |
+
elif isinstance(slice_, int):
|
| 110 |
+
fixed.append(slice(slice_, slice_+1, 1))
|
| 111 |
+
else:
|
| 112 |
+
fixed.append(slice_)
|
| 113 |
+
index = tuple(fixed)
|
| 114 |
+
if len(index) < dims:
|
| 115 |
+
index += (slice(None),) * (dims-len(index))
|
| 116 |
+
|
| 117 |
+
# Return a new arrayterator object.
|
| 118 |
+
out = self.__class__(self.var, self.buf_size)
|
| 119 |
+
for i, (start, stop, step, slice_) in enumerate(
|
| 120 |
+
zip(self.start, self.stop, self.step, index)):
|
| 121 |
+
out.start[i] = start + (slice_.start or 0)
|
| 122 |
+
out.step[i] = step * (slice_.step or 1)
|
| 123 |
+
out.stop[i] = start + (slice_.stop or stop-start)
|
| 124 |
+
out.stop[i] = min(stop, out.stop[i])
|
| 125 |
+
return out
|
| 126 |
+
|
| 127 |
+
def __array__(self):
|
| 128 |
+
"""
|
| 129 |
+
Return corresponding data.
|
| 130 |
+
|
| 131 |
+
"""
|
| 132 |
+
slice_ = tuple(slice(*t) for t in zip(
|
| 133 |
+
self.start, self.stop, self.step))
|
| 134 |
+
return self.var[slice_]
|
| 135 |
+
|
| 136 |
+
@property
|
| 137 |
+
def flat(self):
|
| 138 |
+
"""
|
| 139 |
+
A 1-D flat iterator for Arrayterator objects.
|
| 140 |
+
|
| 141 |
+
This iterator returns elements of the array to be iterated over in
|
| 142 |
+
`Arrayterator` one by one. It is similar to `flatiter`.
|
| 143 |
+
|
| 144 |
+
See Also
|
| 145 |
+
--------
|
| 146 |
+
Arrayterator
|
| 147 |
+
flatiter
|
| 148 |
+
|
| 149 |
+
Examples
|
| 150 |
+
--------
|
| 151 |
+
>>> a = np.arange(3 * 4 * 5 * 6).reshape(3, 4, 5, 6)
|
| 152 |
+
>>> a_itor = np.lib.Arrayterator(a, 2)
|
| 153 |
+
|
| 154 |
+
>>> for subarr in a_itor.flat:
|
| 155 |
+
... if not subarr:
|
| 156 |
+
... print(subarr, type(subarr))
|
| 157 |
+
...
|
| 158 |
+
0 <class 'numpy.int64'>
|
| 159 |
+
|
| 160 |
+
"""
|
| 161 |
+
for block in self:
|
| 162 |
+
yield from block.flat
|
| 163 |
+
|
| 164 |
+
@property
|
| 165 |
+
def shape(self):
|
| 166 |
+
"""
|
| 167 |
+
The shape of the array to be iterated over.
|
| 168 |
+
|
| 169 |
+
For an example, see `Arrayterator`.
|
| 170 |
+
|
| 171 |
+
"""
|
| 172 |
+
return tuple(((stop-start-1)//step+1) for start, stop, step in
|
| 173 |
+
zip(self.start, self.stop, self.step))
|
| 174 |
+
|
| 175 |
+
def __iter__(self):
|
| 176 |
+
# Skip arrays with degenerate dimensions
|
| 177 |
+
if [dim for dim in self.shape if dim <= 0]:
|
| 178 |
+
return
|
| 179 |
+
|
| 180 |
+
start = self.start[:]
|
| 181 |
+
stop = self.stop[:]
|
| 182 |
+
step = self.step[:]
|
| 183 |
+
ndims = self.var.ndim
|
| 184 |
+
|
| 185 |
+
while True:
|
| 186 |
+
count = self.buf_size or reduce(mul, self.shape)
|
| 187 |
+
|
| 188 |
+
# iterate over each dimension, looking for the
|
| 189 |
+
# running dimension (ie, the dimension along which
|
| 190 |
+
# the blocks will be built from)
|
| 191 |
+
rundim = 0
|
| 192 |
+
for i in range(ndims-1, -1, -1):
|
| 193 |
+
# if count is zero we ran out of elements to read
|
| 194 |
+
# along higher dimensions, so we read only a single position
|
| 195 |
+
if count == 0:
|
| 196 |
+
stop[i] = start[i]+1
|
| 197 |
+
elif count <= self.shape[i]:
|
| 198 |
+
# limit along this dimension
|
| 199 |
+
stop[i] = start[i] + count*step[i]
|
| 200 |
+
rundim = i
|
| 201 |
+
else:
|
| 202 |
+
# read everything along this dimension
|
| 203 |
+
stop[i] = self.stop[i]
|
| 204 |
+
stop[i] = min(self.stop[i], stop[i])
|
| 205 |
+
count = count//self.shape[i]
|
| 206 |
+
|
| 207 |
+
# yield a block
|
| 208 |
+
slice_ = tuple(slice(*t) for t in zip(start, stop, step))
|
| 209 |
+
yield self.var[slice_]
|
| 210 |
+
|
| 211 |
+
# Update start position, taking care of overflow to
|
| 212 |
+
# other dimensions
|
| 213 |
+
start[rundim] = stop[rundim] # start where we stopped
|
| 214 |
+
for i in range(ndims-1, 0, -1):
|
| 215 |
+
if start[i] >= self.stop[i]:
|
| 216 |
+
start[i] = self.start[i]
|
| 217 |
+
start[i-1] += self.step[i-1]
|
| 218 |
+
if start[0] >= self.stop[0]:
|
| 219 |
+
return
|
LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/numpy/lib/arrayterator.pyi
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from collections.abc import Generator
|
| 2 |
+
from typing import (
|
| 3 |
+
Any,
|
| 4 |
+
TypeVar,
|
| 5 |
+
Union,
|
| 6 |
+
overload,
|
| 7 |
+
)
|
| 8 |
+
|
| 9 |
+
from numpy import ndarray, dtype, generic
|
| 10 |
+
from numpy._typing import DTypeLike
|
| 11 |
+
|
| 12 |
+
# TODO: Set a shape bound once we've got proper shape support
|
| 13 |
+
_Shape = TypeVar("_Shape", bound=Any)
|
| 14 |
+
_DType = TypeVar("_DType", bound=dtype[Any])
|
| 15 |
+
_ScalarType = TypeVar("_ScalarType", bound=generic)
|
| 16 |
+
|
| 17 |
+
_Index = Union[
|
| 18 |
+
Union[ellipsis, int, slice],
|
| 19 |
+
tuple[Union[ellipsis, int, slice], ...],
|
| 20 |
+
]
|
| 21 |
+
|
| 22 |
+
__all__: list[str]
|
| 23 |
+
|
| 24 |
+
# NOTE: In reality `Arrayterator` does not actually inherit from `ndarray`,
|
| 25 |
+
# but its ``__getattr__` method does wrap around the former and thus has
|
| 26 |
+
# access to all its methods
|
| 27 |
+
|
| 28 |
+
class Arrayterator(ndarray[_Shape, _DType]):
|
| 29 |
+
var: ndarray[_Shape, _DType] # type: ignore[assignment]
|
| 30 |
+
buf_size: None | int
|
| 31 |
+
start: list[int]
|
| 32 |
+
stop: list[int]
|
| 33 |
+
step: list[int]
|
| 34 |
+
|
| 35 |
+
@property # type: ignore[misc]
|
| 36 |
+
def shape(self) -> tuple[int, ...]: ...
|
| 37 |
+
@property
|
| 38 |
+
def flat( # type: ignore[override]
|
| 39 |
+
self: ndarray[Any, dtype[_ScalarType]]
|
| 40 |
+
) -> Generator[_ScalarType, None, None]: ...
|
| 41 |
+
def __init__(
|
| 42 |
+
self, var: ndarray[_Shape, _DType], buf_size: None | int = ...
|
| 43 |
+
) -> None: ...
|
| 44 |
+
@overload
|
| 45 |
+
def __array__(self, dtype: None = ...) -> ndarray[Any, _DType]: ...
|
| 46 |
+
@overload
|
| 47 |
+
def __array__(self, dtype: DTypeLike) -> ndarray[Any, dtype[Any]]: ...
|
| 48 |
+
def __getitem__(self, index: _Index) -> Arrayterator[Any, _DType]: ...
|
| 49 |
+
def __iter__(self) -> Generator[ndarray[Any, _DType], None, None]: ...
|
LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/numpy/lib/format.py
ADDED
|
@@ -0,0 +1,976 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""
|
| 2 |
+
Binary serialization
|
| 3 |
+
|
| 4 |
+
NPY format
|
| 5 |
+
==========
|
| 6 |
+
|
| 7 |
+
A simple format for saving numpy arrays to disk with the full
|
| 8 |
+
information about them.
|
| 9 |
+
|
| 10 |
+
The ``.npy`` format is the standard binary file format in NumPy for
|
| 11 |
+
persisting a *single* arbitrary NumPy array on disk. The format stores all
|
| 12 |
+
of the shape and dtype information necessary to reconstruct the array
|
| 13 |
+
correctly even on another machine with a different architecture.
|
| 14 |
+
The format is designed to be as simple as possible while achieving
|
| 15 |
+
its limited goals.
|
| 16 |
+
|
| 17 |
+
The ``.npz`` format is the standard format for persisting *multiple* NumPy
|
| 18 |
+
arrays on disk. A ``.npz`` file is a zip file containing multiple ``.npy``
|
| 19 |
+
files, one for each array.
|
| 20 |
+
|
| 21 |
+
Capabilities
|
| 22 |
+
------------
|
| 23 |
+
|
| 24 |
+
- Can represent all NumPy arrays including nested record arrays and
|
| 25 |
+
object arrays.
|
| 26 |
+
|
| 27 |
+
- Represents the data in its native binary form.
|
| 28 |
+
|
| 29 |
+
- Supports Fortran-contiguous arrays directly.
|
| 30 |
+
|
| 31 |
+
- Stores all of the necessary information to reconstruct the array
|
| 32 |
+
including shape and dtype on a machine of a different
|
| 33 |
+
architecture. Both little-endian and big-endian arrays are
|
| 34 |
+
supported, and a file with little-endian numbers will yield
|
| 35 |
+
a little-endian array on any machine reading the file. The
|
| 36 |
+
types are described in terms of their actual sizes. For example,
|
| 37 |
+
if a machine with a 64-bit C "long int" writes out an array with
|
| 38 |
+
"long ints", a reading machine with 32-bit C "long ints" will yield
|
| 39 |
+
an array with 64-bit integers.
|
| 40 |
+
|
| 41 |
+
- Is straightforward to reverse engineer. Datasets often live longer than
|
| 42 |
+
the programs that created them. A competent developer should be
|
| 43 |
+
able to create a solution in their preferred programming language to
|
| 44 |
+
read most ``.npy`` files that they have been given without much
|
| 45 |
+
documentation.
|
| 46 |
+
|
| 47 |
+
- Allows memory-mapping of the data. See `open_memmap`.
|
| 48 |
+
|
| 49 |
+
- Can be read from a filelike stream object instead of an actual file.
|
| 50 |
+
|
| 51 |
+
- Stores object arrays, i.e. arrays containing elements that are arbitrary
|
| 52 |
+
Python objects. Files with object arrays are not to be mmapable, but
|
| 53 |
+
can be read and written to disk.
|
| 54 |
+
|
| 55 |
+
Limitations
|
| 56 |
+
-----------
|
| 57 |
+
|
| 58 |
+
- Arbitrary subclasses of numpy.ndarray are not completely preserved.
|
| 59 |
+
Subclasses will be accepted for writing, but only the array data will
|
| 60 |
+
be written out. A regular numpy.ndarray object will be created
|
| 61 |
+
upon reading the file.
|
| 62 |
+
|
| 63 |
+
.. warning::
|
| 64 |
+
|
| 65 |
+
Due to limitations in the interpretation of structured dtypes, dtypes
|
| 66 |
+
with fields with empty names will have the names replaced by 'f0', 'f1',
|
| 67 |
+
etc. Such arrays will not round-trip through the format entirely
|
| 68 |
+
accurately. The data is intact; only the field names will differ. We are
|
| 69 |
+
working on a fix for this. This fix will not require a change in the
|
| 70 |
+
file format. The arrays with such structures can still be saved and
|
| 71 |
+
restored, and the correct dtype may be restored by using the
|
| 72 |
+
``loadedarray.view(correct_dtype)`` method.
|
| 73 |
+
|
| 74 |
+
File extensions
|
| 75 |
+
---------------
|
| 76 |
+
|
| 77 |
+
We recommend using the ``.npy`` and ``.npz`` extensions for files saved
|
| 78 |
+
in this format. This is by no means a requirement; applications may wish
|
| 79 |
+
to use these file formats but use an extension specific to the
|
| 80 |
+
application. In the absence of an obvious alternative, however,
|
| 81 |
+
we suggest using ``.npy`` and ``.npz``.
|
| 82 |
+
|
| 83 |
+
Version numbering
|
| 84 |
+
-----------------
|
| 85 |
+
|
| 86 |
+
The version numbering of these formats is independent of NumPy version
|
| 87 |
+
numbering. If the format is upgraded, the code in `numpy.io` will still
|
| 88 |
+
be able to read and write Version 1.0 files.
|
| 89 |
+
|
| 90 |
+
Format Version 1.0
|
| 91 |
+
------------------
|
| 92 |
+
|
| 93 |
+
The first 6 bytes are a magic string: exactly ``\\x93NUMPY``.
|
| 94 |
+
|
| 95 |
+
The next 1 byte is an unsigned byte: the major version number of the file
|
| 96 |
+
format, e.g. ``\\x01``.
|
| 97 |
+
|
| 98 |
+
The next 1 byte is an unsigned byte: the minor version number of the file
|
| 99 |
+
format, e.g. ``\\x00``. Note: the version of the file format is not tied
|
| 100 |
+
to the version of the numpy package.
|
| 101 |
+
|
| 102 |
+
The next 2 bytes form a little-endian unsigned short int: the length of
|
| 103 |
+
the header data HEADER_LEN.
|
| 104 |
+
|
| 105 |
+
The next HEADER_LEN bytes form the header data describing the array's
|
| 106 |
+
format. It is an ASCII string which contains a Python literal expression
|
| 107 |
+
of a dictionary. It is terminated by a newline (``\\n``) and padded with
|
| 108 |
+
spaces (``\\x20``) to make the total of
|
| 109 |
+
``len(magic string) + 2 + len(length) + HEADER_LEN`` be evenly divisible
|
| 110 |
+
by 64 for alignment purposes.
|
| 111 |
+
|
| 112 |
+
The dictionary contains three keys:
|
| 113 |
+
|
| 114 |
+
"descr" : dtype.descr
|
| 115 |
+
An object that can be passed as an argument to the `numpy.dtype`
|
| 116 |
+
constructor to create the array's dtype.
|
| 117 |
+
"fortran_order" : bool
|
| 118 |
+
Whether the array data is Fortran-contiguous or not. Since
|
| 119 |
+
Fortran-contiguous arrays are a common form of non-C-contiguity,
|
| 120 |
+
we allow them to be written directly to disk for efficiency.
|
| 121 |
+
"shape" : tuple of int
|
| 122 |
+
The shape of the array.
|
| 123 |
+
|
| 124 |
+
For repeatability and readability, the dictionary keys are sorted in
|
| 125 |
+
alphabetic order. This is for convenience only. A writer SHOULD implement
|
| 126 |
+
this if possible. A reader MUST NOT depend on this.
|
| 127 |
+
|
| 128 |
+
Following the header comes the array data. If the dtype contains Python
|
| 129 |
+
objects (i.e. ``dtype.hasobject is True``), then the data is a Python
|
| 130 |
+
pickle of the array. Otherwise the data is the contiguous (either C-
|
| 131 |
+
or Fortran-, depending on ``fortran_order``) bytes of the array.
|
| 132 |
+
Consumers can figure out the number of bytes by multiplying the number
|
| 133 |
+
of elements given by the shape (noting that ``shape=()`` means there is
|
| 134 |
+
1 element) by ``dtype.itemsize``.
|
| 135 |
+
|
| 136 |
+
Format Version 2.0
|
| 137 |
+
------------------
|
| 138 |
+
|
| 139 |
+
The version 1.0 format only allowed the array header to have a total size of
|
| 140 |
+
65535 bytes. This can be exceeded by structured arrays with a large number of
|
| 141 |
+
columns. The version 2.0 format extends the header size to 4 GiB.
|
| 142 |
+
`numpy.save` will automatically save in 2.0 format if the data requires it,
|
| 143 |
+
else it will always use the more compatible 1.0 format.
|
| 144 |
+
|
| 145 |
+
The description of the fourth element of the header therefore has become:
|
| 146 |
+
"The next 4 bytes form a little-endian unsigned int: the length of the header
|
| 147 |
+
data HEADER_LEN."
|
| 148 |
+
|
| 149 |
+
Format Version 3.0
|
| 150 |
+
------------------
|
| 151 |
+
|
| 152 |
+
This version replaces the ASCII string (which in practice was latin1) with
|
| 153 |
+
a utf8-encoded string, so supports structured types with any unicode field
|
| 154 |
+
names.
|
| 155 |
+
|
| 156 |
+
Notes
|
| 157 |
+
-----
|
| 158 |
+
The ``.npy`` format, including motivation for creating it and a comparison of
|
| 159 |
+
alternatives, is described in the
|
| 160 |
+
:doc:`"npy-format" NEP <neps:nep-0001-npy-format>`, however details have
|
| 161 |
+
evolved with time and this document is more current.
|
| 162 |
+
|
| 163 |
+
"""
|
| 164 |
+
import numpy
|
| 165 |
+
import warnings
|
| 166 |
+
from numpy.lib.utils import safe_eval, drop_metadata
|
| 167 |
+
from numpy.compat import (
|
| 168 |
+
isfileobj, os_fspath, pickle
|
| 169 |
+
)
|
| 170 |
+
|
| 171 |
+
|
| 172 |
+
__all__ = []
|
| 173 |
+
|
| 174 |
+
|
| 175 |
+
EXPECTED_KEYS = {'descr', 'fortran_order', 'shape'}
|
| 176 |
+
MAGIC_PREFIX = b'\x93NUMPY'
|
| 177 |
+
MAGIC_LEN = len(MAGIC_PREFIX) + 2
|
| 178 |
+
ARRAY_ALIGN = 64 # plausible values are powers of 2 between 16 and 4096
|
| 179 |
+
BUFFER_SIZE = 2**18 # size of buffer for reading npz files in bytes
|
| 180 |
+
# allow growth within the address space of a 64 bit machine along one axis
|
| 181 |
+
GROWTH_AXIS_MAX_DIGITS = 21 # = len(str(8*2**64-1)) hypothetical int1 dtype
|
| 182 |
+
|
| 183 |
+
# difference between version 1.0 and 2.0 is a 4 byte (I) header length
|
| 184 |
+
# instead of 2 bytes (H) allowing storage of large structured arrays
|
| 185 |
+
_header_size_info = {
|
| 186 |
+
(1, 0): ('<H', 'latin1'),
|
| 187 |
+
(2, 0): ('<I', 'latin1'),
|
| 188 |
+
(3, 0): ('<I', 'utf8'),
|
| 189 |
+
}
|
| 190 |
+
|
| 191 |
+
# Python's literal_eval is not actually safe for large inputs, since parsing
|
| 192 |
+
# may become slow or even cause interpreter crashes.
|
| 193 |
+
# This is an arbitrary, low limit which should make it safe in practice.
|
| 194 |
+
_MAX_HEADER_SIZE = 10000
|
| 195 |
+
|
| 196 |
+
def _check_version(version):
|
| 197 |
+
if version not in [(1, 0), (2, 0), (3, 0), None]:
|
| 198 |
+
msg = "we only support format version (1,0), (2,0), and (3,0), not %s"
|
| 199 |
+
raise ValueError(msg % (version,))
|
| 200 |
+
|
| 201 |
+
def magic(major, minor):
|
| 202 |
+
""" Return the magic string for the given file format version.
|
| 203 |
+
|
| 204 |
+
Parameters
|
| 205 |
+
----------
|
| 206 |
+
major : int in [0, 255]
|
| 207 |
+
minor : int in [0, 255]
|
| 208 |
+
|
| 209 |
+
Returns
|
| 210 |
+
-------
|
| 211 |
+
magic : str
|
| 212 |
+
|
| 213 |
+
Raises
|
| 214 |
+
------
|
| 215 |
+
ValueError if the version cannot be formatted.
|
| 216 |
+
"""
|
| 217 |
+
if major < 0 or major > 255:
|
| 218 |
+
raise ValueError("major version must be 0 <= major < 256")
|
| 219 |
+
if minor < 0 or minor > 255:
|
| 220 |
+
raise ValueError("minor version must be 0 <= minor < 256")
|
| 221 |
+
return MAGIC_PREFIX + bytes([major, minor])
|
| 222 |
+
|
| 223 |
+
def read_magic(fp):
|
| 224 |
+
""" Read the magic string to get the version of the file format.
|
| 225 |
+
|
| 226 |
+
Parameters
|
| 227 |
+
----------
|
| 228 |
+
fp : filelike object
|
| 229 |
+
|
| 230 |
+
Returns
|
| 231 |
+
-------
|
| 232 |
+
major : int
|
| 233 |
+
minor : int
|
| 234 |
+
"""
|
| 235 |
+
magic_str = _read_bytes(fp, MAGIC_LEN, "magic string")
|
| 236 |
+
if magic_str[:-2] != MAGIC_PREFIX:
|
| 237 |
+
msg = "the magic string is not correct; expected %r, got %r"
|
| 238 |
+
raise ValueError(msg % (MAGIC_PREFIX, magic_str[:-2]))
|
| 239 |
+
major, minor = magic_str[-2:]
|
| 240 |
+
return major, minor
|
| 241 |
+
|
| 242 |
+
|
| 243 |
+
def dtype_to_descr(dtype):
|
| 244 |
+
"""
|
| 245 |
+
Get a serializable descriptor from the dtype.
|
| 246 |
+
|
| 247 |
+
The .descr attribute of a dtype object cannot be round-tripped through
|
| 248 |
+
the dtype() constructor. Simple types, like dtype('float32'), have
|
| 249 |
+
a descr which looks like a record array with one field with '' as
|
| 250 |
+
a name. The dtype() constructor interprets this as a request to give
|
| 251 |
+
a default name. Instead, we construct descriptor that can be passed to
|
| 252 |
+
dtype().
|
| 253 |
+
|
| 254 |
+
Parameters
|
| 255 |
+
----------
|
| 256 |
+
dtype : dtype
|
| 257 |
+
The dtype of the array that will be written to disk.
|
| 258 |
+
|
| 259 |
+
Returns
|
| 260 |
+
-------
|
| 261 |
+
descr : object
|
| 262 |
+
An object that can be passed to `numpy.dtype()` in order to
|
| 263 |
+
replicate the input dtype.
|
| 264 |
+
|
| 265 |
+
"""
|
| 266 |
+
# NOTE: that drop_metadata may not return the right dtype e.g. for user
|
| 267 |
+
# dtypes. In that case our code below would fail the same, though.
|
| 268 |
+
new_dtype = drop_metadata(dtype)
|
| 269 |
+
if new_dtype is not dtype:
|
| 270 |
+
warnings.warn("metadata on a dtype is not saved to an npy/npz. "
|
| 271 |
+
"Use another format (such as pickle) to store it.",
|
| 272 |
+
UserWarning, stacklevel=2)
|
| 273 |
+
if dtype.names is not None:
|
| 274 |
+
# This is a record array. The .descr is fine. XXX: parts of the
|
| 275 |
+
# record array with an empty name, like padding bytes, still get
|
| 276 |
+
# fiddled with. This needs to be fixed in the C implementation of
|
| 277 |
+
# dtype().
|
| 278 |
+
return dtype.descr
|
| 279 |
+
else:
|
| 280 |
+
return dtype.str
|
| 281 |
+
|
| 282 |
+
def descr_to_dtype(descr):
|
| 283 |
+
"""
|
| 284 |
+
Returns a dtype based off the given description.
|
| 285 |
+
|
| 286 |
+
This is essentially the reverse of `dtype_to_descr()`. It will remove
|
| 287 |
+
the valueless padding fields created by, i.e. simple fields like
|
| 288 |
+
dtype('float32'), and then convert the description to its corresponding
|
| 289 |
+
dtype.
|
| 290 |
+
|
| 291 |
+
Parameters
|
| 292 |
+
----------
|
| 293 |
+
descr : object
|
| 294 |
+
The object retrieved by dtype.descr. Can be passed to
|
| 295 |
+
`numpy.dtype()` in order to replicate the input dtype.
|
| 296 |
+
|
| 297 |
+
Returns
|
| 298 |
+
-------
|
| 299 |
+
dtype : dtype
|
| 300 |
+
The dtype constructed by the description.
|
| 301 |
+
|
| 302 |
+
"""
|
| 303 |
+
if isinstance(descr, str):
|
| 304 |
+
# No padding removal needed
|
| 305 |
+
return numpy.dtype(descr)
|
| 306 |
+
elif isinstance(descr, tuple):
|
| 307 |
+
# subtype, will always have a shape descr[1]
|
| 308 |
+
dt = descr_to_dtype(descr[0])
|
| 309 |
+
return numpy.dtype((dt, descr[1]))
|
| 310 |
+
|
| 311 |
+
titles = []
|
| 312 |
+
names = []
|
| 313 |
+
formats = []
|
| 314 |
+
offsets = []
|
| 315 |
+
offset = 0
|
| 316 |
+
for field in descr:
|
| 317 |
+
if len(field) == 2:
|
| 318 |
+
name, descr_str = field
|
| 319 |
+
dt = descr_to_dtype(descr_str)
|
| 320 |
+
else:
|
| 321 |
+
name, descr_str, shape = field
|
| 322 |
+
dt = numpy.dtype((descr_to_dtype(descr_str), shape))
|
| 323 |
+
|
| 324 |
+
# Ignore padding bytes, which will be void bytes with '' as name
|
| 325 |
+
# Once support for blank names is removed, only "if name == ''" needed)
|
| 326 |
+
is_pad = (name == '' and dt.type is numpy.void and dt.names is None)
|
| 327 |
+
if not is_pad:
|
| 328 |
+
title, name = name if isinstance(name, tuple) else (None, name)
|
| 329 |
+
titles.append(title)
|
| 330 |
+
names.append(name)
|
| 331 |
+
formats.append(dt)
|
| 332 |
+
offsets.append(offset)
|
| 333 |
+
offset += dt.itemsize
|
| 334 |
+
|
| 335 |
+
return numpy.dtype({'names': names, 'formats': formats, 'titles': titles,
|
| 336 |
+
'offsets': offsets, 'itemsize': offset})
|
| 337 |
+
|
| 338 |
+
def header_data_from_array_1_0(array):
|
| 339 |
+
""" Get the dictionary of header metadata from a numpy.ndarray.
|
| 340 |
+
|
| 341 |
+
Parameters
|
| 342 |
+
----------
|
| 343 |
+
array : numpy.ndarray
|
| 344 |
+
|
| 345 |
+
Returns
|
| 346 |
+
-------
|
| 347 |
+
d : dict
|
| 348 |
+
This has the appropriate entries for writing its string representation
|
| 349 |
+
to the header of the file.
|
| 350 |
+
"""
|
| 351 |
+
d = {'shape': array.shape}
|
| 352 |
+
if array.flags.c_contiguous:
|
| 353 |
+
d['fortran_order'] = False
|
| 354 |
+
elif array.flags.f_contiguous:
|
| 355 |
+
d['fortran_order'] = True
|
| 356 |
+
else:
|
| 357 |
+
# Totally non-contiguous data. We will have to make it C-contiguous
|
| 358 |
+
# before writing. Note that we need to test for C_CONTIGUOUS first
|
| 359 |
+
# because a 1-D array is both C_CONTIGUOUS and F_CONTIGUOUS.
|
| 360 |
+
d['fortran_order'] = False
|
| 361 |
+
|
| 362 |
+
d['descr'] = dtype_to_descr(array.dtype)
|
| 363 |
+
return d
|
| 364 |
+
|
| 365 |
+
|
| 366 |
+
def _wrap_header(header, version):
|
| 367 |
+
"""
|
| 368 |
+
Takes a stringified header, and attaches the prefix and padding to it
|
| 369 |
+
"""
|
| 370 |
+
import struct
|
| 371 |
+
assert version is not None
|
| 372 |
+
fmt, encoding = _header_size_info[version]
|
| 373 |
+
header = header.encode(encoding)
|
| 374 |
+
hlen = len(header) + 1
|
| 375 |
+
padlen = ARRAY_ALIGN - ((MAGIC_LEN + struct.calcsize(fmt) + hlen) % ARRAY_ALIGN)
|
| 376 |
+
try:
|
| 377 |
+
header_prefix = magic(*version) + struct.pack(fmt, hlen + padlen)
|
| 378 |
+
except struct.error:
|
| 379 |
+
msg = "Header length {} too big for version={}".format(hlen, version)
|
| 380 |
+
raise ValueError(msg) from None
|
| 381 |
+
|
| 382 |
+
# Pad the header with spaces and a final newline such that the magic
|
| 383 |
+
# string, the header-length short and the header are aligned on a
|
| 384 |
+
# ARRAY_ALIGN byte boundary. This supports memory mapping of dtypes
|
| 385 |
+
# aligned up to ARRAY_ALIGN on systems like Linux where mmap()
|
| 386 |
+
# offset must be page-aligned (i.e. the beginning of the file).
|
| 387 |
+
return header_prefix + header + b' '*padlen + b'\n'
|
| 388 |
+
|
| 389 |
+
|
| 390 |
+
def _wrap_header_guess_version(header):
|
| 391 |
+
"""
|
| 392 |
+
Like `_wrap_header`, but chooses an appropriate version given the contents
|
| 393 |
+
"""
|
| 394 |
+
try:
|
| 395 |
+
return _wrap_header(header, (1, 0))
|
| 396 |
+
except ValueError:
|
| 397 |
+
pass
|
| 398 |
+
|
| 399 |
+
try:
|
| 400 |
+
ret = _wrap_header(header, (2, 0))
|
| 401 |
+
except UnicodeEncodeError:
|
| 402 |
+
pass
|
| 403 |
+
else:
|
| 404 |
+
warnings.warn("Stored array in format 2.0. It can only be"
|
| 405 |
+
"read by NumPy >= 1.9", UserWarning, stacklevel=2)
|
| 406 |
+
return ret
|
| 407 |
+
|
| 408 |
+
header = _wrap_header(header, (3, 0))
|
| 409 |
+
warnings.warn("Stored array in format 3.0. It can only be "
|
| 410 |
+
"read by NumPy >= 1.17", UserWarning, stacklevel=2)
|
| 411 |
+
return header
|
| 412 |
+
|
| 413 |
+
|
| 414 |
+
def _write_array_header(fp, d, version=None):
|
| 415 |
+
""" Write the header for an array and returns the version used
|
| 416 |
+
|
| 417 |
+
Parameters
|
| 418 |
+
----------
|
| 419 |
+
fp : filelike object
|
| 420 |
+
d : dict
|
| 421 |
+
This has the appropriate entries for writing its string representation
|
| 422 |
+
to the header of the file.
|
| 423 |
+
version : tuple or None
|
| 424 |
+
None means use oldest that works. Providing an explicit version will
|
| 425 |
+
raise a ValueError if the format does not allow saving this data.
|
| 426 |
+
Default: None
|
| 427 |
+
"""
|
| 428 |
+
header = ["{"]
|
| 429 |
+
for key, value in sorted(d.items()):
|
| 430 |
+
# Need to use repr here, since we eval these when reading
|
| 431 |
+
header.append("'%s': %s, " % (key, repr(value)))
|
| 432 |
+
header.append("}")
|
| 433 |
+
header = "".join(header)
|
| 434 |
+
|
| 435 |
+
# Add some spare space so that the array header can be modified in-place
|
| 436 |
+
# when changing the array size, e.g. when growing it by appending data at
|
| 437 |
+
# the end.
|
| 438 |
+
shape = d['shape']
|
| 439 |
+
header += " " * ((GROWTH_AXIS_MAX_DIGITS - len(repr(
|
| 440 |
+
shape[-1 if d['fortran_order'] else 0]
|
| 441 |
+
))) if len(shape) > 0 else 0)
|
| 442 |
+
|
| 443 |
+
if version is None:
|
| 444 |
+
header = _wrap_header_guess_version(header)
|
| 445 |
+
else:
|
| 446 |
+
header = _wrap_header(header, version)
|
| 447 |
+
fp.write(header)
|
| 448 |
+
|
| 449 |
+
def write_array_header_1_0(fp, d):
|
| 450 |
+
""" Write the header for an array using the 1.0 format.
|
| 451 |
+
|
| 452 |
+
Parameters
|
| 453 |
+
----------
|
| 454 |
+
fp : filelike object
|
| 455 |
+
d : dict
|
| 456 |
+
This has the appropriate entries for writing its string
|
| 457 |
+
representation to the header of the file.
|
| 458 |
+
"""
|
| 459 |
+
_write_array_header(fp, d, (1, 0))
|
| 460 |
+
|
| 461 |
+
|
| 462 |
+
def write_array_header_2_0(fp, d):
|
| 463 |
+
""" Write the header for an array using the 2.0 format.
|
| 464 |
+
The 2.0 format allows storing very large structured arrays.
|
| 465 |
+
|
| 466 |
+
.. versionadded:: 1.9.0
|
| 467 |
+
|
| 468 |
+
Parameters
|
| 469 |
+
----------
|
| 470 |
+
fp : filelike object
|
| 471 |
+
d : dict
|
| 472 |
+
This has the appropriate entries for writing its string
|
| 473 |
+
representation to the header of the file.
|
| 474 |
+
"""
|
| 475 |
+
_write_array_header(fp, d, (2, 0))
|
| 476 |
+
|
| 477 |
+
def read_array_header_1_0(fp, max_header_size=_MAX_HEADER_SIZE):
|
| 478 |
+
"""
|
| 479 |
+
Read an array header from a filelike object using the 1.0 file format
|
| 480 |
+
version.
|
| 481 |
+
|
| 482 |
+
This will leave the file object located just after the header.
|
| 483 |
+
|
| 484 |
+
Parameters
|
| 485 |
+
----------
|
| 486 |
+
fp : filelike object
|
| 487 |
+
A file object or something with a `.read()` method like a file.
|
| 488 |
+
|
| 489 |
+
Returns
|
| 490 |
+
-------
|
| 491 |
+
shape : tuple of int
|
| 492 |
+
The shape of the array.
|
| 493 |
+
fortran_order : bool
|
| 494 |
+
The array data will be written out directly if it is either
|
| 495 |
+
C-contiguous or Fortran-contiguous. Otherwise, it will be made
|
| 496 |
+
contiguous before writing it out.
|
| 497 |
+
dtype : dtype
|
| 498 |
+
The dtype of the file's data.
|
| 499 |
+
max_header_size : int, optional
|
| 500 |
+
Maximum allowed size of the header. Large headers may not be safe
|
| 501 |
+
to load securely and thus require explicitly passing a larger value.
|
| 502 |
+
See :py:func:`ast.literal_eval()` for details.
|
| 503 |
+
|
| 504 |
+
Raises
|
| 505 |
+
------
|
| 506 |
+
ValueError
|
| 507 |
+
If the data is invalid.
|
| 508 |
+
|
| 509 |
+
"""
|
| 510 |
+
return _read_array_header(
|
| 511 |
+
fp, version=(1, 0), max_header_size=max_header_size)
|
| 512 |
+
|
| 513 |
+
def read_array_header_2_0(fp, max_header_size=_MAX_HEADER_SIZE):
|
| 514 |
+
"""
|
| 515 |
+
Read an array header from a filelike object using the 2.0 file format
|
| 516 |
+
version.
|
| 517 |
+
|
| 518 |
+
This will leave the file object located just after the header.
|
| 519 |
+
|
| 520 |
+
.. versionadded:: 1.9.0
|
| 521 |
+
|
| 522 |
+
Parameters
|
| 523 |
+
----------
|
| 524 |
+
fp : filelike object
|
| 525 |
+
A file object or something with a `.read()` method like a file.
|
| 526 |
+
max_header_size : int, optional
|
| 527 |
+
Maximum allowed size of the header. Large headers may not be safe
|
| 528 |
+
to load securely and thus require explicitly passing a larger value.
|
| 529 |
+
See :py:func:`ast.literal_eval()` for details.
|
| 530 |
+
|
| 531 |
+
Returns
|
| 532 |
+
-------
|
| 533 |
+
shape : tuple of int
|
| 534 |
+
The shape of the array.
|
| 535 |
+
fortran_order : bool
|
| 536 |
+
The array data will be written out directly if it is either
|
| 537 |
+
C-contiguous or Fortran-contiguous. Otherwise, it will be made
|
| 538 |
+
contiguous before writing it out.
|
| 539 |
+
dtype : dtype
|
| 540 |
+
The dtype of the file's data.
|
| 541 |
+
|
| 542 |
+
Raises
|
| 543 |
+
------
|
| 544 |
+
ValueError
|
| 545 |
+
If the data is invalid.
|
| 546 |
+
|
| 547 |
+
"""
|
| 548 |
+
return _read_array_header(
|
| 549 |
+
fp, version=(2, 0), max_header_size=max_header_size)
|
| 550 |
+
|
| 551 |
+
|
| 552 |
+
def _filter_header(s):
|
| 553 |
+
"""Clean up 'L' in npz header ints.
|
| 554 |
+
|
| 555 |
+
Cleans up the 'L' in strings representing integers. Needed to allow npz
|
| 556 |
+
headers produced in Python2 to be read in Python3.
|
| 557 |
+
|
| 558 |
+
Parameters
|
| 559 |
+
----------
|
| 560 |
+
s : string
|
| 561 |
+
Npy file header.
|
| 562 |
+
|
| 563 |
+
Returns
|
| 564 |
+
-------
|
| 565 |
+
header : str
|
| 566 |
+
Cleaned up header.
|
| 567 |
+
|
| 568 |
+
"""
|
| 569 |
+
import tokenize
|
| 570 |
+
from io import StringIO
|
| 571 |
+
|
| 572 |
+
tokens = []
|
| 573 |
+
last_token_was_number = False
|
| 574 |
+
for token in tokenize.generate_tokens(StringIO(s).readline):
|
| 575 |
+
token_type = token[0]
|
| 576 |
+
token_string = token[1]
|
| 577 |
+
if (last_token_was_number and
|
| 578 |
+
token_type == tokenize.NAME and
|
| 579 |
+
token_string == "L"):
|
| 580 |
+
continue
|
| 581 |
+
else:
|
| 582 |
+
tokens.append(token)
|
| 583 |
+
last_token_was_number = (token_type == tokenize.NUMBER)
|
| 584 |
+
return tokenize.untokenize(tokens)
|
| 585 |
+
|
| 586 |
+
|
| 587 |
+
def _read_array_header(fp, version, max_header_size=_MAX_HEADER_SIZE):
|
| 588 |
+
"""
|
| 589 |
+
see read_array_header_1_0
|
| 590 |
+
"""
|
| 591 |
+
# Read an unsigned, little-endian short int which has the length of the
|
| 592 |
+
# header.
|
| 593 |
+
import struct
|
| 594 |
+
hinfo = _header_size_info.get(version)
|
| 595 |
+
if hinfo is None:
|
| 596 |
+
raise ValueError("Invalid version {!r}".format(version))
|
| 597 |
+
hlength_type, encoding = hinfo
|
| 598 |
+
|
| 599 |
+
hlength_str = _read_bytes(fp, struct.calcsize(hlength_type), "array header length")
|
| 600 |
+
header_length = struct.unpack(hlength_type, hlength_str)[0]
|
| 601 |
+
header = _read_bytes(fp, header_length, "array header")
|
| 602 |
+
header = header.decode(encoding)
|
| 603 |
+
if len(header) > max_header_size:
|
| 604 |
+
raise ValueError(
|
| 605 |
+
f"Header info length ({len(header)}) is large and may not be safe "
|
| 606 |
+
"to load securely.\n"
|
| 607 |
+
"To allow loading, adjust `max_header_size` or fully trust "
|
| 608 |
+
"the `.npy` file using `allow_pickle=True`.\n"
|
| 609 |
+
"For safety against large resource use or crashes, sandboxing "
|
| 610 |
+
"may be necessary.")
|
| 611 |
+
|
| 612 |
+
# The header is a pretty-printed string representation of a literal
|
| 613 |
+
# Python dictionary with trailing newlines padded to a ARRAY_ALIGN byte
|
| 614 |
+
# boundary. The keys are strings.
|
| 615 |
+
# "shape" : tuple of int
|
| 616 |
+
# "fortran_order" : bool
|
| 617 |
+
# "descr" : dtype.descr
|
| 618 |
+
# Versions (2, 0) and (1, 0) could have been created by a Python 2
|
| 619 |
+
# implementation before header filtering was implemented.
|
| 620 |
+
#
|
| 621 |
+
# For performance reasons, we try without _filter_header first though
|
| 622 |
+
try:
|
| 623 |
+
d = safe_eval(header)
|
| 624 |
+
except SyntaxError as e:
|
| 625 |
+
if version <= (2, 0):
|
| 626 |
+
header = _filter_header(header)
|
| 627 |
+
try:
|
| 628 |
+
d = safe_eval(header)
|
| 629 |
+
except SyntaxError as e2:
|
| 630 |
+
msg = "Cannot parse header: {!r}"
|
| 631 |
+
raise ValueError(msg.format(header)) from e2
|
| 632 |
+
else:
|
| 633 |
+
warnings.warn(
|
| 634 |
+
"Reading `.npy` or `.npz` file required additional "
|
| 635 |
+
"header parsing as it was created on Python 2. Save the "
|
| 636 |
+
"file again to speed up loading and avoid this warning.",
|
| 637 |
+
UserWarning, stacklevel=4)
|
| 638 |
+
else:
|
| 639 |
+
msg = "Cannot parse header: {!r}"
|
| 640 |
+
raise ValueError(msg.format(header)) from e
|
| 641 |
+
if not isinstance(d, dict):
|
| 642 |
+
msg = "Header is not a dictionary: {!r}"
|
| 643 |
+
raise ValueError(msg.format(d))
|
| 644 |
+
|
| 645 |
+
if EXPECTED_KEYS != d.keys():
|
| 646 |
+
keys = sorted(d.keys())
|
| 647 |
+
msg = "Header does not contain the correct keys: {!r}"
|
| 648 |
+
raise ValueError(msg.format(keys))
|
| 649 |
+
|
| 650 |
+
# Sanity-check the values.
|
| 651 |
+
if (not isinstance(d['shape'], tuple) or
|
| 652 |
+
not all(isinstance(x, int) for x in d['shape'])):
|
| 653 |
+
msg = "shape is not valid: {!r}"
|
| 654 |
+
raise ValueError(msg.format(d['shape']))
|
| 655 |
+
if not isinstance(d['fortran_order'], bool):
|
| 656 |
+
msg = "fortran_order is not a valid bool: {!r}"
|
| 657 |
+
raise ValueError(msg.format(d['fortran_order']))
|
| 658 |
+
try:
|
| 659 |
+
dtype = descr_to_dtype(d['descr'])
|
| 660 |
+
except TypeError as e:
|
| 661 |
+
msg = "descr is not a valid dtype descriptor: {!r}"
|
| 662 |
+
raise ValueError(msg.format(d['descr'])) from e
|
| 663 |
+
|
| 664 |
+
return d['shape'], d['fortran_order'], dtype
|
| 665 |
+
|
| 666 |
+
def write_array(fp, array, version=None, allow_pickle=True, pickle_kwargs=None):
|
| 667 |
+
"""
|
| 668 |
+
Write an array to an NPY file, including a header.
|
| 669 |
+
|
| 670 |
+
If the array is neither C-contiguous nor Fortran-contiguous AND the
|
| 671 |
+
file_like object is not a real file object, this function will have to
|
| 672 |
+
copy data in memory.
|
| 673 |
+
|
| 674 |
+
Parameters
|
| 675 |
+
----------
|
| 676 |
+
fp : file_like object
|
| 677 |
+
An open, writable file object, or similar object with a
|
| 678 |
+
``.write()`` method.
|
| 679 |
+
array : ndarray
|
| 680 |
+
The array to write to disk.
|
| 681 |
+
version : (int, int) or None, optional
|
| 682 |
+
The version number of the format. None means use the oldest
|
| 683 |
+
supported version that is able to store the data. Default: None
|
| 684 |
+
allow_pickle : bool, optional
|
| 685 |
+
Whether to allow writing pickled data. Default: True
|
| 686 |
+
pickle_kwargs : dict, optional
|
| 687 |
+
Additional keyword arguments to pass to pickle.dump, excluding
|
| 688 |
+
'protocol'. These are only useful when pickling objects in object
|
| 689 |
+
arrays on Python 3 to Python 2 compatible format.
|
| 690 |
+
|
| 691 |
+
Raises
|
| 692 |
+
------
|
| 693 |
+
ValueError
|
| 694 |
+
If the array cannot be persisted. This includes the case of
|
| 695 |
+
allow_pickle=False and array being an object array.
|
| 696 |
+
Various other errors
|
| 697 |
+
If the array contains Python objects as part of its dtype, the
|
| 698 |
+
process of pickling them may raise various errors if the objects
|
| 699 |
+
are not picklable.
|
| 700 |
+
|
| 701 |
+
"""
|
| 702 |
+
_check_version(version)
|
| 703 |
+
_write_array_header(fp, header_data_from_array_1_0(array), version)
|
| 704 |
+
|
| 705 |
+
if array.itemsize == 0:
|
| 706 |
+
buffersize = 0
|
| 707 |
+
else:
|
| 708 |
+
# Set buffer size to 16 MiB to hide the Python loop overhead.
|
| 709 |
+
buffersize = max(16 * 1024 ** 2 // array.itemsize, 1)
|
| 710 |
+
|
| 711 |
+
if array.dtype.hasobject:
|
| 712 |
+
# We contain Python objects so we cannot write out the data
|
| 713 |
+
# directly. Instead, we will pickle it out
|
| 714 |
+
if not allow_pickle:
|
| 715 |
+
raise ValueError("Object arrays cannot be saved when "
|
| 716 |
+
"allow_pickle=False")
|
| 717 |
+
if pickle_kwargs is None:
|
| 718 |
+
pickle_kwargs = {}
|
| 719 |
+
pickle.dump(array, fp, protocol=3, **pickle_kwargs)
|
| 720 |
+
elif array.flags.f_contiguous and not array.flags.c_contiguous:
|
| 721 |
+
if isfileobj(fp):
|
| 722 |
+
array.T.tofile(fp)
|
| 723 |
+
else:
|
| 724 |
+
for chunk in numpy.nditer(
|
| 725 |
+
array, flags=['external_loop', 'buffered', 'zerosize_ok'],
|
| 726 |
+
buffersize=buffersize, order='F'):
|
| 727 |
+
fp.write(chunk.tobytes('C'))
|
| 728 |
+
else:
|
| 729 |
+
if isfileobj(fp):
|
| 730 |
+
array.tofile(fp)
|
| 731 |
+
else:
|
| 732 |
+
for chunk in numpy.nditer(
|
| 733 |
+
array, flags=['external_loop', 'buffered', 'zerosize_ok'],
|
| 734 |
+
buffersize=buffersize, order='C'):
|
| 735 |
+
fp.write(chunk.tobytes('C'))
|
| 736 |
+
|
| 737 |
+
|
| 738 |
+
def read_array(fp, allow_pickle=False, pickle_kwargs=None, *,
|
| 739 |
+
max_header_size=_MAX_HEADER_SIZE):
|
| 740 |
+
"""
|
| 741 |
+
Read an array from an NPY file.
|
| 742 |
+
|
| 743 |
+
Parameters
|
| 744 |
+
----------
|
| 745 |
+
fp : file_like object
|
| 746 |
+
If this is not a real file object, then this may take extra memory
|
| 747 |
+
and time.
|
| 748 |
+
allow_pickle : bool, optional
|
| 749 |
+
Whether to allow writing pickled data. Default: False
|
| 750 |
+
|
| 751 |
+
.. versionchanged:: 1.16.3
|
| 752 |
+
Made default False in response to CVE-2019-6446.
|
| 753 |
+
|
| 754 |
+
pickle_kwargs : dict
|
| 755 |
+
Additional keyword arguments to pass to pickle.load. These are only
|
| 756 |
+
useful when loading object arrays saved on Python 2 when using
|
| 757 |
+
Python 3.
|
| 758 |
+
max_header_size : int, optional
|
| 759 |
+
Maximum allowed size of the header. Large headers may not be safe
|
| 760 |
+
to load securely and thus require explicitly passing a larger value.
|
| 761 |
+
See :py:func:`ast.literal_eval()` for details.
|
| 762 |
+
This option is ignored when `allow_pickle` is passed. In that case
|
| 763 |
+
the file is by definition trusted and the limit is unnecessary.
|
| 764 |
+
|
| 765 |
+
Returns
|
| 766 |
+
-------
|
| 767 |
+
array : ndarray
|
| 768 |
+
The array from the data on disk.
|
| 769 |
+
|
| 770 |
+
Raises
|
| 771 |
+
------
|
| 772 |
+
ValueError
|
| 773 |
+
If the data is invalid, or allow_pickle=False and the file contains
|
| 774 |
+
an object array.
|
| 775 |
+
|
| 776 |
+
"""
|
| 777 |
+
if allow_pickle:
|
| 778 |
+
# Effectively ignore max_header_size, since `allow_pickle` indicates
|
| 779 |
+
# that the input is fully trusted.
|
| 780 |
+
max_header_size = 2**64
|
| 781 |
+
|
| 782 |
+
version = read_magic(fp)
|
| 783 |
+
_check_version(version)
|
| 784 |
+
shape, fortran_order, dtype = _read_array_header(
|
| 785 |
+
fp, version, max_header_size=max_header_size)
|
| 786 |
+
if len(shape) == 0:
|
| 787 |
+
count = 1
|
| 788 |
+
else:
|
| 789 |
+
count = numpy.multiply.reduce(shape, dtype=numpy.int64)
|
| 790 |
+
|
| 791 |
+
# Now read the actual data.
|
| 792 |
+
if dtype.hasobject:
|
| 793 |
+
# The array contained Python objects. We need to unpickle the data.
|
| 794 |
+
if not allow_pickle:
|
| 795 |
+
raise ValueError("Object arrays cannot be loaded when "
|
| 796 |
+
"allow_pickle=False")
|
| 797 |
+
if pickle_kwargs is None:
|
| 798 |
+
pickle_kwargs = {}
|
| 799 |
+
try:
|
| 800 |
+
array = pickle.load(fp, **pickle_kwargs)
|
| 801 |
+
except UnicodeError as err:
|
| 802 |
+
# Friendlier error message
|
| 803 |
+
raise UnicodeError("Unpickling a python object failed: %r\n"
|
| 804 |
+
"You may need to pass the encoding= option "
|
| 805 |
+
"to numpy.load" % (err,)) from err
|
| 806 |
+
else:
|
| 807 |
+
if isfileobj(fp):
|
| 808 |
+
# We can use the fast fromfile() function.
|
| 809 |
+
array = numpy.fromfile(fp, dtype=dtype, count=count)
|
| 810 |
+
else:
|
| 811 |
+
# This is not a real file. We have to read it the
|
| 812 |
+
# memory-intensive way.
|
| 813 |
+
# crc32 module fails on reads greater than 2 ** 32 bytes,
|
| 814 |
+
# breaking large reads from gzip streams. Chunk reads to
|
| 815 |
+
# BUFFER_SIZE bytes to avoid issue and reduce memory overhead
|
| 816 |
+
# of the read. In non-chunked case count < max_read_count, so
|
| 817 |
+
# only one read is performed.
|
| 818 |
+
|
| 819 |
+
# Use np.ndarray instead of np.empty since the latter does
|
| 820 |
+
# not correctly instantiate zero-width string dtypes; see
|
| 821 |
+
# https://github.com/numpy/numpy/pull/6430
|
| 822 |
+
array = numpy.ndarray(count, dtype=dtype)
|
| 823 |
+
|
| 824 |
+
if dtype.itemsize > 0:
|
| 825 |
+
# If dtype.itemsize == 0 then there's nothing more to read
|
| 826 |
+
max_read_count = BUFFER_SIZE // min(BUFFER_SIZE, dtype.itemsize)
|
| 827 |
+
|
| 828 |
+
for i in range(0, count, max_read_count):
|
| 829 |
+
read_count = min(max_read_count, count - i)
|
| 830 |
+
read_size = int(read_count * dtype.itemsize)
|
| 831 |
+
data = _read_bytes(fp, read_size, "array data")
|
| 832 |
+
array[i:i+read_count] = numpy.frombuffer(data, dtype=dtype,
|
| 833 |
+
count=read_count)
|
| 834 |
+
|
| 835 |
+
if fortran_order:
|
| 836 |
+
array.shape = shape[::-1]
|
| 837 |
+
array = array.transpose()
|
| 838 |
+
else:
|
| 839 |
+
array.shape = shape
|
| 840 |
+
|
| 841 |
+
return array
|
| 842 |
+
|
| 843 |
+
|
| 844 |
+
def open_memmap(filename, mode='r+', dtype=None, shape=None,
|
| 845 |
+
fortran_order=False, version=None, *,
|
| 846 |
+
max_header_size=_MAX_HEADER_SIZE):
|
| 847 |
+
"""
|
| 848 |
+
Open a .npy file as a memory-mapped array.
|
| 849 |
+
|
| 850 |
+
This may be used to read an existing file or create a new one.
|
| 851 |
+
|
| 852 |
+
Parameters
|
| 853 |
+
----------
|
| 854 |
+
filename : str or path-like
|
| 855 |
+
The name of the file on disk. This may *not* be a file-like
|
| 856 |
+
object.
|
| 857 |
+
mode : str, optional
|
| 858 |
+
The mode in which to open the file; the default is 'r+'. In
|
| 859 |
+
addition to the standard file modes, 'c' is also accepted to mean
|
| 860 |
+
"copy on write." See `memmap` for the available mode strings.
|
| 861 |
+
dtype : data-type, optional
|
| 862 |
+
The data type of the array if we are creating a new file in "write"
|
| 863 |
+
mode, if not, `dtype` is ignored. The default value is None, which
|
| 864 |
+
results in a data-type of `float64`.
|
| 865 |
+
shape : tuple of int
|
| 866 |
+
The shape of the array if we are creating a new file in "write"
|
| 867 |
+
mode, in which case this parameter is required. Otherwise, this
|
| 868 |
+
parameter is ignored and is thus optional.
|
| 869 |
+
fortran_order : bool, optional
|
| 870 |
+
Whether the array should be Fortran-contiguous (True) or
|
| 871 |
+
C-contiguous (False, the default) if we are creating a new file in
|
| 872 |
+
"write" mode.
|
| 873 |
+
version : tuple of int (major, minor) or None
|
| 874 |
+
If the mode is a "write" mode, then this is the version of the file
|
| 875 |
+
format used to create the file. None means use the oldest
|
| 876 |
+
supported version that is able to store the data. Default: None
|
| 877 |
+
max_header_size : int, optional
|
| 878 |
+
Maximum allowed size of the header. Large headers may not be safe
|
| 879 |
+
to load securely and thus require explicitly passing a larger value.
|
| 880 |
+
See :py:func:`ast.literal_eval()` for details.
|
| 881 |
+
|
| 882 |
+
Returns
|
| 883 |
+
-------
|
| 884 |
+
marray : memmap
|
| 885 |
+
The memory-mapped array.
|
| 886 |
+
|
| 887 |
+
Raises
|
| 888 |
+
------
|
| 889 |
+
ValueError
|
| 890 |
+
If the data or the mode is invalid.
|
| 891 |
+
OSError
|
| 892 |
+
If the file is not found or cannot be opened correctly.
|
| 893 |
+
|
| 894 |
+
See Also
|
| 895 |
+
--------
|
| 896 |
+
numpy.memmap
|
| 897 |
+
|
| 898 |
+
"""
|
| 899 |
+
if isfileobj(filename):
|
| 900 |
+
raise ValueError("Filename must be a string or a path-like object."
|
| 901 |
+
" Memmap cannot use existing file handles.")
|
| 902 |
+
|
| 903 |
+
if 'w' in mode:
|
| 904 |
+
# We are creating the file, not reading it.
|
| 905 |
+
# Check if we ought to create the file.
|
| 906 |
+
_check_version(version)
|
| 907 |
+
# Ensure that the given dtype is an authentic dtype object rather
|
| 908 |
+
# than just something that can be interpreted as a dtype object.
|
| 909 |
+
dtype = numpy.dtype(dtype)
|
| 910 |
+
if dtype.hasobject:
|
| 911 |
+
msg = "Array can't be memory-mapped: Python objects in dtype."
|
| 912 |
+
raise ValueError(msg)
|
| 913 |
+
d = dict(
|
| 914 |
+
descr=dtype_to_descr(dtype),
|
| 915 |
+
fortran_order=fortran_order,
|
| 916 |
+
shape=shape,
|
| 917 |
+
)
|
| 918 |
+
# If we got here, then it should be safe to create the file.
|
| 919 |
+
with open(os_fspath(filename), mode+'b') as fp:
|
| 920 |
+
_write_array_header(fp, d, version)
|
| 921 |
+
offset = fp.tell()
|
| 922 |
+
else:
|
| 923 |
+
# Read the header of the file first.
|
| 924 |
+
with open(os_fspath(filename), 'rb') as fp:
|
| 925 |
+
version = read_magic(fp)
|
| 926 |
+
_check_version(version)
|
| 927 |
+
|
| 928 |
+
shape, fortran_order, dtype = _read_array_header(
|
| 929 |
+
fp, version, max_header_size=max_header_size)
|
| 930 |
+
if dtype.hasobject:
|
| 931 |
+
msg = "Array can't be memory-mapped: Python objects in dtype."
|
| 932 |
+
raise ValueError(msg)
|
| 933 |
+
offset = fp.tell()
|
| 934 |
+
|
| 935 |
+
if fortran_order:
|
| 936 |
+
order = 'F'
|
| 937 |
+
else:
|
| 938 |
+
order = 'C'
|
| 939 |
+
|
| 940 |
+
# We need to change a write-only mode to a read-write mode since we've
|
| 941 |
+
# already written data to the file.
|
| 942 |
+
if mode == 'w+':
|
| 943 |
+
mode = 'r+'
|
| 944 |
+
|
| 945 |
+
marray = numpy.memmap(filename, dtype=dtype, shape=shape, order=order,
|
| 946 |
+
mode=mode, offset=offset)
|
| 947 |
+
|
| 948 |
+
return marray
|
| 949 |
+
|
| 950 |
+
|
| 951 |
+
def _read_bytes(fp, size, error_template="ran out of data"):
|
| 952 |
+
"""
|
| 953 |
+
Read from file-like object until size bytes are read.
|
| 954 |
+
Raises ValueError if not EOF is encountered before size bytes are read.
|
| 955 |
+
Non-blocking objects only supported if they derive from io objects.
|
| 956 |
+
|
| 957 |
+
Required as e.g. ZipExtFile in python 2.6 can return less data than
|
| 958 |
+
requested.
|
| 959 |
+
"""
|
| 960 |
+
data = bytes()
|
| 961 |
+
while True:
|
| 962 |
+
# io files (default in python3) return None or raise on
|
| 963 |
+
# would-block, python2 file will truncate, probably nothing can be
|
| 964 |
+
# done about that. note that regular files can't be non-blocking
|
| 965 |
+
try:
|
| 966 |
+
r = fp.read(size - len(data))
|
| 967 |
+
data += r
|
| 968 |
+
if len(r) == 0 or len(data) == size:
|
| 969 |
+
break
|
| 970 |
+
except BlockingIOError:
|
| 971 |
+
pass
|
| 972 |
+
if len(data) != size:
|
| 973 |
+
msg = "EOF: reading %s, expected %d bytes got %d"
|
| 974 |
+
raise ValueError(msg % (error_template, size, len(data)))
|
| 975 |
+
else:
|
| 976 |
+
return data
|
LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/numpy/lib/nanfunctions.pyi
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from numpy.core.fromnumeric import (
|
| 2 |
+
amin,
|
| 3 |
+
amax,
|
| 4 |
+
argmin,
|
| 5 |
+
argmax,
|
| 6 |
+
sum,
|
| 7 |
+
prod,
|
| 8 |
+
cumsum,
|
| 9 |
+
cumprod,
|
| 10 |
+
mean,
|
| 11 |
+
var,
|
| 12 |
+
std
|
| 13 |
+
)
|
| 14 |
+
|
| 15 |
+
from numpy.lib.function_base import (
|
| 16 |
+
median,
|
| 17 |
+
percentile,
|
| 18 |
+
quantile,
|
| 19 |
+
)
|
| 20 |
+
|
| 21 |
+
__all__: list[str]
|
| 22 |
+
|
| 23 |
+
# NOTE: In reaility these functions are not aliases but distinct functions
|
| 24 |
+
# with identical signatures.
|
| 25 |
+
nanmin = amin
|
| 26 |
+
nanmax = amax
|
| 27 |
+
nanargmin = argmin
|
| 28 |
+
nanargmax = argmax
|
| 29 |
+
nansum = sum
|
| 30 |
+
nanprod = prod
|
| 31 |
+
nancumsum = cumsum
|
| 32 |
+
nancumprod = cumprod
|
| 33 |
+
nanmean = mean
|
| 34 |
+
nanvar = var
|
| 35 |
+
nanstd = std
|
| 36 |
+
nanmedian = median
|
| 37 |
+
nanpercentile = percentile
|
| 38 |
+
nanquantile = quantile
|
LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/numpy/lib/shape_base.pyi
ADDED
|
@@ -0,0 +1,220 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import sys
|
| 2 |
+
from collections.abc import Callable, Sequence
|
| 3 |
+
from typing import TypeVar, Any, overload, SupportsIndex, Protocol
|
| 4 |
+
|
| 5 |
+
if sys.version_info >= (3, 10):
|
| 6 |
+
from typing import ParamSpec, Concatenate
|
| 7 |
+
else:
|
| 8 |
+
from typing_extensions import ParamSpec, Concatenate
|
| 9 |
+
|
| 10 |
+
from numpy import (
|
| 11 |
+
generic,
|
| 12 |
+
integer,
|
| 13 |
+
ufunc,
|
| 14 |
+
bool_,
|
| 15 |
+
unsignedinteger,
|
| 16 |
+
signedinteger,
|
| 17 |
+
floating,
|
| 18 |
+
complexfloating,
|
| 19 |
+
object_,
|
| 20 |
+
)
|
| 21 |
+
|
| 22 |
+
from numpy._typing import (
|
| 23 |
+
ArrayLike,
|
| 24 |
+
NDArray,
|
| 25 |
+
_ShapeLike,
|
| 26 |
+
_ArrayLike,
|
| 27 |
+
_ArrayLikeBool_co,
|
| 28 |
+
_ArrayLikeUInt_co,
|
| 29 |
+
_ArrayLikeInt_co,
|
| 30 |
+
_ArrayLikeFloat_co,
|
| 31 |
+
_ArrayLikeComplex_co,
|
| 32 |
+
_ArrayLikeObject_co,
|
| 33 |
+
)
|
| 34 |
+
|
| 35 |
+
from numpy.core.shape_base import vstack
|
| 36 |
+
|
| 37 |
+
_P = ParamSpec("_P")
|
| 38 |
+
_SCT = TypeVar("_SCT", bound=generic)
|
| 39 |
+
|
| 40 |
+
# The signatures of `__array_wrap__` and `__array_prepare__` are the same;
|
| 41 |
+
# give them unique names for the sake of clarity
|
| 42 |
+
class _ArrayWrap(Protocol):
|
| 43 |
+
def __call__(
|
| 44 |
+
self,
|
| 45 |
+
array: NDArray[Any],
|
| 46 |
+
context: None | tuple[ufunc, tuple[Any, ...], int] = ...,
|
| 47 |
+
/,
|
| 48 |
+
) -> Any: ...
|
| 49 |
+
|
| 50 |
+
class _ArrayPrepare(Protocol):
|
| 51 |
+
def __call__(
|
| 52 |
+
self,
|
| 53 |
+
array: NDArray[Any],
|
| 54 |
+
context: None | tuple[ufunc, tuple[Any, ...], int] = ...,
|
| 55 |
+
/,
|
| 56 |
+
) -> Any: ...
|
| 57 |
+
|
| 58 |
+
class _SupportsArrayWrap(Protocol):
|
| 59 |
+
@property
|
| 60 |
+
def __array_wrap__(self) -> _ArrayWrap: ...
|
| 61 |
+
|
| 62 |
+
class _SupportsArrayPrepare(Protocol):
|
| 63 |
+
@property
|
| 64 |
+
def __array_prepare__(self) -> _ArrayPrepare: ...
|
| 65 |
+
|
| 66 |
+
__all__: list[str]
|
| 67 |
+
|
| 68 |
+
row_stack = vstack
|
| 69 |
+
|
| 70 |
+
def take_along_axis(
|
| 71 |
+
arr: _SCT | NDArray[_SCT],
|
| 72 |
+
indices: NDArray[integer[Any]],
|
| 73 |
+
axis: None | int,
|
| 74 |
+
) -> NDArray[_SCT]: ...
|
| 75 |
+
|
| 76 |
+
def put_along_axis(
|
| 77 |
+
arr: NDArray[_SCT],
|
| 78 |
+
indices: NDArray[integer[Any]],
|
| 79 |
+
values: ArrayLike,
|
| 80 |
+
axis: None | int,
|
| 81 |
+
) -> None: ...
|
| 82 |
+
|
| 83 |
+
@overload
|
| 84 |
+
def apply_along_axis(
|
| 85 |
+
func1d: Callable[Concatenate[NDArray[Any], _P], _ArrayLike[_SCT]],
|
| 86 |
+
axis: SupportsIndex,
|
| 87 |
+
arr: ArrayLike,
|
| 88 |
+
*args: _P.args,
|
| 89 |
+
**kwargs: _P.kwargs,
|
| 90 |
+
) -> NDArray[_SCT]: ...
|
| 91 |
+
@overload
|
| 92 |
+
def apply_along_axis(
|
| 93 |
+
func1d: Callable[Concatenate[NDArray[Any], _P], ArrayLike],
|
| 94 |
+
axis: SupportsIndex,
|
| 95 |
+
arr: ArrayLike,
|
| 96 |
+
*args: _P.args,
|
| 97 |
+
**kwargs: _P.kwargs,
|
| 98 |
+
) -> NDArray[Any]: ...
|
| 99 |
+
|
| 100 |
+
def apply_over_axes(
|
| 101 |
+
func: Callable[[NDArray[Any], int], NDArray[_SCT]],
|
| 102 |
+
a: ArrayLike,
|
| 103 |
+
axes: int | Sequence[int],
|
| 104 |
+
) -> NDArray[_SCT]: ...
|
| 105 |
+
|
| 106 |
+
@overload
|
| 107 |
+
def expand_dims(
|
| 108 |
+
a: _ArrayLike[_SCT],
|
| 109 |
+
axis: _ShapeLike,
|
| 110 |
+
) -> NDArray[_SCT]: ...
|
| 111 |
+
@overload
|
| 112 |
+
def expand_dims(
|
| 113 |
+
a: ArrayLike,
|
| 114 |
+
axis: _ShapeLike,
|
| 115 |
+
) -> NDArray[Any]: ...
|
| 116 |
+
|
| 117 |
+
@overload
|
| 118 |
+
def column_stack(tup: Sequence[_ArrayLike[_SCT]]) -> NDArray[_SCT]: ...
|
| 119 |
+
@overload
|
| 120 |
+
def column_stack(tup: Sequence[ArrayLike]) -> NDArray[Any]: ...
|
| 121 |
+
|
| 122 |
+
@overload
|
| 123 |
+
def dstack(tup: Sequence[_ArrayLike[_SCT]]) -> NDArray[_SCT]: ...
|
| 124 |
+
@overload
|
| 125 |
+
def dstack(tup: Sequence[ArrayLike]) -> NDArray[Any]: ...
|
| 126 |
+
|
| 127 |
+
@overload
|
| 128 |
+
def array_split(
|
| 129 |
+
ary: _ArrayLike[_SCT],
|
| 130 |
+
indices_or_sections: _ShapeLike,
|
| 131 |
+
axis: SupportsIndex = ...,
|
| 132 |
+
) -> list[NDArray[_SCT]]: ...
|
| 133 |
+
@overload
|
| 134 |
+
def array_split(
|
| 135 |
+
ary: ArrayLike,
|
| 136 |
+
indices_or_sections: _ShapeLike,
|
| 137 |
+
axis: SupportsIndex = ...,
|
| 138 |
+
) -> list[NDArray[Any]]: ...
|
| 139 |
+
|
| 140 |
+
@overload
|
| 141 |
+
def split(
|
| 142 |
+
ary: _ArrayLike[_SCT],
|
| 143 |
+
indices_or_sections: _ShapeLike,
|
| 144 |
+
axis: SupportsIndex = ...,
|
| 145 |
+
) -> list[NDArray[_SCT]]: ...
|
| 146 |
+
@overload
|
| 147 |
+
def split(
|
| 148 |
+
ary: ArrayLike,
|
| 149 |
+
indices_or_sections: _ShapeLike,
|
| 150 |
+
axis: SupportsIndex = ...,
|
| 151 |
+
) -> list[NDArray[Any]]: ...
|
| 152 |
+
|
| 153 |
+
@overload
|
| 154 |
+
def hsplit(
|
| 155 |
+
ary: _ArrayLike[_SCT],
|
| 156 |
+
indices_or_sections: _ShapeLike,
|
| 157 |
+
) -> list[NDArray[_SCT]]: ...
|
| 158 |
+
@overload
|
| 159 |
+
def hsplit(
|
| 160 |
+
ary: ArrayLike,
|
| 161 |
+
indices_or_sections: _ShapeLike,
|
| 162 |
+
) -> list[NDArray[Any]]: ...
|
| 163 |
+
|
| 164 |
+
@overload
|
| 165 |
+
def vsplit(
|
| 166 |
+
ary: _ArrayLike[_SCT],
|
| 167 |
+
indices_or_sections: _ShapeLike,
|
| 168 |
+
) -> list[NDArray[_SCT]]: ...
|
| 169 |
+
@overload
|
| 170 |
+
def vsplit(
|
| 171 |
+
ary: ArrayLike,
|
| 172 |
+
indices_or_sections: _ShapeLike,
|
| 173 |
+
) -> list[NDArray[Any]]: ...
|
| 174 |
+
|
| 175 |
+
@overload
|
| 176 |
+
def dsplit(
|
| 177 |
+
ary: _ArrayLike[_SCT],
|
| 178 |
+
indices_or_sections: _ShapeLike,
|
| 179 |
+
) -> list[NDArray[_SCT]]: ...
|
| 180 |
+
@overload
|
| 181 |
+
def dsplit(
|
| 182 |
+
ary: ArrayLike,
|
| 183 |
+
indices_or_sections: _ShapeLike,
|
| 184 |
+
) -> list[NDArray[Any]]: ...
|
| 185 |
+
|
| 186 |
+
@overload
|
| 187 |
+
def get_array_prepare(*args: _SupportsArrayPrepare) -> _ArrayPrepare: ...
|
| 188 |
+
@overload
|
| 189 |
+
def get_array_prepare(*args: object) -> None | _ArrayPrepare: ...
|
| 190 |
+
|
| 191 |
+
@overload
|
| 192 |
+
def get_array_wrap(*args: _SupportsArrayWrap) -> _ArrayWrap: ...
|
| 193 |
+
@overload
|
| 194 |
+
def get_array_wrap(*args: object) -> None | _ArrayWrap: ...
|
| 195 |
+
|
| 196 |
+
@overload
|
| 197 |
+
def kron(a: _ArrayLikeBool_co, b: _ArrayLikeBool_co) -> NDArray[bool_]: ... # type: ignore[misc]
|
| 198 |
+
@overload
|
| 199 |
+
def kron(a: _ArrayLikeUInt_co, b: _ArrayLikeUInt_co) -> NDArray[unsignedinteger[Any]]: ... # type: ignore[misc]
|
| 200 |
+
@overload
|
| 201 |
+
def kron(a: _ArrayLikeInt_co, b: _ArrayLikeInt_co) -> NDArray[signedinteger[Any]]: ... # type: ignore[misc]
|
| 202 |
+
@overload
|
| 203 |
+
def kron(a: _ArrayLikeFloat_co, b: _ArrayLikeFloat_co) -> NDArray[floating[Any]]: ... # type: ignore[misc]
|
| 204 |
+
@overload
|
| 205 |
+
def kron(a: _ArrayLikeComplex_co, b: _ArrayLikeComplex_co) -> NDArray[complexfloating[Any, Any]]: ...
|
| 206 |
+
@overload
|
| 207 |
+
def kron(a: _ArrayLikeObject_co, b: Any) -> NDArray[object_]: ...
|
| 208 |
+
@overload
|
| 209 |
+
def kron(a: Any, b: _ArrayLikeObject_co) -> NDArray[object_]: ...
|
| 210 |
+
|
| 211 |
+
@overload
|
| 212 |
+
def tile(
|
| 213 |
+
A: _ArrayLike[_SCT],
|
| 214 |
+
reps: int | Sequence[int],
|
| 215 |
+
) -> NDArray[_SCT]: ...
|
| 216 |
+
@overload
|
| 217 |
+
def tile(
|
| 218 |
+
A: ArrayLike,
|
| 219 |
+
reps: int | Sequence[int],
|
| 220 |
+
) -> NDArray[Any]: ...
|
LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/numpy/lib/utils.py
ADDED
|
@@ -0,0 +1,1211 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import os
|
| 2 |
+
import sys
|
| 3 |
+
import textwrap
|
| 4 |
+
import types
|
| 5 |
+
import re
|
| 6 |
+
import warnings
|
| 7 |
+
import functools
|
| 8 |
+
import platform
|
| 9 |
+
|
| 10 |
+
from .._utils import set_module
|
| 11 |
+
from numpy.core.numerictypes import issubclass_, issubsctype, issubdtype
|
| 12 |
+
from numpy.core import ndarray, ufunc, asarray
|
| 13 |
+
import numpy as np
|
| 14 |
+
|
| 15 |
+
__all__ = [
|
| 16 |
+
'issubclass_', 'issubsctype', 'issubdtype', 'deprecate',
|
| 17 |
+
'deprecate_with_doc', 'get_include', 'info', 'source', 'who',
|
| 18 |
+
'lookfor', 'byte_bounds', 'safe_eval', 'show_runtime'
|
| 19 |
+
]
|
| 20 |
+
|
| 21 |
+
|
| 22 |
+
def show_runtime():
|
| 23 |
+
"""
|
| 24 |
+
Print information about various resources in the system
|
| 25 |
+
including available intrinsic support and BLAS/LAPACK library
|
| 26 |
+
in use
|
| 27 |
+
|
| 28 |
+
.. versionadded:: 1.24.0
|
| 29 |
+
|
| 30 |
+
See Also
|
| 31 |
+
--------
|
| 32 |
+
show_config : Show libraries in the system on which NumPy was built.
|
| 33 |
+
|
| 34 |
+
Notes
|
| 35 |
+
-----
|
| 36 |
+
1. Information is derived with the help of `threadpoolctl <https://pypi.org/project/threadpoolctl/>`_
|
| 37 |
+
library if available.
|
| 38 |
+
2. SIMD related information is derived from ``__cpu_features__``,
|
| 39 |
+
``__cpu_baseline__`` and ``__cpu_dispatch__``
|
| 40 |
+
|
| 41 |
+
"""
|
| 42 |
+
from numpy.core._multiarray_umath import (
|
| 43 |
+
__cpu_features__, __cpu_baseline__, __cpu_dispatch__
|
| 44 |
+
)
|
| 45 |
+
from pprint import pprint
|
| 46 |
+
config_found = [{
|
| 47 |
+
"numpy_version": np.__version__,
|
| 48 |
+
"python": sys.version,
|
| 49 |
+
"uname": platform.uname(),
|
| 50 |
+
}]
|
| 51 |
+
features_found, features_not_found = [], []
|
| 52 |
+
for feature in __cpu_dispatch__:
|
| 53 |
+
if __cpu_features__[feature]:
|
| 54 |
+
features_found.append(feature)
|
| 55 |
+
else:
|
| 56 |
+
features_not_found.append(feature)
|
| 57 |
+
config_found.append({
|
| 58 |
+
"simd_extensions": {
|
| 59 |
+
"baseline": __cpu_baseline__,
|
| 60 |
+
"found": features_found,
|
| 61 |
+
"not_found": features_not_found
|
| 62 |
+
}
|
| 63 |
+
})
|
| 64 |
+
try:
|
| 65 |
+
from threadpoolctl import threadpool_info
|
| 66 |
+
config_found.extend(threadpool_info())
|
| 67 |
+
except ImportError:
|
| 68 |
+
print("WARNING: `threadpoolctl` not found in system!"
|
| 69 |
+
" Install it by `pip install threadpoolctl`."
|
| 70 |
+
" Once installed, try `np.show_runtime` again"
|
| 71 |
+
" for more detailed build information")
|
| 72 |
+
pprint(config_found)
|
| 73 |
+
|
| 74 |
+
|
| 75 |
+
def get_include():
|
| 76 |
+
"""
|
| 77 |
+
Return the directory that contains the NumPy \\*.h header files.
|
| 78 |
+
|
| 79 |
+
Extension modules that need to compile against NumPy should use this
|
| 80 |
+
function to locate the appropriate include directory.
|
| 81 |
+
|
| 82 |
+
Notes
|
| 83 |
+
-----
|
| 84 |
+
When using ``distutils``, for example in ``setup.py``::
|
| 85 |
+
|
| 86 |
+
import numpy as np
|
| 87 |
+
...
|
| 88 |
+
Extension('extension_name', ...
|
| 89 |
+
include_dirs=[np.get_include()])
|
| 90 |
+
...
|
| 91 |
+
|
| 92 |
+
"""
|
| 93 |
+
import numpy
|
| 94 |
+
if numpy.show_config is None:
|
| 95 |
+
# running from numpy source directory
|
| 96 |
+
d = os.path.join(os.path.dirname(numpy.__file__), 'core', 'include')
|
| 97 |
+
else:
|
| 98 |
+
# using installed numpy core headers
|
| 99 |
+
import numpy.core as core
|
| 100 |
+
d = os.path.join(os.path.dirname(core.__file__), 'include')
|
| 101 |
+
return d
|
| 102 |
+
|
| 103 |
+
|
| 104 |
+
class _Deprecate:
|
| 105 |
+
"""
|
| 106 |
+
Decorator class to deprecate old functions.
|
| 107 |
+
|
| 108 |
+
Refer to `deprecate` for details.
|
| 109 |
+
|
| 110 |
+
See Also
|
| 111 |
+
--------
|
| 112 |
+
deprecate
|
| 113 |
+
|
| 114 |
+
"""
|
| 115 |
+
|
| 116 |
+
def __init__(self, old_name=None, new_name=None, message=None):
|
| 117 |
+
self.old_name = old_name
|
| 118 |
+
self.new_name = new_name
|
| 119 |
+
self.message = message
|
| 120 |
+
|
| 121 |
+
def __call__(self, func, *args, **kwargs):
|
| 122 |
+
"""
|
| 123 |
+
Decorator call. Refer to ``decorate``.
|
| 124 |
+
|
| 125 |
+
"""
|
| 126 |
+
old_name = self.old_name
|
| 127 |
+
new_name = self.new_name
|
| 128 |
+
message = self.message
|
| 129 |
+
|
| 130 |
+
if old_name is None:
|
| 131 |
+
old_name = func.__name__
|
| 132 |
+
if new_name is None:
|
| 133 |
+
depdoc = "`%s` is deprecated!" % old_name
|
| 134 |
+
else:
|
| 135 |
+
depdoc = "`%s` is deprecated, use `%s` instead!" % \
|
| 136 |
+
(old_name, new_name)
|
| 137 |
+
|
| 138 |
+
if message is not None:
|
| 139 |
+
depdoc += "\n" + message
|
| 140 |
+
|
| 141 |
+
@functools.wraps(func)
|
| 142 |
+
def newfunc(*args, **kwds):
|
| 143 |
+
warnings.warn(depdoc, DeprecationWarning, stacklevel=2)
|
| 144 |
+
return func(*args, **kwds)
|
| 145 |
+
|
| 146 |
+
newfunc.__name__ = old_name
|
| 147 |
+
doc = func.__doc__
|
| 148 |
+
if doc is None:
|
| 149 |
+
doc = depdoc
|
| 150 |
+
else:
|
| 151 |
+
lines = doc.expandtabs().split('\n')
|
| 152 |
+
indent = _get_indent(lines[1:])
|
| 153 |
+
if lines[0].lstrip():
|
| 154 |
+
# Indent the original first line to let inspect.cleandoc()
|
| 155 |
+
# dedent the docstring despite the deprecation notice.
|
| 156 |
+
doc = indent * ' ' + doc
|
| 157 |
+
else:
|
| 158 |
+
# Remove the same leading blank lines as cleandoc() would.
|
| 159 |
+
skip = len(lines[0]) + 1
|
| 160 |
+
for line in lines[1:]:
|
| 161 |
+
if len(line) > indent:
|
| 162 |
+
break
|
| 163 |
+
skip += len(line) + 1
|
| 164 |
+
doc = doc[skip:]
|
| 165 |
+
depdoc = textwrap.indent(depdoc, ' ' * indent)
|
| 166 |
+
doc = '\n\n'.join([depdoc, doc])
|
| 167 |
+
newfunc.__doc__ = doc
|
| 168 |
+
|
| 169 |
+
return newfunc
|
| 170 |
+
|
| 171 |
+
|
| 172 |
+
def _get_indent(lines):
|
| 173 |
+
"""
|
| 174 |
+
Determines the leading whitespace that could be removed from all the lines.
|
| 175 |
+
"""
|
| 176 |
+
indent = sys.maxsize
|
| 177 |
+
for line in lines:
|
| 178 |
+
content = len(line.lstrip())
|
| 179 |
+
if content:
|
| 180 |
+
indent = min(indent, len(line) - content)
|
| 181 |
+
if indent == sys.maxsize:
|
| 182 |
+
indent = 0
|
| 183 |
+
return indent
|
| 184 |
+
|
| 185 |
+
|
| 186 |
+
def deprecate(*args, **kwargs):
|
| 187 |
+
"""
|
| 188 |
+
Issues a DeprecationWarning, adds warning to `old_name`'s
|
| 189 |
+
docstring, rebinds ``old_name.__name__`` and returns the new
|
| 190 |
+
function object.
|
| 191 |
+
|
| 192 |
+
This function may also be used as a decorator.
|
| 193 |
+
|
| 194 |
+
Parameters
|
| 195 |
+
----------
|
| 196 |
+
func : function
|
| 197 |
+
The function to be deprecated.
|
| 198 |
+
old_name : str, optional
|
| 199 |
+
The name of the function to be deprecated. Default is None, in
|
| 200 |
+
which case the name of `func` is used.
|
| 201 |
+
new_name : str, optional
|
| 202 |
+
The new name for the function. Default is None, in which case the
|
| 203 |
+
deprecation message is that `old_name` is deprecated. If given, the
|
| 204 |
+
deprecation message is that `old_name` is deprecated and `new_name`
|
| 205 |
+
should be used instead.
|
| 206 |
+
message : str, optional
|
| 207 |
+
Additional explanation of the deprecation. Displayed in the
|
| 208 |
+
docstring after the warning.
|
| 209 |
+
|
| 210 |
+
Returns
|
| 211 |
+
-------
|
| 212 |
+
old_func : function
|
| 213 |
+
The deprecated function.
|
| 214 |
+
|
| 215 |
+
Examples
|
| 216 |
+
--------
|
| 217 |
+
Note that ``olduint`` returns a value after printing Deprecation
|
| 218 |
+
Warning:
|
| 219 |
+
|
| 220 |
+
>>> olduint = np.deprecate(np.uint)
|
| 221 |
+
DeprecationWarning: `uint64` is deprecated! # may vary
|
| 222 |
+
>>> olduint(6)
|
| 223 |
+
6
|
| 224 |
+
|
| 225 |
+
"""
|
| 226 |
+
# Deprecate may be run as a function or as a decorator
|
| 227 |
+
# If run as a function, we initialise the decorator class
|
| 228 |
+
# and execute its __call__ method.
|
| 229 |
+
|
| 230 |
+
if args:
|
| 231 |
+
fn = args[0]
|
| 232 |
+
args = args[1:]
|
| 233 |
+
|
| 234 |
+
return _Deprecate(*args, **kwargs)(fn)
|
| 235 |
+
else:
|
| 236 |
+
return _Deprecate(*args, **kwargs)
|
| 237 |
+
|
| 238 |
+
|
| 239 |
+
def deprecate_with_doc(msg):
|
| 240 |
+
"""
|
| 241 |
+
Deprecates a function and includes the deprecation in its docstring.
|
| 242 |
+
|
| 243 |
+
This function is used as a decorator. It returns an object that can be
|
| 244 |
+
used to issue a DeprecationWarning, by passing the to-be decorated
|
| 245 |
+
function as argument, this adds warning to the to-be decorated function's
|
| 246 |
+
docstring and returns the new function object.
|
| 247 |
+
|
| 248 |
+
See Also
|
| 249 |
+
--------
|
| 250 |
+
deprecate : Decorate a function such that it issues a `DeprecationWarning`
|
| 251 |
+
|
| 252 |
+
Parameters
|
| 253 |
+
----------
|
| 254 |
+
msg : str
|
| 255 |
+
Additional explanation of the deprecation. Displayed in the
|
| 256 |
+
docstring after the warning.
|
| 257 |
+
|
| 258 |
+
Returns
|
| 259 |
+
-------
|
| 260 |
+
obj : object
|
| 261 |
+
|
| 262 |
+
"""
|
| 263 |
+
return _Deprecate(message=msg)
|
| 264 |
+
|
| 265 |
+
|
| 266 |
+
#--------------------------------------------
|
| 267 |
+
# Determine if two arrays can share memory
|
| 268 |
+
#--------------------------------------------
|
| 269 |
+
|
| 270 |
+
def byte_bounds(a):
|
| 271 |
+
"""
|
| 272 |
+
Returns pointers to the end-points of an array.
|
| 273 |
+
|
| 274 |
+
Parameters
|
| 275 |
+
----------
|
| 276 |
+
a : ndarray
|
| 277 |
+
Input array. It must conform to the Python-side of the array
|
| 278 |
+
interface.
|
| 279 |
+
|
| 280 |
+
Returns
|
| 281 |
+
-------
|
| 282 |
+
(low, high) : tuple of 2 integers
|
| 283 |
+
The first integer is the first byte of the array, the second
|
| 284 |
+
integer is just past the last byte of the array. If `a` is not
|
| 285 |
+
contiguous it will not use every byte between the (`low`, `high`)
|
| 286 |
+
values.
|
| 287 |
+
|
| 288 |
+
Examples
|
| 289 |
+
--------
|
| 290 |
+
>>> I = np.eye(2, dtype='f'); I.dtype
|
| 291 |
+
dtype('float32')
|
| 292 |
+
>>> low, high = np.byte_bounds(I)
|
| 293 |
+
>>> high - low == I.size*I.itemsize
|
| 294 |
+
True
|
| 295 |
+
>>> I = np.eye(2); I.dtype
|
| 296 |
+
dtype('float64')
|
| 297 |
+
>>> low, high = np.byte_bounds(I)
|
| 298 |
+
>>> high - low == I.size*I.itemsize
|
| 299 |
+
True
|
| 300 |
+
|
| 301 |
+
"""
|
| 302 |
+
ai = a.__array_interface__
|
| 303 |
+
a_data = ai['data'][0]
|
| 304 |
+
astrides = ai['strides']
|
| 305 |
+
ashape = ai['shape']
|
| 306 |
+
bytes_a = asarray(a).dtype.itemsize
|
| 307 |
+
|
| 308 |
+
a_low = a_high = a_data
|
| 309 |
+
if astrides is None:
|
| 310 |
+
# contiguous case
|
| 311 |
+
a_high += a.size * bytes_a
|
| 312 |
+
else:
|
| 313 |
+
for shape, stride in zip(ashape, astrides):
|
| 314 |
+
if stride < 0:
|
| 315 |
+
a_low += (shape-1)*stride
|
| 316 |
+
else:
|
| 317 |
+
a_high += (shape-1)*stride
|
| 318 |
+
a_high += bytes_a
|
| 319 |
+
return a_low, a_high
|
| 320 |
+
|
| 321 |
+
|
| 322 |
+
#-----------------------------------------------------------------------------
|
| 323 |
+
# Function for output and information on the variables used.
|
| 324 |
+
#-----------------------------------------------------------------------------
|
| 325 |
+
|
| 326 |
+
|
| 327 |
+
def who(vardict=None):
|
| 328 |
+
"""
|
| 329 |
+
Print the NumPy arrays in the given dictionary.
|
| 330 |
+
|
| 331 |
+
If there is no dictionary passed in or `vardict` is None then returns
|
| 332 |
+
NumPy arrays in the globals() dictionary (all NumPy arrays in the
|
| 333 |
+
namespace).
|
| 334 |
+
|
| 335 |
+
Parameters
|
| 336 |
+
----------
|
| 337 |
+
vardict : dict, optional
|
| 338 |
+
A dictionary possibly containing ndarrays. Default is globals().
|
| 339 |
+
|
| 340 |
+
Returns
|
| 341 |
+
-------
|
| 342 |
+
out : None
|
| 343 |
+
Returns 'None'.
|
| 344 |
+
|
| 345 |
+
Notes
|
| 346 |
+
-----
|
| 347 |
+
Prints out the name, shape, bytes and type of all of the ndarrays
|
| 348 |
+
present in `vardict`.
|
| 349 |
+
|
| 350 |
+
Examples
|
| 351 |
+
--------
|
| 352 |
+
>>> a = np.arange(10)
|
| 353 |
+
>>> b = np.ones(20)
|
| 354 |
+
>>> np.who()
|
| 355 |
+
Name Shape Bytes Type
|
| 356 |
+
===========================================================
|
| 357 |
+
a 10 80 int64
|
| 358 |
+
b 20 160 float64
|
| 359 |
+
Upper bound on total bytes = 240
|
| 360 |
+
|
| 361 |
+
>>> d = {'x': np.arange(2.0), 'y': np.arange(3.0), 'txt': 'Some str',
|
| 362 |
+
... 'idx':5}
|
| 363 |
+
>>> np.who(d)
|
| 364 |
+
Name Shape Bytes Type
|
| 365 |
+
===========================================================
|
| 366 |
+
x 2 16 float64
|
| 367 |
+
y 3 24 float64
|
| 368 |
+
Upper bound on total bytes = 40
|
| 369 |
+
|
| 370 |
+
"""
|
| 371 |
+
if vardict is None:
|
| 372 |
+
frame = sys._getframe().f_back
|
| 373 |
+
vardict = frame.f_globals
|
| 374 |
+
sta = []
|
| 375 |
+
cache = {}
|
| 376 |
+
for name in vardict.keys():
|
| 377 |
+
if isinstance(vardict[name], ndarray):
|
| 378 |
+
var = vardict[name]
|
| 379 |
+
idv = id(var)
|
| 380 |
+
if idv in cache.keys():
|
| 381 |
+
namestr = name + " (%s)" % cache[idv]
|
| 382 |
+
original = 0
|
| 383 |
+
else:
|
| 384 |
+
cache[idv] = name
|
| 385 |
+
namestr = name
|
| 386 |
+
original = 1
|
| 387 |
+
shapestr = " x ".join(map(str, var.shape))
|
| 388 |
+
bytestr = str(var.nbytes)
|
| 389 |
+
sta.append([namestr, shapestr, bytestr, var.dtype.name,
|
| 390 |
+
original])
|
| 391 |
+
|
| 392 |
+
maxname = 0
|
| 393 |
+
maxshape = 0
|
| 394 |
+
maxbyte = 0
|
| 395 |
+
totalbytes = 0
|
| 396 |
+
for val in sta:
|
| 397 |
+
if maxname < len(val[0]):
|
| 398 |
+
maxname = len(val[0])
|
| 399 |
+
if maxshape < len(val[1]):
|
| 400 |
+
maxshape = len(val[1])
|
| 401 |
+
if maxbyte < len(val[2]):
|
| 402 |
+
maxbyte = len(val[2])
|
| 403 |
+
if val[4]:
|
| 404 |
+
totalbytes += int(val[2])
|
| 405 |
+
|
| 406 |
+
if len(sta) > 0:
|
| 407 |
+
sp1 = max(10, maxname)
|
| 408 |
+
sp2 = max(10, maxshape)
|
| 409 |
+
sp3 = max(10, maxbyte)
|
| 410 |
+
prval = "Name %s Shape %s Bytes %s Type" % (sp1*' ', sp2*' ', sp3*' ')
|
| 411 |
+
print(prval + "\n" + "="*(len(prval)+5) + "\n")
|
| 412 |
+
|
| 413 |
+
for val in sta:
|
| 414 |
+
print("%s %s %s %s %s %s %s" % (val[0], ' '*(sp1-len(val[0])+4),
|
| 415 |
+
val[1], ' '*(sp2-len(val[1])+5),
|
| 416 |
+
val[2], ' '*(sp3-len(val[2])+5),
|
| 417 |
+
val[3]))
|
| 418 |
+
print("\nUpper bound on total bytes = %d" % totalbytes)
|
| 419 |
+
return
|
| 420 |
+
|
| 421 |
+
#-----------------------------------------------------------------------------
|
| 422 |
+
|
| 423 |
+
|
| 424 |
+
# NOTE: pydoc defines a help function which works similarly to this
|
| 425 |
+
# except it uses a pager to take over the screen.
|
| 426 |
+
|
| 427 |
+
# combine name and arguments and split to multiple lines of width
|
| 428 |
+
# characters. End lines on a comma and begin argument list indented with
|
| 429 |
+
# the rest of the arguments.
|
| 430 |
+
def _split_line(name, arguments, width):
|
| 431 |
+
firstwidth = len(name)
|
| 432 |
+
k = firstwidth
|
| 433 |
+
newstr = name
|
| 434 |
+
sepstr = ", "
|
| 435 |
+
arglist = arguments.split(sepstr)
|
| 436 |
+
for argument in arglist:
|
| 437 |
+
if k == firstwidth:
|
| 438 |
+
addstr = ""
|
| 439 |
+
else:
|
| 440 |
+
addstr = sepstr
|
| 441 |
+
k = k + len(argument) + len(addstr)
|
| 442 |
+
if k > width:
|
| 443 |
+
k = firstwidth + 1 + len(argument)
|
| 444 |
+
newstr = newstr + ",\n" + " "*(firstwidth+2) + argument
|
| 445 |
+
else:
|
| 446 |
+
newstr = newstr + addstr + argument
|
| 447 |
+
return newstr
|
| 448 |
+
|
| 449 |
+
_namedict = None
|
| 450 |
+
_dictlist = None
|
| 451 |
+
|
| 452 |
+
# Traverse all module directories underneath globals
|
| 453 |
+
# to see if something is defined
|
| 454 |
+
def _makenamedict(module='numpy'):
|
| 455 |
+
module = __import__(module, globals(), locals(), [])
|
| 456 |
+
thedict = {module.__name__:module.__dict__}
|
| 457 |
+
dictlist = [module.__name__]
|
| 458 |
+
totraverse = [module.__dict__]
|
| 459 |
+
while True:
|
| 460 |
+
if len(totraverse) == 0:
|
| 461 |
+
break
|
| 462 |
+
thisdict = totraverse.pop(0)
|
| 463 |
+
for x in thisdict.keys():
|
| 464 |
+
if isinstance(thisdict[x], types.ModuleType):
|
| 465 |
+
modname = thisdict[x].__name__
|
| 466 |
+
if modname not in dictlist:
|
| 467 |
+
moddict = thisdict[x].__dict__
|
| 468 |
+
dictlist.append(modname)
|
| 469 |
+
totraverse.append(moddict)
|
| 470 |
+
thedict[modname] = moddict
|
| 471 |
+
return thedict, dictlist
|
| 472 |
+
|
| 473 |
+
|
| 474 |
+
def _info(obj, output=None):
|
| 475 |
+
"""Provide information about ndarray obj.
|
| 476 |
+
|
| 477 |
+
Parameters
|
| 478 |
+
----------
|
| 479 |
+
obj : ndarray
|
| 480 |
+
Must be ndarray, not checked.
|
| 481 |
+
output
|
| 482 |
+
Where printed output goes.
|
| 483 |
+
|
| 484 |
+
Notes
|
| 485 |
+
-----
|
| 486 |
+
Copied over from the numarray module prior to its removal.
|
| 487 |
+
Adapted somewhat as only numpy is an option now.
|
| 488 |
+
|
| 489 |
+
Called by info.
|
| 490 |
+
|
| 491 |
+
"""
|
| 492 |
+
extra = ""
|
| 493 |
+
tic = ""
|
| 494 |
+
bp = lambda x: x
|
| 495 |
+
cls = getattr(obj, '__class__', type(obj))
|
| 496 |
+
nm = getattr(cls, '__name__', cls)
|
| 497 |
+
strides = obj.strides
|
| 498 |
+
endian = obj.dtype.byteorder
|
| 499 |
+
|
| 500 |
+
if output is None:
|
| 501 |
+
output = sys.stdout
|
| 502 |
+
|
| 503 |
+
print("class: ", nm, file=output)
|
| 504 |
+
print("shape: ", obj.shape, file=output)
|
| 505 |
+
print("strides: ", strides, file=output)
|
| 506 |
+
print("itemsize: ", obj.itemsize, file=output)
|
| 507 |
+
print("aligned: ", bp(obj.flags.aligned), file=output)
|
| 508 |
+
print("contiguous: ", bp(obj.flags.contiguous), file=output)
|
| 509 |
+
print("fortran: ", obj.flags.fortran, file=output)
|
| 510 |
+
print(
|
| 511 |
+
"data pointer: %s%s" % (hex(obj.ctypes._as_parameter_.value), extra),
|
| 512 |
+
file=output
|
| 513 |
+
)
|
| 514 |
+
print("byteorder: ", end=' ', file=output)
|
| 515 |
+
if endian in ['|', '=']:
|
| 516 |
+
print("%s%s%s" % (tic, sys.byteorder, tic), file=output)
|
| 517 |
+
byteswap = False
|
| 518 |
+
elif endian == '>':
|
| 519 |
+
print("%sbig%s" % (tic, tic), file=output)
|
| 520 |
+
byteswap = sys.byteorder != "big"
|
| 521 |
+
else:
|
| 522 |
+
print("%slittle%s" % (tic, tic), file=output)
|
| 523 |
+
byteswap = sys.byteorder != "little"
|
| 524 |
+
print("byteswap: ", bp(byteswap), file=output)
|
| 525 |
+
print("type: %s" % obj.dtype, file=output)
|
| 526 |
+
|
| 527 |
+
|
| 528 |
+
@set_module('numpy')
|
| 529 |
+
def info(object=None, maxwidth=76, output=None, toplevel='numpy'):
|
| 530 |
+
"""
|
| 531 |
+
Get help information for an array, function, class, or module.
|
| 532 |
+
|
| 533 |
+
Parameters
|
| 534 |
+
----------
|
| 535 |
+
object : object or str, optional
|
| 536 |
+
Input object or name to get information about. If `object` is
|
| 537 |
+
an `ndarray` instance, information about the array is printed.
|
| 538 |
+
If `object` is a numpy object, its docstring is given. If it is
|
| 539 |
+
a string, available modules are searched for matching objects.
|
| 540 |
+
If None, information about `info` itself is returned.
|
| 541 |
+
maxwidth : int, optional
|
| 542 |
+
Printing width.
|
| 543 |
+
output : file like object, optional
|
| 544 |
+
File like object that the output is written to, default is
|
| 545 |
+
``None``, in which case ``sys.stdout`` will be used.
|
| 546 |
+
The object has to be opened in 'w' or 'a' mode.
|
| 547 |
+
toplevel : str, optional
|
| 548 |
+
Start search at this level.
|
| 549 |
+
|
| 550 |
+
See Also
|
| 551 |
+
--------
|
| 552 |
+
source, lookfor
|
| 553 |
+
|
| 554 |
+
Notes
|
| 555 |
+
-----
|
| 556 |
+
When used interactively with an object, ``np.info(obj)`` is equivalent
|
| 557 |
+
to ``help(obj)`` on the Python prompt or ``obj?`` on the IPython
|
| 558 |
+
prompt.
|
| 559 |
+
|
| 560 |
+
Examples
|
| 561 |
+
--------
|
| 562 |
+
>>> np.info(np.polyval) # doctest: +SKIP
|
| 563 |
+
polyval(p, x)
|
| 564 |
+
Evaluate the polynomial p at x.
|
| 565 |
+
...
|
| 566 |
+
|
| 567 |
+
When using a string for `object` it is possible to get multiple results.
|
| 568 |
+
|
| 569 |
+
>>> np.info('fft') # doctest: +SKIP
|
| 570 |
+
*** Found in numpy ***
|
| 571 |
+
Core FFT routines
|
| 572 |
+
...
|
| 573 |
+
*** Found in numpy.fft ***
|
| 574 |
+
fft(a, n=None, axis=-1)
|
| 575 |
+
...
|
| 576 |
+
*** Repeat reference found in numpy.fft.fftpack ***
|
| 577 |
+
*** Total of 3 references found. ***
|
| 578 |
+
|
| 579 |
+
When the argument is an array, information about the array is printed.
|
| 580 |
+
|
| 581 |
+
>>> a = np.array([[1 + 2j, 3, -4], [-5j, 6, 0]], dtype=np.complex64)
|
| 582 |
+
>>> np.info(a)
|
| 583 |
+
class: ndarray
|
| 584 |
+
shape: (2, 3)
|
| 585 |
+
strides: (24, 8)
|
| 586 |
+
itemsize: 8
|
| 587 |
+
aligned: True
|
| 588 |
+
contiguous: True
|
| 589 |
+
fortran: False
|
| 590 |
+
data pointer: 0x562b6e0d2860 # may vary
|
| 591 |
+
byteorder: little
|
| 592 |
+
byteswap: False
|
| 593 |
+
type: complex64
|
| 594 |
+
|
| 595 |
+
"""
|
| 596 |
+
global _namedict, _dictlist
|
| 597 |
+
# Local import to speed up numpy's import time.
|
| 598 |
+
import pydoc
|
| 599 |
+
import inspect
|
| 600 |
+
|
| 601 |
+
if (hasattr(object, '_ppimport_importer') or
|
| 602 |
+
hasattr(object, '_ppimport_module')):
|
| 603 |
+
object = object._ppimport_module
|
| 604 |
+
elif hasattr(object, '_ppimport_attr'):
|
| 605 |
+
object = object._ppimport_attr
|
| 606 |
+
|
| 607 |
+
if output is None:
|
| 608 |
+
output = sys.stdout
|
| 609 |
+
|
| 610 |
+
if object is None:
|
| 611 |
+
info(info)
|
| 612 |
+
elif isinstance(object, ndarray):
|
| 613 |
+
_info(object, output=output)
|
| 614 |
+
elif isinstance(object, str):
|
| 615 |
+
if _namedict is None:
|
| 616 |
+
_namedict, _dictlist = _makenamedict(toplevel)
|
| 617 |
+
numfound = 0
|
| 618 |
+
objlist = []
|
| 619 |
+
for namestr in _dictlist:
|
| 620 |
+
try:
|
| 621 |
+
obj = _namedict[namestr][object]
|
| 622 |
+
if id(obj) in objlist:
|
| 623 |
+
print("\n "
|
| 624 |
+
"*** Repeat reference found in %s *** " % namestr,
|
| 625 |
+
file=output
|
| 626 |
+
)
|
| 627 |
+
else:
|
| 628 |
+
objlist.append(id(obj))
|
| 629 |
+
print(" *** Found in %s ***" % namestr, file=output)
|
| 630 |
+
info(obj)
|
| 631 |
+
print("-"*maxwidth, file=output)
|
| 632 |
+
numfound += 1
|
| 633 |
+
except KeyError:
|
| 634 |
+
pass
|
| 635 |
+
if numfound == 0:
|
| 636 |
+
print("Help for %s not found." % object, file=output)
|
| 637 |
+
else:
|
| 638 |
+
print("\n "
|
| 639 |
+
"*** Total of %d references found. ***" % numfound,
|
| 640 |
+
file=output
|
| 641 |
+
)
|
| 642 |
+
|
| 643 |
+
elif inspect.isfunction(object) or inspect.ismethod(object):
|
| 644 |
+
name = object.__name__
|
| 645 |
+
try:
|
| 646 |
+
arguments = str(inspect.signature(object))
|
| 647 |
+
except Exception:
|
| 648 |
+
arguments = "()"
|
| 649 |
+
|
| 650 |
+
if len(name+arguments) > maxwidth:
|
| 651 |
+
argstr = _split_line(name, arguments, maxwidth)
|
| 652 |
+
else:
|
| 653 |
+
argstr = name + arguments
|
| 654 |
+
|
| 655 |
+
print(" " + argstr + "\n", file=output)
|
| 656 |
+
print(inspect.getdoc(object), file=output)
|
| 657 |
+
|
| 658 |
+
elif inspect.isclass(object):
|
| 659 |
+
name = object.__name__
|
| 660 |
+
try:
|
| 661 |
+
arguments = str(inspect.signature(object))
|
| 662 |
+
except Exception:
|
| 663 |
+
arguments = "()"
|
| 664 |
+
|
| 665 |
+
if len(name+arguments) > maxwidth:
|
| 666 |
+
argstr = _split_line(name, arguments, maxwidth)
|
| 667 |
+
else:
|
| 668 |
+
argstr = name + arguments
|
| 669 |
+
|
| 670 |
+
print(" " + argstr + "\n", file=output)
|
| 671 |
+
doc1 = inspect.getdoc(object)
|
| 672 |
+
if doc1 is None:
|
| 673 |
+
if hasattr(object, '__init__'):
|
| 674 |
+
print(inspect.getdoc(object.__init__), file=output)
|
| 675 |
+
else:
|
| 676 |
+
print(inspect.getdoc(object), file=output)
|
| 677 |
+
|
| 678 |
+
methods = pydoc.allmethods(object)
|
| 679 |
+
|
| 680 |
+
public_methods = [meth for meth in methods if meth[0] != '_']
|
| 681 |
+
if public_methods:
|
| 682 |
+
print("\n\nMethods:\n", file=output)
|
| 683 |
+
for meth in public_methods:
|
| 684 |
+
thisobj = getattr(object, meth, None)
|
| 685 |
+
if thisobj is not None:
|
| 686 |
+
methstr, other = pydoc.splitdoc(
|
| 687 |
+
inspect.getdoc(thisobj) or "None"
|
| 688 |
+
)
|
| 689 |
+
print(" %s -- %s" % (meth, methstr), file=output)
|
| 690 |
+
|
| 691 |
+
elif hasattr(object, '__doc__'):
|
| 692 |
+
print(inspect.getdoc(object), file=output)
|
| 693 |
+
|
| 694 |
+
|
| 695 |
+
@set_module('numpy')
|
| 696 |
+
def source(object, output=sys.stdout):
|
| 697 |
+
"""
|
| 698 |
+
Print or write to a file the source code for a NumPy object.
|
| 699 |
+
|
| 700 |
+
The source code is only returned for objects written in Python. Many
|
| 701 |
+
functions and classes are defined in C and will therefore not return
|
| 702 |
+
useful information.
|
| 703 |
+
|
| 704 |
+
Parameters
|
| 705 |
+
----------
|
| 706 |
+
object : numpy object
|
| 707 |
+
Input object. This can be any object (function, class, module,
|
| 708 |
+
...).
|
| 709 |
+
output : file object, optional
|
| 710 |
+
If `output` not supplied then source code is printed to screen
|
| 711 |
+
(sys.stdout). File object must be created with either write 'w' or
|
| 712 |
+
append 'a' modes.
|
| 713 |
+
|
| 714 |
+
See Also
|
| 715 |
+
--------
|
| 716 |
+
lookfor, info
|
| 717 |
+
|
| 718 |
+
Examples
|
| 719 |
+
--------
|
| 720 |
+
>>> np.source(np.interp) #doctest: +SKIP
|
| 721 |
+
In file: /usr/lib/python2.6/dist-packages/numpy/lib/function_base.py
|
| 722 |
+
def interp(x, xp, fp, left=None, right=None):
|
| 723 |
+
\"\"\".... (full docstring printed)\"\"\"
|
| 724 |
+
if isinstance(x, (float, int, number)):
|
| 725 |
+
return compiled_interp([x], xp, fp, left, right).item()
|
| 726 |
+
else:
|
| 727 |
+
return compiled_interp(x, xp, fp, left, right)
|
| 728 |
+
|
| 729 |
+
The source code is only returned for objects written in Python.
|
| 730 |
+
|
| 731 |
+
>>> np.source(np.array) #doctest: +SKIP
|
| 732 |
+
Not available for this object.
|
| 733 |
+
|
| 734 |
+
"""
|
| 735 |
+
# Local import to speed up numpy's import time.
|
| 736 |
+
import inspect
|
| 737 |
+
try:
|
| 738 |
+
print("In file: %s\n" % inspect.getsourcefile(object), file=output)
|
| 739 |
+
print(inspect.getsource(object), file=output)
|
| 740 |
+
except Exception:
|
| 741 |
+
print("Not available for this object.", file=output)
|
| 742 |
+
|
| 743 |
+
|
| 744 |
+
# Cache for lookfor: {id(module): {name: (docstring, kind, index), ...}...}
|
| 745 |
+
# where kind: "func", "class", "module", "object"
|
| 746 |
+
# and index: index in breadth-first namespace traversal
|
| 747 |
+
_lookfor_caches = {}
|
| 748 |
+
|
| 749 |
+
# regexp whose match indicates that the string may contain a function
|
| 750 |
+
# signature
|
| 751 |
+
_function_signature_re = re.compile(r"[a-z0-9_]+\(.*[,=].*\)", re.I)
|
| 752 |
+
|
| 753 |
+
|
| 754 |
+
@set_module('numpy')
|
| 755 |
+
def lookfor(what, module=None, import_modules=True, regenerate=False,
|
| 756 |
+
output=None):
|
| 757 |
+
"""
|
| 758 |
+
Do a keyword search on docstrings.
|
| 759 |
+
|
| 760 |
+
A list of objects that matched the search is displayed,
|
| 761 |
+
sorted by relevance. All given keywords need to be found in the
|
| 762 |
+
docstring for it to be returned as a result, but the order does
|
| 763 |
+
not matter.
|
| 764 |
+
|
| 765 |
+
Parameters
|
| 766 |
+
----------
|
| 767 |
+
what : str
|
| 768 |
+
String containing words to look for.
|
| 769 |
+
module : str or list, optional
|
| 770 |
+
Name of module(s) whose docstrings to go through.
|
| 771 |
+
import_modules : bool, optional
|
| 772 |
+
Whether to import sub-modules in packages. Default is True.
|
| 773 |
+
regenerate : bool, optional
|
| 774 |
+
Whether to re-generate the docstring cache. Default is False.
|
| 775 |
+
output : file-like, optional
|
| 776 |
+
File-like object to write the output to. If omitted, use a pager.
|
| 777 |
+
|
| 778 |
+
See Also
|
| 779 |
+
--------
|
| 780 |
+
source, info
|
| 781 |
+
|
| 782 |
+
Notes
|
| 783 |
+
-----
|
| 784 |
+
Relevance is determined only roughly, by checking if the keywords occur
|
| 785 |
+
in the function name, at the start of a docstring, etc.
|
| 786 |
+
|
| 787 |
+
Examples
|
| 788 |
+
--------
|
| 789 |
+
>>> np.lookfor('binary representation') # doctest: +SKIP
|
| 790 |
+
Search results for 'binary representation'
|
| 791 |
+
------------------------------------------
|
| 792 |
+
numpy.binary_repr
|
| 793 |
+
Return the binary representation of the input number as a string.
|
| 794 |
+
numpy.core.setup_common.long_double_representation
|
| 795 |
+
Given a binary dump as given by GNU od -b, look for long double
|
| 796 |
+
numpy.base_repr
|
| 797 |
+
Return a string representation of a number in the given base system.
|
| 798 |
+
...
|
| 799 |
+
|
| 800 |
+
"""
|
| 801 |
+
import pydoc
|
| 802 |
+
|
| 803 |
+
# Cache
|
| 804 |
+
cache = _lookfor_generate_cache(module, import_modules, regenerate)
|
| 805 |
+
|
| 806 |
+
# Search
|
| 807 |
+
# XXX: maybe using a real stemming search engine would be better?
|
| 808 |
+
found = []
|
| 809 |
+
whats = str(what).lower().split()
|
| 810 |
+
if not whats:
|
| 811 |
+
return
|
| 812 |
+
|
| 813 |
+
for name, (docstring, kind, index) in cache.items():
|
| 814 |
+
if kind in ('module', 'object'):
|
| 815 |
+
# don't show modules or objects
|
| 816 |
+
continue
|
| 817 |
+
doc = docstring.lower()
|
| 818 |
+
if all(w in doc for w in whats):
|
| 819 |
+
found.append(name)
|
| 820 |
+
|
| 821 |
+
# Relevance sort
|
| 822 |
+
# XXX: this is full Harrison-Stetson heuristics now,
|
| 823 |
+
# XXX: it probably could be improved
|
| 824 |
+
|
| 825 |
+
kind_relevance = {'func': 1000, 'class': 1000,
|
| 826 |
+
'module': -1000, 'object': -1000}
|
| 827 |
+
|
| 828 |
+
def relevance(name, docstr, kind, index):
|
| 829 |
+
r = 0
|
| 830 |
+
# do the keywords occur within the start of the docstring?
|
| 831 |
+
first_doc = "\n".join(docstr.lower().strip().split("\n")[:3])
|
| 832 |
+
r += sum([200 for w in whats if w in first_doc])
|
| 833 |
+
# do the keywords occur in the function name?
|
| 834 |
+
r += sum([30 for w in whats if w in name])
|
| 835 |
+
# is the full name long?
|
| 836 |
+
r += -len(name) * 5
|
| 837 |
+
# is the object of bad type?
|
| 838 |
+
r += kind_relevance.get(kind, -1000)
|
| 839 |
+
# is the object deep in namespace hierarchy?
|
| 840 |
+
r += -name.count('.') * 10
|
| 841 |
+
r += max(-index / 100, -100)
|
| 842 |
+
return r
|
| 843 |
+
|
| 844 |
+
def relevance_value(a):
|
| 845 |
+
return relevance(a, *cache[a])
|
| 846 |
+
found.sort(key=relevance_value)
|
| 847 |
+
|
| 848 |
+
# Pretty-print
|
| 849 |
+
s = "Search results for '%s'" % (' '.join(whats))
|
| 850 |
+
help_text = [s, "-"*len(s)]
|
| 851 |
+
for name in found[::-1]:
|
| 852 |
+
doc, kind, ix = cache[name]
|
| 853 |
+
|
| 854 |
+
doclines = [line.strip() for line in doc.strip().split("\n")
|
| 855 |
+
if line.strip()]
|
| 856 |
+
|
| 857 |
+
# find a suitable short description
|
| 858 |
+
try:
|
| 859 |
+
first_doc = doclines[0].strip()
|
| 860 |
+
if _function_signature_re.search(first_doc):
|
| 861 |
+
first_doc = doclines[1].strip()
|
| 862 |
+
except IndexError:
|
| 863 |
+
first_doc = ""
|
| 864 |
+
help_text.append("%s\n %s" % (name, first_doc))
|
| 865 |
+
|
| 866 |
+
if not found:
|
| 867 |
+
help_text.append("Nothing found.")
|
| 868 |
+
|
| 869 |
+
# Output
|
| 870 |
+
if output is not None:
|
| 871 |
+
output.write("\n".join(help_text))
|
| 872 |
+
elif len(help_text) > 10:
|
| 873 |
+
pager = pydoc.getpager()
|
| 874 |
+
pager("\n".join(help_text))
|
| 875 |
+
else:
|
| 876 |
+
print("\n".join(help_text))
|
| 877 |
+
|
| 878 |
+
def _lookfor_generate_cache(module, import_modules, regenerate):
|
| 879 |
+
"""
|
| 880 |
+
Generate docstring cache for given module.
|
| 881 |
+
|
| 882 |
+
Parameters
|
| 883 |
+
----------
|
| 884 |
+
module : str, None, module
|
| 885 |
+
Module for which to generate docstring cache
|
| 886 |
+
import_modules : bool
|
| 887 |
+
Whether to import sub-modules in packages.
|
| 888 |
+
regenerate : bool
|
| 889 |
+
Re-generate the docstring cache
|
| 890 |
+
|
| 891 |
+
Returns
|
| 892 |
+
-------
|
| 893 |
+
cache : dict {obj_full_name: (docstring, kind, index), ...}
|
| 894 |
+
Docstring cache for the module, either cached one (regenerate=False)
|
| 895 |
+
or newly generated.
|
| 896 |
+
|
| 897 |
+
"""
|
| 898 |
+
# Local import to speed up numpy's import time.
|
| 899 |
+
import inspect
|
| 900 |
+
|
| 901 |
+
from io import StringIO
|
| 902 |
+
|
| 903 |
+
if module is None:
|
| 904 |
+
module = "numpy"
|
| 905 |
+
|
| 906 |
+
if isinstance(module, str):
|
| 907 |
+
try:
|
| 908 |
+
__import__(module)
|
| 909 |
+
except ImportError:
|
| 910 |
+
return {}
|
| 911 |
+
module = sys.modules[module]
|
| 912 |
+
elif isinstance(module, list) or isinstance(module, tuple):
|
| 913 |
+
cache = {}
|
| 914 |
+
for mod in module:
|
| 915 |
+
cache.update(_lookfor_generate_cache(mod, import_modules,
|
| 916 |
+
regenerate))
|
| 917 |
+
return cache
|
| 918 |
+
|
| 919 |
+
if id(module) in _lookfor_caches and not regenerate:
|
| 920 |
+
return _lookfor_caches[id(module)]
|
| 921 |
+
|
| 922 |
+
# walk items and collect docstrings
|
| 923 |
+
cache = {}
|
| 924 |
+
_lookfor_caches[id(module)] = cache
|
| 925 |
+
seen = {}
|
| 926 |
+
index = 0
|
| 927 |
+
stack = [(module.__name__, module)]
|
| 928 |
+
while stack:
|
| 929 |
+
name, item = stack.pop(0)
|
| 930 |
+
if id(item) in seen:
|
| 931 |
+
continue
|
| 932 |
+
seen[id(item)] = True
|
| 933 |
+
|
| 934 |
+
index += 1
|
| 935 |
+
kind = "object"
|
| 936 |
+
|
| 937 |
+
if inspect.ismodule(item):
|
| 938 |
+
kind = "module"
|
| 939 |
+
try:
|
| 940 |
+
_all = item.__all__
|
| 941 |
+
except AttributeError:
|
| 942 |
+
_all = None
|
| 943 |
+
|
| 944 |
+
# import sub-packages
|
| 945 |
+
if import_modules and hasattr(item, '__path__'):
|
| 946 |
+
for pth in item.__path__:
|
| 947 |
+
for mod_path in os.listdir(pth):
|
| 948 |
+
this_py = os.path.join(pth, mod_path)
|
| 949 |
+
init_py = os.path.join(pth, mod_path, '__init__.py')
|
| 950 |
+
if (os.path.isfile(this_py) and
|
| 951 |
+
mod_path.endswith('.py')):
|
| 952 |
+
to_import = mod_path[:-3]
|
| 953 |
+
elif os.path.isfile(init_py):
|
| 954 |
+
to_import = mod_path
|
| 955 |
+
else:
|
| 956 |
+
continue
|
| 957 |
+
if to_import == '__init__':
|
| 958 |
+
continue
|
| 959 |
+
|
| 960 |
+
try:
|
| 961 |
+
old_stdout = sys.stdout
|
| 962 |
+
old_stderr = sys.stderr
|
| 963 |
+
try:
|
| 964 |
+
sys.stdout = StringIO()
|
| 965 |
+
sys.stderr = StringIO()
|
| 966 |
+
__import__("%s.%s" % (name, to_import))
|
| 967 |
+
finally:
|
| 968 |
+
sys.stdout = old_stdout
|
| 969 |
+
sys.stderr = old_stderr
|
| 970 |
+
except KeyboardInterrupt:
|
| 971 |
+
# Assume keyboard interrupt came from a user
|
| 972 |
+
raise
|
| 973 |
+
except BaseException:
|
| 974 |
+
# Ignore also SystemExit and pytests.importorskip
|
| 975 |
+
# `Skipped` (these are BaseExceptions; gh-22345)
|
| 976 |
+
continue
|
| 977 |
+
|
| 978 |
+
for n, v in _getmembers(item):
|
| 979 |
+
try:
|
| 980 |
+
item_name = getattr(v, '__name__', "%s.%s" % (name, n))
|
| 981 |
+
mod_name = getattr(v, '__module__', None)
|
| 982 |
+
except NameError:
|
| 983 |
+
# ref. SWIG's global cvars
|
| 984 |
+
# NameError: Unknown C global variable
|
| 985 |
+
item_name = "%s.%s" % (name, n)
|
| 986 |
+
mod_name = None
|
| 987 |
+
if '.' not in item_name and mod_name:
|
| 988 |
+
item_name = "%s.%s" % (mod_name, item_name)
|
| 989 |
+
|
| 990 |
+
if not item_name.startswith(name + '.'):
|
| 991 |
+
# don't crawl "foreign" objects
|
| 992 |
+
if isinstance(v, ufunc):
|
| 993 |
+
# ... unless they are ufuncs
|
| 994 |
+
pass
|
| 995 |
+
else:
|
| 996 |
+
continue
|
| 997 |
+
elif not (inspect.ismodule(v) or _all is None or n in _all):
|
| 998 |
+
continue
|
| 999 |
+
stack.append(("%s.%s" % (name, n), v))
|
| 1000 |
+
elif inspect.isclass(item):
|
| 1001 |
+
kind = "class"
|
| 1002 |
+
for n, v in _getmembers(item):
|
| 1003 |
+
stack.append(("%s.%s" % (name, n), v))
|
| 1004 |
+
elif hasattr(item, "__call__"):
|
| 1005 |
+
kind = "func"
|
| 1006 |
+
|
| 1007 |
+
try:
|
| 1008 |
+
doc = inspect.getdoc(item)
|
| 1009 |
+
except NameError:
|
| 1010 |
+
# ref SWIG's NameError: Unknown C global variable
|
| 1011 |
+
doc = None
|
| 1012 |
+
if doc is not None:
|
| 1013 |
+
cache[name] = (doc, kind, index)
|
| 1014 |
+
|
| 1015 |
+
return cache
|
| 1016 |
+
|
| 1017 |
+
def _getmembers(item):
|
| 1018 |
+
import inspect
|
| 1019 |
+
try:
|
| 1020 |
+
members = inspect.getmembers(item)
|
| 1021 |
+
except Exception:
|
| 1022 |
+
members = [(x, getattr(item, x)) for x in dir(item)
|
| 1023 |
+
if hasattr(item, x)]
|
| 1024 |
+
return members
|
| 1025 |
+
|
| 1026 |
+
|
| 1027 |
+
def safe_eval(source):
|
| 1028 |
+
"""
|
| 1029 |
+
Protected string evaluation.
|
| 1030 |
+
|
| 1031 |
+
Evaluate a string containing a Python literal expression without
|
| 1032 |
+
allowing the execution of arbitrary non-literal code.
|
| 1033 |
+
|
| 1034 |
+
.. warning::
|
| 1035 |
+
|
| 1036 |
+
This function is identical to :py:meth:`ast.literal_eval` and
|
| 1037 |
+
has the same security implications. It may not always be safe
|
| 1038 |
+
to evaluate large input strings.
|
| 1039 |
+
|
| 1040 |
+
Parameters
|
| 1041 |
+
----------
|
| 1042 |
+
source : str
|
| 1043 |
+
The string to evaluate.
|
| 1044 |
+
|
| 1045 |
+
Returns
|
| 1046 |
+
-------
|
| 1047 |
+
obj : object
|
| 1048 |
+
The result of evaluating `source`.
|
| 1049 |
+
|
| 1050 |
+
Raises
|
| 1051 |
+
------
|
| 1052 |
+
SyntaxError
|
| 1053 |
+
If the code has invalid Python syntax, or if it contains
|
| 1054 |
+
non-literal code.
|
| 1055 |
+
|
| 1056 |
+
Examples
|
| 1057 |
+
--------
|
| 1058 |
+
>>> np.safe_eval('1')
|
| 1059 |
+
1
|
| 1060 |
+
>>> np.safe_eval('[1, 2, 3]')
|
| 1061 |
+
[1, 2, 3]
|
| 1062 |
+
>>> np.safe_eval('{"foo": ("bar", 10.0)}')
|
| 1063 |
+
{'foo': ('bar', 10.0)}
|
| 1064 |
+
|
| 1065 |
+
>>> np.safe_eval('import os')
|
| 1066 |
+
Traceback (most recent call last):
|
| 1067 |
+
...
|
| 1068 |
+
SyntaxError: invalid syntax
|
| 1069 |
+
|
| 1070 |
+
>>> np.safe_eval('open("/home/user/.ssh/id_dsa").read()')
|
| 1071 |
+
Traceback (most recent call last):
|
| 1072 |
+
...
|
| 1073 |
+
ValueError: malformed node or string: <_ast.Call object at 0x...>
|
| 1074 |
+
|
| 1075 |
+
"""
|
| 1076 |
+
# Local import to speed up numpy's import time.
|
| 1077 |
+
import ast
|
| 1078 |
+
return ast.literal_eval(source)
|
| 1079 |
+
|
| 1080 |
+
|
| 1081 |
+
def _median_nancheck(data, result, axis):
|
| 1082 |
+
"""
|
| 1083 |
+
Utility function to check median result from data for NaN values at the end
|
| 1084 |
+
and return NaN in that case. Input result can also be a MaskedArray.
|
| 1085 |
+
|
| 1086 |
+
Parameters
|
| 1087 |
+
----------
|
| 1088 |
+
data : array
|
| 1089 |
+
Sorted input data to median function
|
| 1090 |
+
result : Array or MaskedArray
|
| 1091 |
+
Result of median function.
|
| 1092 |
+
axis : int
|
| 1093 |
+
Axis along which the median was computed.
|
| 1094 |
+
|
| 1095 |
+
Returns
|
| 1096 |
+
-------
|
| 1097 |
+
result : scalar or ndarray
|
| 1098 |
+
Median or NaN in axes which contained NaN in the input. If the input
|
| 1099 |
+
was an array, NaN will be inserted in-place. If a scalar, either the
|
| 1100 |
+
input itself or a scalar NaN.
|
| 1101 |
+
"""
|
| 1102 |
+
if data.size == 0:
|
| 1103 |
+
return result
|
| 1104 |
+
potential_nans = data.take(-1, axis=axis)
|
| 1105 |
+
n = np.isnan(potential_nans)
|
| 1106 |
+
# masked NaN values are ok, although for masked the copyto may fail for
|
| 1107 |
+
# unmasked ones (this was always broken) when the result is a scalar.
|
| 1108 |
+
if np.ma.isMaskedArray(n):
|
| 1109 |
+
n = n.filled(False)
|
| 1110 |
+
|
| 1111 |
+
if not n.any():
|
| 1112 |
+
return result
|
| 1113 |
+
|
| 1114 |
+
# Without given output, it is possible that the current result is a
|
| 1115 |
+
# numpy scalar, which is not writeable. If so, just return nan.
|
| 1116 |
+
if isinstance(result, np.generic):
|
| 1117 |
+
return potential_nans
|
| 1118 |
+
|
| 1119 |
+
# Otherwise copy NaNs (if there are any)
|
| 1120 |
+
np.copyto(result, potential_nans, where=n)
|
| 1121 |
+
return result
|
| 1122 |
+
|
| 1123 |
+
def _opt_info():
|
| 1124 |
+
"""
|
| 1125 |
+
Returns a string contains the supported CPU features by the current build.
|
| 1126 |
+
|
| 1127 |
+
The string format can be explained as follows:
|
| 1128 |
+
- dispatched features that are supported by the running machine
|
| 1129 |
+
end with `*`.
|
| 1130 |
+
- dispatched features that are "not" supported by the running machine
|
| 1131 |
+
end with `?`.
|
| 1132 |
+
- remained features are representing the baseline.
|
| 1133 |
+
"""
|
| 1134 |
+
from numpy.core._multiarray_umath import (
|
| 1135 |
+
__cpu_features__, __cpu_baseline__, __cpu_dispatch__
|
| 1136 |
+
)
|
| 1137 |
+
|
| 1138 |
+
if len(__cpu_baseline__) == 0 and len(__cpu_dispatch__) == 0:
|
| 1139 |
+
return ''
|
| 1140 |
+
|
| 1141 |
+
enabled_features = ' '.join(__cpu_baseline__)
|
| 1142 |
+
for feature in __cpu_dispatch__:
|
| 1143 |
+
if __cpu_features__[feature]:
|
| 1144 |
+
enabled_features += f" {feature}*"
|
| 1145 |
+
else:
|
| 1146 |
+
enabled_features += f" {feature}?"
|
| 1147 |
+
|
| 1148 |
+
return enabled_features
|
| 1149 |
+
|
| 1150 |
+
|
| 1151 |
+
def drop_metadata(dtype, /):
|
| 1152 |
+
"""
|
| 1153 |
+
Returns the dtype unchanged if it contained no metadata or a copy of the
|
| 1154 |
+
dtype if it (or any of its structure dtypes) contained metadata.
|
| 1155 |
+
|
| 1156 |
+
This utility is used by `np.save` and `np.savez` to drop metadata before
|
| 1157 |
+
saving.
|
| 1158 |
+
|
| 1159 |
+
.. note::
|
| 1160 |
+
|
| 1161 |
+
Due to its limitation this function may move to a more appropriate
|
| 1162 |
+
home or change in the future and is considered semi-public API only.
|
| 1163 |
+
|
| 1164 |
+
.. warning::
|
| 1165 |
+
|
| 1166 |
+
This function does not preserve more strange things like record dtypes
|
| 1167 |
+
and user dtypes may simply return the wrong thing. If you need to be
|
| 1168 |
+
sure about the latter, check the result with:
|
| 1169 |
+
``np.can_cast(new_dtype, dtype, casting="no")``.
|
| 1170 |
+
|
| 1171 |
+
"""
|
| 1172 |
+
if dtype.fields is not None:
|
| 1173 |
+
found_metadata = dtype.metadata is not None
|
| 1174 |
+
|
| 1175 |
+
names = []
|
| 1176 |
+
formats = []
|
| 1177 |
+
offsets = []
|
| 1178 |
+
titles = []
|
| 1179 |
+
for name, field in dtype.fields.items():
|
| 1180 |
+
field_dt = drop_metadata(field[0])
|
| 1181 |
+
if field_dt is not field[0]:
|
| 1182 |
+
found_metadata = True
|
| 1183 |
+
|
| 1184 |
+
names.append(name)
|
| 1185 |
+
formats.append(field_dt)
|
| 1186 |
+
offsets.append(field[1])
|
| 1187 |
+
titles.append(None if len(field) < 3 else field[2])
|
| 1188 |
+
|
| 1189 |
+
if not found_metadata:
|
| 1190 |
+
return dtype
|
| 1191 |
+
|
| 1192 |
+
structure = dict(
|
| 1193 |
+
names=names, formats=formats, offsets=offsets, titles=titles,
|
| 1194 |
+
itemsize=dtype.itemsize)
|
| 1195 |
+
|
| 1196 |
+
# NOTE: Could pass (dtype.type, structure) to preserve record dtypes...
|
| 1197 |
+
return np.dtype(structure, align=dtype.isalignedstruct)
|
| 1198 |
+
elif dtype.subdtype is not None:
|
| 1199 |
+
# subarray dtype
|
| 1200 |
+
subdtype, shape = dtype.subdtype
|
| 1201 |
+
new_subdtype = drop_metadata(subdtype)
|
| 1202 |
+
if dtype.metadata is None and new_subdtype is subdtype:
|
| 1203 |
+
return dtype
|
| 1204 |
+
|
| 1205 |
+
return np.dtype((new_subdtype, shape))
|
| 1206 |
+
else:
|
| 1207 |
+
# Normal unstructured dtype
|
| 1208 |
+
if dtype.metadata is None:
|
| 1209 |
+
return dtype
|
| 1210 |
+
# Note that `dt.str` doesn't round-trip e.g. for user-dtypes.
|
| 1211 |
+
return np.dtype(dtype.str)
|
LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/transformers/models/barthez/__init__.py
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2024 The HuggingFace Team. All rights reserved.
|
| 2 |
+
#
|
| 3 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 4 |
+
# you may not use this file except in compliance with the License.
|
| 5 |
+
# You may obtain a copy of the License at
|
| 6 |
+
#
|
| 7 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 8 |
+
#
|
| 9 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 10 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 11 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 12 |
+
# See the License for the specific language governing permissions and
|
| 13 |
+
# limitations under the License.
|
| 14 |
+
from typing import TYPE_CHECKING
|
| 15 |
+
|
| 16 |
+
from ...utils import _LazyModule
|
| 17 |
+
from ...utils.import_utils import define_import_structure
|
| 18 |
+
|
| 19 |
+
|
| 20 |
+
if TYPE_CHECKING:
|
| 21 |
+
from .tokenization_barthez import *
|
| 22 |
+
else:
|
| 23 |
+
import sys
|
| 24 |
+
|
| 25 |
+
_file = globals()["__file__"]
|
| 26 |
+
sys.modules[__name__] = _LazyModule(__name__, _file, define_import_structure(_file), module_spec=__spec__)
|
LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/transformers/models/barthez/tokenization_barthez.py
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2020 Ecole Polytechnique and the HuggingFace Inc. team.
|
| 2 |
+
#
|
| 3 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 4 |
+
# you may not use this file except in compliance with the License.
|
| 5 |
+
# You may obtain a copy of the License at
|
| 6 |
+
#
|
| 7 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 8 |
+
#
|
| 9 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 10 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 11 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 12 |
+
# See the License for the specific language governing permissions and
|
| 13 |
+
# limitations under the License
|
| 14 |
+
"""Tokenization classes for the BARThez model."""
|
| 15 |
+
|
| 16 |
+
from tokenizers import Regex, Tokenizer, decoders, normalizers, pre_tokenizers
|
| 17 |
+
from tokenizers.models import Unigram
|
| 18 |
+
|
| 19 |
+
from ...tokenization_python import AddedToken
|
| 20 |
+
from ...tokenization_utils_tokenizers import TokenizersBackend
|
| 21 |
+
from ...utils import logging
|
| 22 |
+
|
| 23 |
+
|
| 24 |
+
logger = logging.get_logger(__name__)
|
| 25 |
+
|
| 26 |
+
VOCAB_FILES_NAMES = {"vocab_file": "sentencepiece.bpe.model", "tokenizer_file": "tokenizer.json"}
|
| 27 |
+
|
| 28 |
+
|
| 29 |
+
SPIECE_UNDERLINE = "▁"
|
| 30 |
+
|
| 31 |
+
|
| 32 |
+
class BarthezTokenizer(TokenizersBackend):
|
| 33 |
+
"""
|
| 34 |
+
Adapted from [`CamembertTokenizer`] and [`BartTokenizer`]. Construct a "fast" BARThez tokenizer. Based on
|
| 35 |
+
[SentencePiece](https://github.com/google/sentencepiece).
|
| 36 |
+
|
| 37 |
+
This tokenizer inherits from [`PreTrainedTokenizerFast`] which contains most of the main methods. Users should
|
| 38 |
+
refer to this superclass for more information regarding those methods.
|
| 39 |
+
|
| 40 |
+
Args:
|
| 41 |
+
bos_token (`str`, *optional*, defaults to `"<s>"`):
|
| 42 |
+
The beginning of sequence token that was used during pretraining. Can be used a sequence classifier token.
|
| 43 |
+
|
| 44 |
+
<Tip>
|
| 45 |
+
|
| 46 |
+
When building a sequence using special tokens, this is not the token that is used for the beginning of
|
| 47 |
+
sequence. The token used is the `cls_token`.
|
| 48 |
+
|
| 49 |
+
</Tip>
|
| 50 |
+
|
| 51 |
+
eos_token (`str`, *optional*, defaults to `"</s>"`):
|
| 52 |
+
The end of sequence token.
|
| 53 |
+
|
| 54 |
+
<Tip>
|
| 55 |
+
|
| 56 |
+
When building a sequence using special tokens, this is not the token that is used for the end of sequence.
|
| 57 |
+
The token used is the `sep_token`.
|
| 58 |
+
|
| 59 |
+
</Tip>
|
| 60 |
+
|
| 61 |
+
sep_token (`str`, *optional*, defaults to `"</s>"`):
|
| 62 |
+
The separator token, which is used when building a sequence from multiple sequences, e.g. two sequences for
|
| 63 |
+
sequence classification or for a text and a question for question answering. It is also used as the last
|
| 64 |
+
token of a sequence built with special tokens.
|
| 65 |
+
cls_token (`str`, *optional*, defaults to `"<s>"`):
|
| 66 |
+
The classifier token which is used when doing sequence classification (classification of the whole sequence
|
| 67 |
+
instead of per-token classification). It is the first token of the sequence when built with special tokens.
|
| 68 |
+
unk_token (`str`, *optional*, defaults to `"<unk>"`):
|
| 69 |
+
The unknown token. A token that is not in the vocabulary cannot be converted to an ID and is set to be this
|
| 70 |
+
token instead.
|
| 71 |
+
pad_token (`str`, *optional*, defaults to `"<pad>"`):
|
| 72 |
+
The token used for padding, for example when batching sequences of different lengths.
|
| 73 |
+
mask_token (`str`, *optional*, defaults to `"<mask>"`):
|
| 74 |
+
The token used for masking values. This is the token used when training this model with masked language
|
| 75 |
+
modeling. This is the token which the model will try to predict.
|
| 76 |
+
vocab_file (`str`, *optional*):
|
| 77 |
+
[SentencePiece](https://github.com/google/sentencepiece) file (generally has a *.spm* extension) that
|
| 78 |
+
contains the vocabulary necessary to instantiate a tokenizer.
|
| 79 |
+
vocab (`str`, `dict` or `list`, *optional*):
|
| 80 |
+
Custom vocabulary dictionary. If not provided, vocabulary is loaded from vocab_file.
|
| 81 |
+
add_prefix_space (`bool`, *optional*, defaults to `True`):
|
| 82 |
+
Whether or not to add an initial space to the input. This allows to treat the leading word just as any
|
| 83 |
+
other word.
|
| 84 |
+
"""
|
| 85 |
+
|
| 86 |
+
vocab_files_names = VOCAB_FILES_NAMES
|
| 87 |
+
model_input_names = ["input_ids", "attention_mask"]
|
| 88 |
+
slow_tokenizer_class = None
|
| 89 |
+
|
| 90 |
+
def __init__(
|
| 91 |
+
self,
|
| 92 |
+
vocab: str | dict | list | None = None,
|
| 93 |
+
bos_token="<s>",
|
| 94 |
+
eos_token="</s>",
|
| 95 |
+
sep_token="</s>",
|
| 96 |
+
cls_token="<s>",
|
| 97 |
+
unk_token="<unk>",
|
| 98 |
+
pad_token="<pad>",
|
| 99 |
+
mask_token="<mask>",
|
| 100 |
+
add_prefix_space=True,
|
| 101 |
+
**kwargs,
|
| 102 |
+
):
|
| 103 |
+
# Mask token behave like a normal word, i.e. include the space before it
|
| 104 |
+
mask_token = AddedToken(mask_token, lstrip=True, rstrip=False) if isinstance(mask_token, str) else mask_token
|
| 105 |
+
self.add_prefix_space = add_prefix_space
|
| 106 |
+
|
| 107 |
+
if vocab is not None:
|
| 108 |
+
self._vocab = vocab
|
| 109 |
+
else:
|
| 110 |
+
self._vocab = [
|
| 111 |
+
(str(pad_token), 0.0),
|
| 112 |
+
(str(unk_token), 0.0),
|
| 113 |
+
(str(cls_token), 0.0),
|
| 114 |
+
(str(sep_token), 0.0),
|
| 115 |
+
(str(mask_token), 0.0),
|
| 116 |
+
]
|
| 117 |
+
|
| 118 |
+
self._tokenizer = Tokenizer(Unigram(self._vocab, unk_id=3, byte_fallback=False))
|
| 119 |
+
|
| 120 |
+
self._tokenizer.normalizer = normalizers.Sequence(
|
| 121 |
+
[
|
| 122 |
+
normalizers.Replace(Regex(r"\s{2,}|[\n\r\t]"), " "),
|
| 123 |
+
normalizers.NFC(),
|
| 124 |
+
normalizers.Strip(left=False, right=True),
|
| 125 |
+
]
|
| 126 |
+
)
|
| 127 |
+
prepend_scheme = "always" if add_prefix_space else "never"
|
| 128 |
+
self._tokenizer.pre_tokenizer = pre_tokenizers.Metaspace(replacement="▁", prepend_scheme=prepend_scheme)
|
| 129 |
+
self._tokenizer.decoder = decoders.Metaspace(replacement="▁", prepend_scheme=prepend_scheme)
|
| 130 |
+
|
| 131 |
+
super().__init__(
|
| 132 |
+
bos_token=bos_token,
|
| 133 |
+
eos_token=eos_token,
|
| 134 |
+
unk_token=unk_token,
|
| 135 |
+
sep_token=sep_token,
|
| 136 |
+
cls_token=cls_token,
|
| 137 |
+
pad_token=pad_token,
|
| 138 |
+
mask_token=mask_token,
|
| 139 |
+
add_prefix_space=add_prefix_space,
|
| 140 |
+
**kwargs,
|
| 141 |
+
)
|
| 142 |
+
|
| 143 |
+
|
| 144 |
+
__all__ = ["BarthezTokenizer"]
|
LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/transformers/models/bert/__init__.py
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2024 The HuggingFace Team. All rights reserved.
|
| 2 |
+
#
|
| 3 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 4 |
+
# you may not use this file except in compliance with the License.
|
| 5 |
+
# You may obtain a copy of the License at
|
| 6 |
+
#
|
| 7 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 8 |
+
#
|
| 9 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 10 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 11 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 12 |
+
# See the License for the specific language governing permissions and
|
| 13 |
+
# limitations under the License.
|
| 14 |
+
from typing import TYPE_CHECKING
|
| 15 |
+
|
| 16 |
+
from ...utils import _LazyModule
|
| 17 |
+
from ...utils.import_utils import define_import_structure
|
| 18 |
+
|
| 19 |
+
|
| 20 |
+
if TYPE_CHECKING:
|
| 21 |
+
from .configuration_bert import *
|
| 22 |
+
from .modeling_bert import *
|
| 23 |
+
from .tokenization_bert import *
|
| 24 |
+
else:
|
| 25 |
+
import sys
|
| 26 |
+
|
| 27 |
+
_file = globals()["__file__"]
|
| 28 |
+
sys.modules[__name__] = _LazyModule(__name__, _file, define_import_structure(_file), module_spec=__spec__)
|
LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/transformers/models/bert/configuration_bert.py
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2018 The Google AI Language Team Authors and The HuggingFace Inc. team.
|
| 2 |
+
# Copyright (c) 2018, NVIDIA CORPORATION. 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 |
+
"""BERT model configuration"""
|
| 16 |
+
|
| 17 |
+
from huggingface_hub.dataclasses import strict
|
| 18 |
+
|
| 19 |
+
from ...configuration_utils import PreTrainedConfig
|
| 20 |
+
from ...utils import auto_docstring
|
| 21 |
+
|
| 22 |
+
|
| 23 |
+
@auto_docstring(checkpoint="google-bert/bert-base-uncased")
|
| 24 |
+
@strict
|
| 25 |
+
class BertConfig(PreTrainedConfig):
|
| 26 |
+
r"""
|
| 27 |
+
Examples:
|
| 28 |
+
|
| 29 |
+
```python
|
| 30 |
+
>>> from transformers import BertConfig, BertModel
|
| 31 |
+
|
| 32 |
+
>>> # Initializing a BERT google-bert/bert-base-uncased style configuration
|
| 33 |
+
>>> configuration = BertConfig()
|
| 34 |
+
|
| 35 |
+
>>> # Initializing a model (with random weights) from the google-bert/bert-base-uncased style configuration
|
| 36 |
+
>>> model = BertModel(configuration)
|
| 37 |
+
|
| 38 |
+
>>> # Accessing the model configuration
|
| 39 |
+
>>> configuration = model.config
|
| 40 |
+
```"""
|
| 41 |
+
|
| 42 |
+
model_type = "bert"
|
| 43 |
+
|
| 44 |
+
vocab_size: int = 30522
|
| 45 |
+
hidden_size: int = 768
|
| 46 |
+
num_hidden_layers: int = 12
|
| 47 |
+
num_attention_heads: int = 12
|
| 48 |
+
intermediate_size: int = 3072
|
| 49 |
+
hidden_act: str = "gelu"
|
| 50 |
+
hidden_dropout_prob: float | int = 0.1
|
| 51 |
+
attention_probs_dropout_prob: float | int = 0.1
|
| 52 |
+
max_position_embeddings: int = 512
|
| 53 |
+
type_vocab_size: int = 2
|
| 54 |
+
initializer_range: float = 0.02
|
| 55 |
+
layer_norm_eps: float = 1e-12
|
| 56 |
+
pad_token_id: int | None = 0
|
| 57 |
+
use_cache: bool = True
|
| 58 |
+
classifier_dropout: float | int | None = None
|
| 59 |
+
is_decoder: bool = False
|
| 60 |
+
add_cross_attention: bool = False
|
| 61 |
+
bos_token_id: int | None = None
|
| 62 |
+
eos_token_id: int | list[int] | None = None
|
| 63 |
+
tie_word_embeddings: bool = True
|
| 64 |
+
|
| 65 |
+
|
| 66 |
+
__all__ = ["BertConfig"]
|
LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/transformers/models/bert/modeling_bert.py
ADDED
|
@@ -0,0 +1,1394 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2018 The Google AI Language Team Authors and The HuggingFace Inc. team.
|
| 2 |
+
# Copyright (c) 2018, NVIDIA CORPORATION. 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 BERT model."""
|
| 16 |
+
|
| 17 |
+
from collections.abc import Callable
|
| 18 |
+
from dataclasses import dataclass
|
| 19 |
+
|
| 20 |
+
import torch
|
| 21 |
+
from torch import nn
|
| 22 |
+
from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss
|
| 23 |
+
|
| 24 |
+
from ... import initialization as init
|
| 25 |
+
from ...activations import ACT2FN
|
| 26 |
+
from ...cache_utils import Cache, DynamicCache, EncoderDecoderCache
|
| 27 |
+
from ...generation import GenerationMixin
|
| 28 |
+
from ...masking_utils import create_bidirectional_mask, create_causal_mask
|
| 29 |
+
from ...modeling_layers import GradientCheckpointingLayer
|
| 30 |
+
from ...modeling_outputs import (
|
| 31 |
+
BaseModelOutputWithPastAndCrossAttentions,
|
| 32 |
+
BaseModelOutputWithPoolingAndCrossAttentions,
|
| 33 |
+
CausalLMOutputWithCrossAttentions,
|
| 34 |
+
MaskedLMOutput,
|
| 35 |
+
MultipleChoiceModelOutput,
|
| 36 |
+
NextSentencePredictorOutput,
|
| 37 |
+
QuestionAnsweringModelOutput,
|
| 38 |
+
SequenceClassifierOutput,
|
| 39 |
+
TokenClassifierOutput,
|
| 40 |
+
)
|
| 41 |
+
from ...modeling_utils import ALL_ATTENTION_FUNCTIONS, PreTrainedModel
|
| 42 |
+
from ...processing_utils import Unpack
|
| 43 |
+
from ...pytorch_utils import apply_chunking_to_forward
|
| 44 |
+
from ...utils import ModelOutput, TransformersKwargs, auto_docstring, logging
|
| 45 |
+
from ...utils.generic import can_return_tuple, merge_with_config_defaults
|
| 46 |
+
from ...utils.output_capturing import capture_outputs
|
| 47 |
+
from .configuration_bert import BertConfig
|
| 48 |
+
|
| 49 |
+
|
| 50 |
+
logger = logging.get_logger(__name__)
|
| 51 |
+
|
| 52 |
+
|
| 53 |
+
class BertEmbeddings(nn.Module):
|
| 54 |
+
"""Construct the embeddings from word, position and token_type embeddings."""
|
| 55 |
+
|
| 56 |
+
def __init__(self, config):
|
| 57 |
+
super().__init__()
|
| 58 |
+
self.word_embeddings = nn.Embedding(config.vocab_size, config.hidden_size, padding_idx=config.pad_token_id)
|
| 59 |
+
self.position_embeddings = nn.Embedding(config.max_position_embeddings, config.hidden_size)
|
| 60 |
+
self.token_type_embeddings = nn.Embedding(config.type_vocab_size, config.hidden_size)
|
| 61 |
+
|
| 62 |
+
self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps)
|
| 63 |
+
self.dropout = nn.Dropout(config.hidden_dropout_prob)
|
| 64 |
+
# position_ids (1, len position emb) is contiguous in memory and exported when serialized
|
| 65 |
+
self.register_buffer(
|
| 66 |
+
"position_ids", torch.arange(config.max_position_embeddings).expand((1, -1)), persistent=False
|
| 67 |
+
)
|
| 68 |
+
self.register_buffer(
|
| 69 |
+
"token_type_ids", torch.zeros(self.position_ids.size(), dtype=torch.long), persistent=False
|
| 70 |
+
)
|
| 71 |
+
|
| 72 |
+
def forward(
|
| 73 |
+
self,
|
| 74 |
+
input_ids: torch.LongTensor | None = None,
|
| 75 |
+
token_type_ids: torch.LongTensor | None = None,
|
| 76 |
+
position_ids: torch.LongTensor | None = None,
|
| 77 |
+
inputs_embeds: torch.FloatTensor | None = None,
|
| 78 |
+
past_key_values_length: int = 0,
|
| 79 |
+
) -> torch.Tensor:
|
| 80 |
+
if input_ids is not None:
|
| 81 |
+
input_shape = input_ids.size()
|
| 82 |
+
else:
|
| 83 |
+
input_shape = inputs_embeds.size()[:-1]
|
| 84 |
+
|
| 85 |
+
batch_size, seq_length = input_shape
|
| 86 |
+
|
| 87 |
+
if position_ids is None:
|
| 88 |
+
position_ids = self.position_ids[:, past_key_values_length : seq_length + past_key_values_length]
|
| 89 |
+
|
| 90 |
+
# Setting the token_type_ids to the registered buffer in constructor where it is all zeros, which usually occurs
|
| 91 |
+
# when its auto-generated, registered buffer helps users when tracing the model without passing token_type_ids, solves
|
| 92 |
+
# issue #5664
|
| 93 |
+
if token_type_ids is None:
|
| 94 |
+
if hasattr(self, "token_type_ids"):
|
| 95 |
+
# NOTE: We assume either pos ids to have bsz == 1 (broadcastable) or bsz == effective bsz (input_shape[0])
|
| 96 |
+
buffered_token_type_ids = self.token_type_ids.expand(position_ids.shape[0], -1)
|
| 97 |
+
buffered_token_type_ids = torch.gather(buffered_token_type_ids, dim=1, index=position_ids)
|
| 98 |
+
token_type_ids = buffered_token_type_ids.expand(batch_size, seq_length)
|
| 99 |
+
else:
|
| 100 |
+
token_type_ids = torch.zeros(input_shape, dtype=torch.long, device=self.position_ids.device)
|
| 101 |
+
|
| 102 |
+
if inputs_embeds is None:
|
| 103 |
+
inputs_embeds = self.word_embeddings(input_ids)
|
| 104 |
+
token_type_embeddings = self.token_type_embeddings(token_type_ids)
|
| 105 |
+
embeddings = inputs_embeds + token_type_embeddings
|
| 106 |
+
|
| 107 |
+
position_embeddings = self.position_embeddings(position_ids)
|
| 108 |
+
embeddings = embeddings + position_embeddings
|
| 109 |
+
|
| 110 |
+
embeddings = self.LayerNorm(embeddings)
|
| 111 |
+
embeddings = self.dropout(embeddings)
|
| 112 |
+
return embeddings
|
| 113 |
+
|
| 114 |
+
|
| 115 |
+
def eager_attention_forward(
|
| 116 |
+
module: nn.Module,
|
| 117 |
+
query: torch.Tensor,
|
| 118 |
+
key: torch.Tensor,
|
| 119 |
+
value: torch.Tensor,
|
| 120 |
+
attention_mask: torch.Tensor | None,
|
| 121 |
+
scaling: float | None = None,
|
| 122 |
+
dropout: float = 0.0,
|
| 123 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 124 |
+
):
|
| 125 |
+
if scaling is None:
|
| 126 |
+
scaling = query.size(-1) ** -0.5
|
| 127 |
+
|
| 128 |
+
# Take the dot product between "query" and "key" to get the raw attention scores.
|
| 129 |
+
attn_weights = torch.matmul(query, key.transpose(2, 3)) * scaling
|
| 130 |
+
|
| 131 |
+
if attention_mask is not None:
|
| 132 |
+
attn_weights = attn_weights + attention_mask
|
| 133 |
+
|
| 134 |
+
attn_weights = nn.functional.softmax(attn_weights, dim=-1)
|
| 135 |
+
attn_weights = nn.functional.dropout(attn_weights, p=dropout, training=module.training)
|
| 136 |
+
|
| 137 |
+
attn_output = torch.matmul(attn_weights, value)
|
| 138 |
+
attn_output = attn_output.transpose(1, 2).contiguous()
|
| 139 |
+
|
| 140 |
+
return attn_output, attn_weights
|
| 141 |
+
|
| 142 |
+
|
| 143 |
+
class BertSelfAttention(nn.Module):
|
| 144 |
+
def __init__(self, config, is_causal=False, layer_idx=None):
|
| 145 |
+
super().__init__()
|
| 146 |
+
if config.hidden_size % config.num_attention_heads != 0 and not hasattr(config, "embedding_size"):
|
| 147 |
+
raise ValueError(
|
| 148 |
+
f"The hidden size ({config.hidden_size}) is not a multiple of the number of attention "
|
| 149 |
+
f"heads ({config.num_attention_heads})"
|
| 150 |
+
)
|
| 151 |
+
self.config = config
|
| 152 |
+
|
| 153 |
+
self.num_attention_heads = config.num_attention_heads
|
| 154 |
+
self.attention_head_size = int(config.hidden_size / config.num_attention_heads)
|
| 155 |
+
self.all_head_size = self.num_attention_heads * self.attention_head_size
|
| 156 |
+
self.scaling = self.attention_head_size**-0.5
|
| 157 |
+
|
| 158 |
+
self.query = nn.Linear(config.hidden_size, self.all_head_size)
|
| 159 |
+
self.key = nn.Linear(config.hidden_size, self.all_head_size)
|
| 160 |
+
self.value = nn.Linear(config.hidden_size, self.all_head_size)
|
| 161 |
+
|
| 162 |
+
self.dropout = nn.Dropout(config.attention_probs_dropout_prob)
|
| 163 |
+
|
| 164 |
+
self.is_decoder = config.is_decoder
|
| 165 |
+
self.is_causal = is_causal
|
| 166 |
+
self.layer_idx = layer_idx
|
| 167 |
+
|
| 168 |
+
def forward(
|
| 169 |
+
self,
|
| 170 |
+
hidden_states: torch.Tensor,
|
| 171 |
+
attention_mask: torch.FloatTensor | None = None,
|
| 172 |
+
past_key_values: Cache | None = None,
|
| 173 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 174 |
+
) -> tuple[torch.Tensor]:
|
| 175 |
+
input_shape = hidden_states.shape[:-1]
|
| 176 |
+
hidden_shape = (*input_shape, -1, self.attention_head_size)
|
| 177 |
+
|
| 178 |
+
# get all proj
|
| 179 |
+
query_layer = self.query(hidden_states).view(*hidden_shape).transpose(1, 2)
|
| 180 |
+
key_layer = self.key(hidden_states).view(*hidden_shape).transpose(1, 2)
|
| 181 |
+
value_layer = self.value(hidden_states).view(*hidden_shape).transpose(1, 2)
|
| 182 |
+
|
| 183 |
+
if past_key_values is not None:
|
| 184 |
+
# decoder-only bert can have a simple dynamic cache for example
|
| 185 |
+
current_past_key_values = past_key_values
|
| 186 |
+
if isinstance(past_key_values, EncoderDecoderCache):
|
| 187 |
+
current_past_key_values = past_key_values.self_attention_cache
|
| 188 |
+
|
| 189 |
+
# save all key/value_layer to cache to be re-used for fast auto-regressive generation
|
| 190 |
+
key_layer, value_layer = current_past_key_values.update(key_layer, value_layer, self.layer_idx)
|
| 191 |
+
|
| 192 |
+
attention_interface: Callable = ALL_ATTENTION_FUNCTIONS.get_interface(
|
| 193 |
+
self.config._attn_implementation, eager_attention_forward
|
| 194 |
+
)
|
| 195 |
+
|
| 196 |
+
attn_output, attn_weights = attention_interface(
|
| 197 |
+
self,
|
| 198 |
+
query_layer,
|
| 199 |
+
key_layer,
|
| 200 |
+
value_layer,
|
| 201 |
+
attention_mask,
|
| 202 |
+
dropout=0.0 if not self.training else self.dropout.p,
|
| 203 |
+
scaling=self.scaling,
|
| 204 |
+
**kwargs,
|
| 205 |
+
)
|
| 206 |
+
attn_output = attn_output.reshape(*input_shape, -1).contiguous()
|
| 207 |
+
return attn_output, attn_weights
|
| 208 |
+
|
| 209 |
+
|
| 210 |
+
class BertCrossAttention(nn.Module):
|
| 211 |
+
def __init__(self, config, is_causal=False, layer_idx=None):
|
| 212 |
+
super().__init__()
|
| 213 |
+
if config.hidden_size % config.num_attention_heads != 0 and not hasattr(config, "embedding_size"):
|
| 214 |
+
raise ValueError(
|
| 215 |
+
f"The hidden size ({config.hidden_size}) is not a multiple of the number of attention "
|
| 216 |
+
f"heads ({config.num_attention_heads})"
|
| 217 |
+
)
|
| 218 |
+
self.config = config
|
| 219 |
+
|
| 220 |
+
self.num_attention_heads = config.num_attention_heads
|
| 221 |
+
self.attention_head_size = int(config.hidden_size / config.num_attention_heads)
|
| 222 |
+
self.all_head_size = self.num_attention_heads * self.attention_head_size
|
| 223 |
+
self.scaling = self.attention_head_size**-0.5
|
| 224 |
+
|
| 225 |
+
self.query = nn.Linear(config.hidden_size, self.all_head_size)
|
| 226 |
+
self.key = nn.Linear(config.hidden_size, self.all_head_size)
|
| 227 |
+
self.value = nn.Linear(config.hidden_size, self.all_head_size)
|
| 228 |
+
|
| 229 |
+
self.dropout = nn.Dropout(config.attention_probs_dropout_prob)
|
| 230 |
+
|
| 231 |
+
self.is_causal = is_causal
|
| 232 |
+
self.layer_idx = layer_idx
|
| 233 |
+
|
| 234 |
+
def forward(
|
| 235 |
+
self,
|
| 236 |
+
hidden_states: torch.Tensor,
|
| 237 |
+
encoder_hidden_states: torch.FloatTensor | None = None,
|
| 238 |
+
attention_mask: torch.FloatTensor | None = None,
|
| 239 |
+
past_key_values: EncoderDecoderCache | None = None,
|
| 240 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 241 |
+
) -> tuple[torch.Tensor]:
|
| 242 |
+
# determine input shapes
|
| 243 |
+
input_shape = hidden_states.shape[:-1]
|
| 244 |
+
|
| 245 |
+
hidden_shape = (*input_shape, -1, self.attention_head_size)
|
| 246 |
+
|
| 247 |
+
# get query proj
|
| 248 |
+
query_layer = self.query(hidden_states).view(hidden_shape).transpose(1, 2)
|
| 249 |
+
|
| 250 |
+
is_updated = past_key_values.is_updated.get(self.layer_idx) if past_key_values is not None else False
|
| 251 |
+
if past_key_values is not None and is_updated:
|
| 252 |
+
# reuse k,v, cross_attentions
|
| 253 |
+
key_layer = past_key_values.cross_attention_cache.layers[self.layer_idx].keys
|
| 254 |
+
value_layer = past_key_values.cross_attention_cache.layers[self.layer_idx].values
|
| 255 |
+
else:
|
| 256 |
+
kv_shape = (*encoder_hidden_states.shape[:-1], -1, self.attention_head_size)
|
| 257 |
+
key_layer = self.key(encoder_hidden_states).view(kv_shape).transpose(1, 2)
|
| 258 |
+
value_layer = self.value(encoder_hidden_states).view(kv_shape).transpose(1, 2)
|
| 259 |
+
|
| 260 |
+
if past_key_values is not None:
|
| 261 |
+
# save all states to the cache
|
| 262 |
+
key_layer, value_layer = past_key_values.cross_attention_cache.update(
|
| 263 |
+
key_layer, value_layer, self.layer_idx
|
| 264 |
+
)
|
| 265 |
+
# set flag that curr layer for cross-attn is already updated so we can re-use in subsequent calls
|
| 266 |
+
past_key_values.is_updated[self.layer_idx] = True
|
| 267 |
+
|
| 268 |
+
attention_interface: Callable = ALL_ATTENTION_FUNCTIONS.get_interface(
|
| 269 |
+
self.config._attn_implementation, eager_attention_forward
|
| 270 |
+
)
|
| 271 |
+
|
| 272 |
+
attn_output, attn_weights = attention_interface(
|
| 273 |
+
self,
|
| 274 |
+
query_layer,
|
| 275 |
+
key_layer,
|
| 276 |
+
value_layer,
|
| 277 |
+
attention_mask,
|
| 278 |
+
dropout=0.0 if not self.training else self.dropout.p,
|
| 279 |
+
scaling=self.scaling,
|
| 280 |
+
**kwargs,
|
| 281 |
+
)
|
| 282 |
+
attn_output = attn_output.reshape(*input_shape, -1).contiguous()
|
| 283 |
+
return attn_output, attn_weights
|
| 284 |
+
|
| 285 |
+
|
| 286 |
+
class BertSelfOutput(nn.Module):
|
| 287 |
+
def __init__(self, config):
|
| 288 |
+
super().__init__()
|
| 289 |
+
self.dense = nn.Linear(config.hidden_size, config.hidden_size)
|
| 290 |
+
self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps)
|
| 291 |
+
self.dropout = nn.Dropout(config.hidden_dropout_prob)
|
| 292 |
+
|
| 293 |
+
def forward(self, hidden_states: torch.Tensor, input_tensor: torch.Tensor) -> torch.Tensor:
|
| 294 |
+
hidden_states = self.dense(hidden_states)
|
| 295 |
+
hidden_states = self.dropout(hidden_states)
|
| 296 |
+
hidden_states = self.LayerNorm(hidden_states + input_tensor)
|
| 297 |
+
return hidden_states
|
| 298 |
+
|
| 299 |
+
|
| 300 |
+
class BertAttention(nn.Module):
|
| 301 |
+
def __init__(self, config, is_causal=False, layer_idx=None, is_cross_attention=False):
|
| 302 |
+
super().__init__()
|
| 303 |
+
self.is_cross_attention = is_cross_attention
|
| 304 |
+
attention_class = BertCrossAttention if is_cross_attention else BertSelfAttention
|
| 305 |
+
self.self = attention_class(config, is_causal=is_causal, layer_idx=layer_idx)
|
| 306 |
+
self.output = BertSelfOutput(config)
|
| 307 |
+
|
| 308 |
+
def forward(
|
| 309 |
+
self,
|
| 310 |
+
hidden_states: torch.Tensor,
|
| 311 |
+
attention_mask: torch.FloatTensor | None = None,
|
| 312 |
+
encoder_hidden_states: torch.FloatTensor | None = None,
|
| 313 |
+
encoder_attention_mask: torch.FloatTensor | None = None,
|
| 314 |
+
past_key_values: Cache | None = None,
|
| 315 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 316 |
+
) -> tuple[torch.Tensor]:
|
| 317 |
+
attention_mask = attention_mask if not self.is_cross_attention else encoder_attention_mask
|
| 318 |
+
attention_output, attn_weights = self.self(
|
| 319 |
+
hidden_states,
|
| 320 |
+
encoder_hidden_states=encoder_hidden_states,
|
| 321 |
+
attention_mask=attention_mask,
|
| 322 |
+
past_key_values=past_key_values,
|
| 323 |
+
**kwargs,
|
| 324 |
+
)
|
| 325 |
+
attention_output = self.output(attention_output, hidden_states)
|
| 326 |
+
return attention_output, attn_weights
|
| 327 |
+
|
| 328 |
+
|
| 329 |
+
class BertIntermediate(nn.Module):
|
| 330 |
+
def __init__(self, config):
|
| 331 |
+
super().__init__()
|
| 332 |
+
self.dense = nn.Linear(config.hidden_size, config.intermediate_size)
|
| 333 |
+
if isinstance(config.hidden_act, str):
|
| 334 |
+
self.intermediate_act_fn = ACT2FN[config.hidden_act]
|
| 335 |
+
else:
|
| 336 |
+
self.intermediate_act_fn = config.hidden_act
|
| 337 |
+
|
| 338 |
+
def forward(self, hidden_states: torch.Tensor) -> torch.Tensor:
|
| 339 |
+
hidden_states = self.dense(hidden_states)
|
| 340 |
+
hidden_states = self.intermediate_act_fn(hidden_states)
|
| 341 |
+
return hidden_states
|
| 342 |
+
|
| 343 |
+
|
| 344 |
+
class BertOutput(nn.Module):
|
| 345 |
+
def __init__(self, config):
|
| 346 |
+
super().__init__()
|
| 347 |
+
self.dense = nn.Linear(config.intermediate_size, config.hidden_size)
|
| 348 |
+
self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps)
|
| 349 |
+
self.dropout = nn.Dropout(config.hidden_dropout_prob)
|
| 350 |
+
|
| 351 |
+
def forward(self, hidden_states: torch.Tensor, input_tensor: torch.Tensor) -> torch.Tensor:
|
| 352 |
+
hidden_states = self.dense(hidden_states)
|
| 353 |
+
hidden_states = self.dropout(hidden_states)
|
| 354 |
+
hidden_states = self.LayerNorm(hidden_states + input_tensor)
|
| 355 |
+
return hidden_states
|
| 356 |
+
|
| 357 |
+
|
| 358 |
+
class BertLayer(GradientCheckpointingLayer):
|
| 359 |
+
def __init__(self, config, layer_idx=None):
|
| 360 |
+
super().__init__()
|
| 361 |
+
self.chunk_size_feed_forward = config.chunk_size_feed_forward
|
| 362 |
+
self.seq_len_dim = 1
|
| 363 |
+
self.attention = BertAttention(config, is_causal=config.is_decoder, layer_idx=layer_idx)
|
| 364 |
+
self.is_decoder = config.is_decoder
|
| 365 |
+
self.add_cross_attention = config.add_cross_attention
|
| 366 |
+
if self.add_cross_attention:
|
| 367 |
+
if not self.is_decoder:
|
| 368 |
+
raise ValueError(f"{self} should be used as a decoder model if cross attention is added")
|
| 369 |
+
self.crossattention = BertAttention(
|
| 370 |
+
config,
|
| 371 |
+
is_causal=False,
|
| 372 |
+
layer_idx=layer_idx,
|
| 373 |
+
is_cross_attention=True,
|
| 374 |
+
)
|
| 375 |
+
self.intermediate = BertIntermediate(config)
|
| 376 |
+
self.output = BertOutput(config)
|
| 377 |
+
|
| 378 |
+
def forward(
|
| 379 |
+
self,
|
| 380 |
+
hidden_states: torch.Tensor,
|
| 381 |
+
attention_mask: torch.FloatTensor | None = None,
|
| 382 |
+
encoder_hidden_states: torch.FloatTensor | None = None,
|
| 383 |
+
encoder_attention_mask: torch.FloatTensor | None = None,
|
| 384 |
+
past_key_values: Cache | None = None,
|
| 385 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 386 |
+
) -> torch.Tensor:
|
| 387 |
+
self_attention_output, _ = self.attention(
|
| 388 |
+
hidden_states,
|
| 389 |
+
attention_mask,
|
| 390 |
+
past_key_values=past_key_values,
|
| 391 |
+
**kwargs,
|
| 392 |
+
)
|
| 393 |
+
attention_output = self_attention_output
|
| 394 |
+
|
| 395 |
+
if self.is_decoder and encoder_hidden_states is not None:
|
| 396 |
+
if not hasattr(self, "crossattention"):
|
| 397 |
+
raise ValueError(
|
| 398 |
+
f"If `encoder_hidden_states` are passed, {self} has to be instantiated with cross-attention layers"
|
| 399 |
+
" by setting `config.add_cross_attention=True`"
|
| 400 |
+
)
|
| 401 |
+
|
| 402 |
+
cross_attention_output, _ = self.crossattention(
|
| 403 |
+
self_attention_output,
|
| 404 |
+
None, # attention_mask
|
| 405 |
+
encoder_hidden_states,
|
| 406 |
+
encoder_attention_mask,
|
| 407 |
+
past_key_values=past_key_values,
|
| 408 |
+
**kwargs,
|
| 409 |
+
)
|
| 410 |
+
attention_output = cross_attention_output
|
| 411 |
+
|
| 412 |
+
layer_output = apply_chunking_to_forward(
|
| 413 |
+
self.feed_forward_chunk, self.chunk_size_feed_forward, self.seq_len_dim, attention_output
|
| 414 |
+
)
|
| 415 |
+
return layer_output
|
| 416 |
+
|
| 417 |
+
def feed_forward_chunk(self, attention_output):
|
| 418 |
+
intermediate_output = self.intermediate(attention_output)
|
| 419 |
+
layer_output = self.output(intermediate_output, attention_output)
|
| 420 |
+
return layer_output
|
| 421 |
+
|
| 422 |
+
|
| 423 |
+
class BertEncoder(nn.Module):
|
| 424 |
+
def __init__(self, config):
|
| 425 |
+
super().__init__()
|
| 426 |
+
self.config = config
|
| 427 |
+
self.layer = nn.ModuleList([BertLayer(config, layer_idx=i) for i in range(config.num_hidden_layers)])
|
| 428 |
+
|
| 429 |
+
def forward(
|
| 430 |
+
self,
|
| 431 |
+
hidden_states: torch.Tensor,
|
| 432 |
+
attention_mask: torch.FloatTensor | None = None,
|
| 433 |
+
encoder_hidden_states: torch.FloatTensor | None = None,
|
| 434 |
+
encoder_attention_mask: torch.FloatTensor | None = None,
|
| 435 |
+
past_key_values: Cache | None = None,
|
| 436 |
+
use_cache: bool | None = None,
|
| 437 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 438 |
+
) -> tuple[torch.Tensor] | BaseModelOutputWithPastAndCrossAttentions:
|
| 439 |
+
for i, layer_module in enumerate(self.layer):
|
| 440 |
+
hidden_states = layer_module(
|
| 441 |
+
hidden_states,
|
| 442 |
+
attention_mask,
|
| 443 |
+
encoder_hidden_states, # as a positional argument for gradient checkpointing
|
| 444 |
+
encoder_attention_mask=encoder_attention_mask,
|
| 445 |
+
past_key_values=past_key_values,
|
| 446 |
+
**kwargs,
|
| 447 |
+
)
|
| 448 |
+
|
| 449 |
+
return BaseModelOutputWithPastAndCrossAttentions(
|
| 450 |
+
last_hidden_state=hidden_states,
|
| 451 |
+
past_key_values=past_key_values if use_cache else None,
|
| 452 |
+
)
|
| 453 |
+
|
| 454 |
+
|
| 455 |
+
class BertPooler(nn.Module):
|
| 456 |
+
def __init__(self, config):
|
| 457 |
+
super().__init__()
|
| 458 |
+
self.dense = nn.Linear(config.hidden_size, config.hidden_size)
|
| 459 |
+
self.activation = nn.Tanh()
|
| 460 |
+
|
| 461 |
+
def forward(self, hidden_states: torch.Tensor) -> torch.Tensor:
|
| 462 |
+
# We "pool" the model by simply taking the hidden state corresponding
|
| 463 |
+
# to the first token.
|
| 464 |
+
first_token_tensor = hidden_states[:, 0]
|
| 465 |
+
pooled_output = self.dense(first_token_tensor)
|
| 466 |
+
pooled_output = self.activation(pooled_output)
|
| 467 |
+
return pooled_output
|
| 468 |
+
|
| 469 |
+
|
| 470 |
+
class BertPredictionHeadTransform(nn.Module):
|
| 471 |
+
def __init__(self, config):
|
| 472 |
+
super().__init__()
|
| 473 |
+
self.dense = nn.Linear(config.hidden_size, config.hidden_size)
|
| 474 |
+
if isinstance(config.hidden_act, str):
|
| 475 |
+
self.transform_act_fn = ACT2FN[config.hidden_act]
|
| 476 |
+
else:
|
| 477 |
+
self.transform_act_fn = config.hidden_act
|
| 478 |
+
self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps)
|
| 479 |
+
|
| 480 |
+
def forward(self, hidden_states: torch.Tensor) -> torch.Tensor:
|
| 481 |
+
hidden_states = self.dense(hidden_states)
|
| 482 |
+
hidden_states = self.transform_act_fn(hidden_states)
|
| 483 |
+
hidden_states = self.LayerNorm(hidden_states)
|
| 484 |
+
return hidden_states
|
| 485 |
+
|
| 486 |
+
|
| 487 |
+
class BertLMPredictionHead(nn.Module):
|
| 488 |
+
def __init__(self, config):
|
| 489 |
+
super().__init__()
|
| 490 |
+
self.transform = BertPredictionHeadTransform(config)
|
| 491 |
+
|
| 492 |
+
# The output weights are the same as the input embeddings, but there is
|
| 493 |
+
# an output-only bias for each token.
|
| 494 |
+
self.decoder = nn.Linear(config.hidden_size, config.vocab_size, bias=True)
|
| 495 |
+
self.bias = nn.Parameter(torch.zeros(config.vocab_size))
|
| 496 |
+
|
| 497 |
+
def forward(self, hidden_states):
|
| 498 |
+
hidden_states = self.transform(hidden_states)
|
| 499 |
+
hidden_states = self.decoder(hidden_states)
|
| 500 |
+
return hidden_states
|
| 501 |
+
|
| 502 |
+
|
| 503 |
+
class BertOnlyMLMHead(nn.Module):
|
| 504 |
+
def __init__(self, config):
|
| 505 |
+
super().__init__()
|
| 506 |
+
self.predictions = BertLMPredictionHead(config)
|
| 507 |
+
|
| 508 |
+
def forward(self, sequence_output: torch.Tensor) -> torch.Tensor:
|
| 509 |
+
prediction_scores = self.predictions(sequence_output)
|
| 510 |
+
return prediction_scores
|
| 511 |
+
|
| 512 |
+
|
| 513 |
+
class BertOnlyNSPHead(nn.Module):
|
| 514 |
+
def __init__(self, config):
|
| 515 |
+
super().__init__()
|
| 516 |
+
self.seq_relationship = nn.Linear(config.hidden_size, 2)
|
| 517 |
+
|
| 518 |
+
def forward(self, pooled_output):
|
| 519 |
+
seq_relationship_score = self.seq_relationship(pooled_output)
|
| 520 |
+
return seq_relationship_score
|
| 521 |
+
|
| 522 |
+
|
| 523 |
+
class BertPreTrainingHeads(nn.Module):
|
| 524 |
+
def __init__(self, config):
|
| 525 |
+
super().__init__()
|
| 526 |
+
self.predictions = BertLMPredictionHead(config)
|
| 527 |
+
self.seq_relationship = nn.Linear(config.hidden_size, 2)
|
| 528 |
+
|
| 529 |
+
def forward(self, sequence_output, pooled_output):
|
| 530 |
+
prediction_scores = self.predictions(sequence_output)
|
| 531 |
+
seq_relationship_score = self.seq_relationship(pooled_output)
|
| 532 |
+
return prediction_scores, seq_relationship_score
|
| 533 |
+
|
| 534 |
+
|
| 535 |
+
@auto_docstring
|
| 536 |
+
class BertPreTrainedModel(PreTrainedModel):
|
| 537 |
+
config_class = BertConfig
|
| 538 |
+
base_model_prefix = "bert"
|
| 539 |
+
supports_gradient_checkpointing = True
|
| 540 |
+
_supports_flash_attn = True
|
| 541 |
+
_supports_sdpa = True
|
| 542 |
+
_supports_flex_attn = True
|
| 543 |
+
_supports_attention_backend = True
|
| 544 |
+
_can_record_outputs = {
|
| 545 |
+
"hidden_states": BertLayer,
|
| 546 |
+
"attentions": BertSelfAttention,
|
| 547 |
+
"cross_attentions": BertCrossAttention,
|
| 548 |
+
}
|
| 549 |
+
|
| 550 |
+
@torch.no_grad()
|
| 551 |
+
def _init_weights(self, module):
|
| 552 |
+
"""Initialize the weights"""
|
| 553 |
+
super()._init_weights(module)
|
| 554 |
+
if isinstance(module, BertLMPredictionHead):
|
| 555 |
+
init.zeros_(module.bias)
|
| 556 |
+
elif isinstance(module, BertEmbeddings):
|
| 557 |
+
init.copy_(module.position_ids, torch.arange(module.position_ids.shape[-1]).expand((1, -1)))
|
| 558 |
+
init.zeros_(module.token_type_ids)
|
| 559 |
+
|
| 560 |
+
|
| 561 |
+
@auto_docstring(
|
| 562 |
+
custom_intro="""
|
| 563 |
+
Output type of [`BertForPreTraining`].
|
| 564 |
+
"""
|
| 565 |
+
)
|
| 566 |
+
@dataclass
|
| 567 |
+
class BertForPreTrainingOutput(ModelOutput):
|
| 568 |
+
r"""
|
| 569 |
+
loss (*optional*, returned when `labels` is provided, `torch.FloatTensor` of shape `(1,)`):
|
| 570 |
+
Total loss as the sum of the masked language modeling loss and the next sequence prediction
|
| 571 |
+
(classification) loss.
|
| 572 |
+
prediction_logits (`torch.FloatTensor` of shape `(batch_size, sequence_length, config.vocab_size)`):
|
| 573 |
+
Prediction scores of the language modeling head (scores for each vocabulary token before SoftMax).
|
| 574 |
+
seq_relationship_logits (`torch.FloatTensor` of shape `(batch_size, 2)`):
|
| 575 |
+
Prediction scores of the next sequence prediction (classification) head (scores of True/False continuation
|
| 576 |
+
before SoftMax).
|
| 577 |
+
"""
|
| 578 |
+
|
| 579 |
+
loss: torch.FloatTensor | None = None
|
| 580 |
+
prediction_logits: torch.FloatTensor | None = None
|
| 581 |
+
seq_relationship_logits: torch.FloatTensor | None = None
|
| 582 |
+
hidden_states: tuple[torch.FloatTensor] | None = None
|
| 583 |
+
attentions: tuple[torch.FloatTensor] | None = None
|
| 584 |
+
|
| 585 |
+
|
| 586 |
+
@auto_docstring(
|
| 587 |
+
custom_intro="""
|
| 588 |
+
The model can behave as an encoder (with only self-attention) as well as a decoder, in which case a layer of
|
| 589 |
+
cross-attention is added between the self-attention layers, following the architecture described in [Attention is
|
| 590 |
+
all you need](https://huggingface.co/papers/1706.03762) by Ashish Vaswani, Noam Shazeer, Niki Parmar, Jakob Uszkoreit,
|
| 591 |
+
Llion Jones, Aidan N. Gomez, Lukasz Kaiser and Illia Polosukhin.
|
| 592 |
+
|
| 593 |
+
To behave as an decoder the model needs to be initialized with the `is_decoder` argument of the configuration set
|
| 594 |
+
to `True`. To be used in a Seq2Seq model, the model needs to initialized with both `is_decoder` argument and
|
| 595 |
+
`add_cross_attention` set to `True`; an `encoder_hidden_states` is then expected as an input to the forward pass.
|
| 596 |
+
"""
|
| 597 |
+
)
|
| 598 |
+
class BertModel(BertPreTrainedModel):
|
| 599 |
+
_no_split_modules = ["BertEmbeddings", "BertLayer"]
|
| 600 |
+
|
| 601 |
+
def __init__(self, config, add_pooling_layer=True):
|
| 602 |
+
r"""
|
| 603 |
+
add_pooling_layer (bool, *optional*, defaults to `True`):
|
| 604 |
+
Whether to add a pooling layer
|
| 605 |
+
"""
|
| 606 |
+
super().__init__(config)
|
| 607 |
+
self.config = config
|
| 608 |
+
self.gradient_checkpointing = False
|
| 609 |
+
|
| 610 |
+
self.embeddings = BertEmbeddings(config)
|
| 611 |
+
self.encoder = BertEncoder(config)
|
| 612 |
+
|
| 613 |
+
self.pooler = BertPooler(config) if add_pooling_layer else None
|
| 614 |
+
|
| 615 |
+
# Initialize weights and apply final processing
|
| 616 |
+
self.post_init()
|
| 617 |
+
|
| 618 |
+
def get_input_embeddings(self):
|
| 619 |
+
return self.embeddings.word_embeddings
|
| 620 |
+
|
| 621 |
+
def set_input_embeddings(self, value):
|
| 622 |
+
self.embeddings.word_embeddings = value
|
| 623 |
+
|
| 624 |
+
@merge_with_config_defaults
|
| 625 |
+
@capture_outputs
|
| 626 |
+
@auto_docstring
|
| 627 |
+
def forward(
|
| 628 |
+
self,
|
| 629 |
+
input_ids: torch.Tensor | None = None,
|
| 630 |
+
attention_mask: torch.Tensor | None = None,
|
| 631 |
+
token_type_ids: torch.Tensor | None = None,
|
| 632 |
+
position_ids: torch.Tensor | None = None,
|
| 633 |
+
inputs_embeds: torch.Tensor | None = None,
|
| 634 |
+
encoder_hidden_states: torch.Tensor | None = None,
|
| 635 |
+
encoder_attention_mask: torch.Tensor | None = None,
|
| 636 |
+
past_key_values: Cache | None = None,
|
| 637 |
+
use_cache: bool | None = None,
|
| 638 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 639 |
+
) -> tuple[torch.Tensor] | BaseModelOutputWithPoolingAndCrossAttentions:
|
| 640 |
+
if (input_ids is None) ^ (inputs_embeds is not None):
|
| 641 |
+
raise ValueError("You must specify exactly one of input_ids or inputs_embeds")
|
| 642 |
+
|
| 643 |
+
if self.config.is_decoder:
|
| 644 |
+
use_cache = use_cache if use_cache is not None else self.config.use_cache
|
| 645 |
+
else:
|
| 646 |
+
use_cache = False
|
| 647 |
+
|
| 648 |
+
if use_cache and past_key_values is None:
|
| 649 |
+
past_key_values = (
|
| 650 |
+
EncoderDecoderCache(DynamicCache(config=self.config), DynamicCache(config=self.config))
|
| 651 |
+
if encoder_hidden_states is not None or self.config.is_encoder_decoder
|
| 652 |
+
else DynamicCache(config=self.config)
|
| 653 |
+
)
|
| 654 |
+
|
| 655 |
+
past_key_values_length = past_key_values.get_seq_length() if past_key_values is not None else 0
|
| 656 |
+
|
| 657 |
+
embedding_output = self.embeddings(
|
| 658 |
+
input_ids=input_ids,
|
| 659 |
+
position_ids=position_ids,
|
| 660 |
+
token_type_ids=token_type_ids,
|
| 661 |
+
inputs_embeds=inputs_embeds,
|
| 662 |
+
past_key_values_length=past_key_values_length,
|
| 663 |
+
)
|
| 664 |
+
|
| 665 |
+
attention_mask, encoder_attention_mask = self._create_attention_masks(
|
| 666 |
+
attention_mask=attention_mask,
|
| 667 |
+
encoder_attention_mask=encoder_attention_mask,
|
| 668 |
+
embedding_output=embedding_output,
|
| 669 |
+
encoder_hidden_states=encoder_hidden_states,
|
| 670 |
+
past_key_values=past_key_values,
|
| 671 |
+
)
|
| 672 |
+
|
| 673 |
+
encoder_outputs = self.encoder(
|
| 674 |
+
embedding_output,
|
| 675 |
+
attention_mask=attention_mask,
|
| 676 |
+
encoder_hidden_states=encoder_hidden_states,
|
| 677 |
+
encoder_attention_mask=encoder_attention_mask,
|
| 678 |
+
past_key_values=past_key_values,
|
| 679 |
+
use_cache=use_cache,
|
| 680 |
+
position_ids=position_ids,
|
| 681 |
+
**kwargs,
|
| 682 |
+
)
|
| 683 |
+
sequence_output = encoder_outputs.last_hidden_state
|
| 684 |
+
pooled_output = self.pooler(sequence_output) if self.pooler is not None else None
|
| 685 |
+
|
| 686 |
+
return BaseModelOutputWithPoolingAndCrossAttentions(
|
| 687 |
+
last_hidden_state=sequence_output,
|
| 688 |
+
pooler_output=pooled_output,
|
| 689 |
+
past_key_values=encoder_outputs.past_key_values,
|
| 690 |
+
)
|
| 691 |
+
|
| 692 |
+
def _create_attention_masks(
|
| 693 |
+
self,
|
| 694 |
+
attention_mask,
|
| 695 |
+
encoder_attention_mask,
|
| 696 |
+
embedding_output,
|
| 697 |
+
encoder_hidden_states,
|
| 698 |
+
past_key_values,
|
| 699 |
+
):
|
| 700 |
+
if self.config.is_decoder:
|
| 701 |
+
attention_mask = create_causal_mask(
|
| 702 |
+
config=self.config,
|
| 703 |
+
inputs_embeds=embedding_output,
|
| 704 |
+
attention_mask=attention_mask,
|
| 705 |
+
past_key_values=past_key_values,
|
| 706 |
+
)
|
| 707 |
+
else:
|
| 708 |
+
attention_mask = create_bidirectional_mask(
|
| 709 |
+
config=self.config,
|
| 710 |
+
inputs_embeds=embedding_output,
|
| 711 |
+
attention_mask=attention_mask,
|
| 712 |
+
)
|
| 713 |
+
|
| 714 |
+
if encoder_attention_mask is not None:
|
| 715 |
+
encoder_attention_mask = create_bidirectional_mask(
|
| 716 |
+
config=self.config,
|
| 717 |
+
inputs_embeds=embedding_output,
|
| 718 |
+
attention_mask=encoder_attention_mask,
|
| 719 |
+
encoder_hidden_states=encoder_hidden_states,
|
| 720 |
+
)
|
| 721 |
+
|
| 722 |
+
return attention_mask, encoder_attention_mask
|
| 723 |
+
|
| 724 |
+
|
| 725 |
+
@auto_docstring(
|
| 726 |
+
custom_intro="""
|
| 727 |
+
Bert Model with two heads on top as done during the pretraining: a `masked language modeling` head and a `next
|
| 728 |
+
sentence prediction (classification)` head.
|
| 729 |
+
"""
|
| 730 |
+
)
|
| 731 |
+
class BertForPreTraining(BertPreTrainedModel):
|
| 732 |
+
_tied_weights_keys = {
|
| 733 |
+
"cls.predictions.decoder.weight": "bert.embeddings.word_embeddings.weight",
|
| 734 |
+
"cls.predictions.decoder.bias": "cls.predictions.bias",
|
| 735 |
+
}
|
| 736 |
+
|
| 737 |
+
def __init__(self, config):
|
| 738 |
+
super().__init__(config)
|
| 739 |
+
|
| 740 |
+
self.bert = BertModel(config)
|
| 741 |
+
self.cls = BertPreTrainingHeads(config)
|
| 742 |
+
|
| 743 |
+
# Initialize weights and apply final processing
|
| 744 |
+
self.post_init()
|
| 745 |
+
|
| 746 |
+
def get_output_embeddings(self):
|
| 747 |
+
return self.cls.predictions.decoder
|
| 748 |
+
|
| 749 |
+
def set_output_embeddings(self, new_embeddings):
|
| 750 |
+
self.cls.predictions.decoder = new_embeddings
|
| 751 |
+
self.cls.predictions.bias = new_embeddings.bias
|
| 752 |
+
|
| 753 |
+
@can_return_tuple
|
| 754 |
+
@auto_docstring
|
| 755 |
+
def forward(
|
| 756 |
+
self,
|
| 757 |
+
input_ids: torch.Tensor | None = None,
|
| 758 |
+
attention_mask: torch.Tensor | None = None,
|
| 759 |
+
token_type_ids: torch.Tensor | None = None,
|
| 760 |
+
position_ids: torch.Tensor | None = None,
|
| 761 |
+
inputs_embeds: torch.Tensor | None = None,
|
| 762 |
+
labels: torch.Tensor | None = None,
|
| 763 |
+
next_sentence_label: torch.Tensor | None = None,
|
| 764 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 765 |
+
) -> tuple[torch.Tensor] | BertForPreTrainingOutput:
|
| 766 |
+
r"""
|
| 767 |
+
labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):
|
| 768 |
+
Labels for computing the masked language modeling loss. Indices should be in `[-100, 0, ...,
|
| 769 |
+
config.vocab_size]` (see `input_ids` docstring) Tokens with indices set to `-100` are ignored (masked),
|
| 770 |
+
the loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]`
|
| 771 |
+
next_sentence_label (`torch.LongTensor` of shape `(batch_size,)`, *optional*):
|
| 772 |
+
Labels for computing the next sequence prediction (classification) loss. Input should be a sequence
|
| 773 |
+
pair (see `input_ids` docstring) Indices should be in `[0, 1]`:
|
| 774 |
+
|
| 775 |
+
- 0 indicates sequence B is a continuation of sequence A,
|
| 776 |
+
- 1 indicates sequence B is a random sequence.
|
| 777 |
+
|
| 778 |
+
Example:
|
| 779 |
+
|
| 780 |
+
```python
|
| 781 |
+
>>> from transformers import AutoTokenizer, BertForPreTraining
|
| 782 |
+
>>> import torch
|
| 783 |
+
|
| 784 |
+
>>> tokenizer = AutoTokenizer.from_pretrained("google-bert/bert-base-uncased")
|
| 785 |
+
>>> model = BertForPreTraining.from_pretrained("google-bert/bert-base-uncased")
|
| 786 |
+
|
| 787 |
+
>>> inputs = tokenizer("Hello, my dog is cute", return_tensors="pt")
|
| 788 |
+
>>> outputs = model(**inputs)
|
| 789 |
+
|
| 790 |
+
>>> prediction_logits = outputs.prediction_logits
|
| 791 |
+
>>> seq_relationship_logits = outputs.seq_relationship_logits
|
| 792 |
+
```
|
| 793 |
+
"""
|
| 794 |
+
outputs = self.bert(
|
| 795 |
+
input_ids,
|
| 796 |
+
attention_mask=attention_mask,
|
| 797 |
+
token_type_ids=token_type_ids,
|
| 798 |
+
position_ids=position_ids,
|
| 799 |
+
inputs_embeds=inputs_embeds,
|
| 800 |
+
return_dict=True,
|
| 801 |
+
**kwargs,
|
| 802 |
+
)
|
| 803 |
+
|
| 804 |
+
sequence_output, pooled_output = outputs[:2]
|
| 805 |
+
prediction_scores, seq_relationship_score = self.cls(sequence_output, pooled_output)
|
| 806 |
+
|
| 807 |
+
total_loss = None
|
| 808 |
+
if labels is not None and next_sentence_label is not None:
|
| 809 |
+
loss_fct = CrossEntropyLoss()
|
| 810 |
+
masked_lm_loss = loss_fct(prediction_scores.view(-1, self.config.vocab_size), labels.view(-1))
|
| 811 |
+
next_sentence_loss = loss_fct(seq_relationship_score.view(-1, 2), next_sentence_label.view(-1))
|
| 812 |
+
total_loss = masked_lm_loss + next_sentence_loss
|
| 813 |
+
|
| 814 |
+
return BertForPreTrainingOutput(
|
| 815 |
+
loss=total_loss,
|
| 816 |
+
prediction_logits=prediction_scores,
|
| 817 |
+
seq_relationship_logits=seq_relationship_score,
|
| 818 |
+
hidden_states=outputs.hidden_states,
|
| 819 |
+
attentions=outputs.attentions,
|
| 820 |
+
)
|
| 821 |
+
|
| 822 |
+
|
| 823 |
+
@auto_docstring(
|
| 824 |
+
custom_intro="""
|
| 825 |
+
Bert Model with a `language modeling` head on top for CLM fine-tuning.
|
| 826 |
+
"""
|
| 827 |
+
)
|
| 828 |
+
class BertLMHeadModel(BertPreTrainedModel, GenerationMixin):
|
| 829 |
+
_tied_weights_keys = {
|
| 830 |
+
"cls.predictions.decoder.weight": "bert.embeddings.word_embeddings.weight",
|
| 831 |
+
"cls.predictions.decoder.bias": "cls.predictions.bias",
|
| 832 |
+
}
|
| 833 |
+
|
| 834 |
+
def __init__(self, config):
|
| 835 |
+
super().__init__(config)
|
| 836 |
+
|
| 837 |
+
if not config.is_decoder:
|
| 838 |
+
logger.warning("If you want to use `BertLMHeadModel` as a standalone, add `is_decoder=True.`")
|
| 839 |
+
|
| 840 |
+
self.bert = BertModel(config, add_pooling_layer=False)
|
| 841 |
+
self.cls = BertOnlyMLMHead(config)
|
| 842 |
+
|
| 843 |
+
# Initialize weights and apply final processing
|
| 844 |
+
self.post_init()
|
| 845 |
+
|
| 846 |
+
def get_output_embeddings(self):
|
| 847 |
+
return self.cls.predictions.decoder
|
| 848 |
+
|
| 849 |
+
def set_output_embeddings(self, new_embeddings):
|
| 850 |
+
self.cls.predictions.decoder = new_embeddings
|
| 851 |
+
self.cls.predictions.bias = new_embeddings.bias
|
| 852 |
+
|
| 853 |
+
@can_return_tuple
|
| 854 |
+
@auto_docstring
|
| 855 |
+
def forward(
|
| 856 |
+
self,
|
| 857 |
+
input_ids: torch.Tensor | None = None,
|
| 858 |
+
attention_mask: torch.Tensor | None = None,
|
| 859 |
+
token_type_ids: torch.Tensor | None = None,
|
| 860 |
+
position_ids: torch.Tensor | None = None,
|
| 861 |
+
inputs_embeds: torch.Tensor | None = None,
|
| 862 |
+
encoder_hidden_states: torch.Tensor | None = None,
|
| 863 |
+
encoder_attention_mask: torch.Tensor | None = None,
|
| 864 |
+
labels: torch.Tensor | None = None,
|
| 865 |
+
past_key_values: Cache | None = None,
|
| 866 |
+
use_cache: bool | None = None,
|
| 867 |
+
logits_to_keep: int | torch.Tensor = 0,
|
| 868 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 869 |
+
) -> tuple[torch.Tensor] | CausalLMOutputWithCrossAttentions:
|
| 870 |
+
r"""
|
| 871 |
+
labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):
|
| 872 |
+
Labels for computing the left-to-right language modeling loss (next word prediction). Indices should be in
|
| 873 |
+
`[-100, 0, ..., config.vocab_size]` (see `input_ids` docstring) Tokens with indices set to `-100` are
|
| 874 |
+
ignored (masked), the loss is only computed for the tokens with labels n `[0, ..., config.vocab_size]`
|
| 875 |
+
"""
|
| 876 |
+
if labels is not None:
|
| 877 |
+
use_cache = False
|
| 878 |
+
|
| 879 |
+
outputs: BaseModelOutputWithPoolingAndCrossAttentions = self.bert(
|
| 880 |
+
input_ids,
|
| 881 |
+
attention_mask=attention_mask,
|
| 882 |
+
token_type_ids=token_type_ids,
|
| 883 |
+
position_ids=position_ids,
|
| 884 |
+
inputs_embeds=inputs_embeds,
|
| 885 |
+
encoder_hidden_states=encoder_hidden_states,
|
| 886 |
+
encoder_attention_mask=encoder_attention_mask,
|
| 887 |
+
past_key_values=past_key_values,
|
| 888 |
+
use_cache=use_cache,
|
| 889 |
+
return_dict=True,
|
| 890 |
+
**kwargs,
|
| 891 |
+
)
|
| 892 |
+
|
| 893 |
+
hidden_states = outputs.last_hidden_state
|
| 894 |
+
# Only compute necessary logits, and do not upcast them to float if we are not computing the loss
|
| 895 |
+
slice_indices = slice(-logits_to_keep, None) if isinstance(logits_to_keep, int) else logits_to_keep
|
| 896 |
+
logits = self.cls(hidden_states[:, slice_indices, :])
|
| 897 |
+
|
| 898 |
+
loss = None
|
| 899 |
+
if labels is not None:
|
| 900 |
+
loss = self.loss_function(logits=logits, labels=labels, vocab_size=self.config.vocab_size, **kwargs)
|
| 901 |
+
|
| 902 |
+
return CausalLMOutputWithCrossAttentions(
|
| 903 |
+
loss=loss,
|
| 904 |
+
logits=logits,
|
| 905 |
+
past_key_values=outputs.past_key_values,
|
| 906 |
+
hidden_states=outputs.hidden_states,
|
| 907 |
+
attentions=outputs.attentions,
|
| 908 |
+
cross_attentions=outputs.cross_attentions,
|
| 909 |
+
)
|
| 910 |
+
|
| 911 |
+
|
| 912 |
+
@auto_docstring
|
| 913 |
+
class BertForMaskedLM(BertPreTrainedModel):
|
| 914 |
+
_tied_weights_keys = {
|
| 915 |
+
"cls.predictions.decoder.weight": "bert.embeddings.word_embeddings.weight",
|
| 916 |
+
"cls.predictions.decoder.bias": "cls.predictions.bias",
|
| 917 |
+
}
|
| 918 |
+
|
| 919 |
+
def __init__(self, config):
|
| 920 |
+
super().__init__(config)
|
| 921 |
+
|
| 922 |
+
if config.is_decoder:
|
| 923 |
+
logger.warning(
|
| 924 |
+
"If you want to use `BertForMaskedLM` make sure `config.is_decoder=False` for "
|
| 925 |
+
"bi-directional self-attention."
|
| 926 |
+
)
|
| 927 |
+
|
| 928 |
+
self.bert = BertModel(config, add_pooling_layer=False)
|
| 929 |
+
self.cls = BertOnlyMLMHead(config)
|
| 930 |
+
|
| 931 |
+
# Initialize weights and apply final processing
|
| 932 |
+
self.post_init()
|
| 933 |
+
|
| 934 |
+
def get_output_embeddings(self):
|
| 935 |
+
return self.cls.predictions.decoder
|
| 936 |
+
|
| 937 |
+
def set_output_embeddings(self, new_embeddings):
|
| 938 |
+
self.cls.predictions.decoder = new_embeddings
|
| 939 |
+
self.cls.predictions.bias = new_embeddings.bias
|
| 940 |
+
|
| 941 |
+
@can_return_tuple
|
| 942 |
+
@auto_docstring
|
| 943 |
+
def forward(
|
| 944 |
+
self,
|
| 945 |
+
input_ids: torch.Tensor | None = None,
|
| 946 |
+
attention_mask: torch.Tensor | None = None,
|
| 947 |
+
token_type_ids: torch.Tensor | None = None,
|
| 948 |
+
position_ids: torch.Tensor | None = None,
|
| 949 |
+
inputs_embeds: torch.Tensor | None = None,
|
| 950 |
+
encoder_hidden_states: torch.Tensor | None = None,
|
| 951 |
+
encoder_attention_mask: torch.Tensor | None = None,
|
| 952 |
+
labels: torch.Tensor | None = None,
|
| 953 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 954 |
+
) -> tuple[torch.Tensor] | MaskedLMOutput:
|
| 955 |
+
r"""
|
| 956 |
+
labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):
|
| 957 |
+
Labels for computing the masked language modeling loss. Indices should be in `[-100, 0, ...,
|
| 958 |
+
config.vocab_size]` (see `input_ids` docstring) Tokens with indices set to `-100` are ignored (masked), the
|
| 959 |
+
loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]`
|
| 960 |
+
"""
|
| 961 |
+
outputs = self.bert(
|
| 962 |
+
input_ids,
|
| 963 |
+
attention_mask=attention_mask,
|
| 964 |
+
token_type_ids=token_type_ids,
|
| 965 |
+
position_ids=position_ids,
|
| 966 |
+
inputs_embeds=inputs_embeds,
|
| 967 |
+
encoder_hidden_states=encoder_hidden_states,
|
| 968 |
+
encoder_attention_mask=encoder_attention_mask,
|
| 969 |
+
return_dict=True,
|
| 970 |
+
**kwargs,
|
| 971 |
+
)
|
| 972 |
+
|
| 973 |
+
sequence_output = outputs[0]
|
| 974 |
+
prediction_scores = self.cls(sequence_output)
|
| 975 |
+
|
| 976 |
+
masked_lm_loss = None
|
| 977 |
+
if labels is not None:
|
| 978 |
+
loss_fct = CrossEntropyLoss() # -100 index = padding token
|
| 979 |
+
masked_lm_loss = loss_fct(prediction_scores.view(-1, self.config.vocab_size), labels.view(-1))
|
| 980 |
+
|
| 981 |
+
return MaskedLMOutput(
|
| 982 |
+
loss=masked_lm_loss,
|
| 983 |
+
logits=prediction_scores,
|
| 984 |
+
hidden_states=outputs.hidden_states,
|
| 985 |
+
attentions=outputs.attentions,
|
| 986 |
+
)
|
| 987 |
+
|
| 988 |
+
|
| 989 |
+
@auto_docstring(
|
| 990 |
+
custom_intro="""
|
| 991 |
+
Bert Model with a `next sentence prediction (classification)` head on top.
|
| 992 |
+
"""
|
| 993 |
+
)
|
| 994 |
+
class BertForNextSentencePrediction(BertPreTrainedModel):
|
| 995 |
+
def __init__(self, config):
|
| 996 |
+
super().__init__(config)
|
| 997 |
+
|
| 998 |
+
self.bert = BertModel(config)
|
| 999 |
+
self.cls = BertOnlyNSPHead(config)
|
| 1000 |
+
|
| 1001 |
+
# Initialize weights and apply final processing
|
| 1002 |
+
self.post_init()
|
| 1003 |
+
|
| 1004 |
+
@can_return_tuple
|
| 1005 |
+
@auto_docstring
|
| 1006 |
+
def forward(
|
| 1007 |
+
self,
|
| 1008 |
+
input_ids: torch.Tensor | None = None,
|
| 1009 |
+
attention_mask: torch.Tensor | None = None,
|
| 1010 |
+
token_type_ids: torch.Tensor | None = None,
|
| 1011 |
+
position_ids: torch.Tensor | None = None,
|
| 1012 |
+
inputs_embeds: torch.Tensor | None = None,
|
| 1013 |
+
labels: torch.Tensor | None = None,
|
| 1014 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 1015 |
+
) -> tuple[torch.Tensor] | NextSentencePredictorOutput:
|
| 1016 |
+
r"""
|
| 1017 |
+
labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*):
|
| 1018 |
+
Labels for computing the next sequence prediction (classification) loss. Input should be a sequence pair
|
| 1019 |
+
(see `input_ids` docstring). Indices should be in `[0, 1]`:
|
| 1020 |
+
|
| 1021 |
+
- 0 indicates sequence B is a continuation of sequence A,
|
| 1022 |
+
- 1 indicates sequence B is a random sequence.
|
| 1023 |
+
|
| 1024 |
+
Example:
|
| 1025 |
+
|
| 1026 |
+
```python
|
| 1027 |
+
>>> from transformers import AutoTokenizer, BertForNextSentencePrediction
|
| 1028 |
+
>>> import torch
|
| 1029 |
+
|
| 1030 |
+
>>> tokenizer = AutoTokenizer.from_pretrained("google-bert/bert-base-uncased")
|
| 1031 |
+
>>> model = BertForNextSentencePrediction.from_pretrained("google-bert/bert-base-uncased")
|
| 1032 |
+
|
| 1033 |
+
>>> prompt = "In Italy, pizza served in formal settings, such as at a restaurant, is presented unsliced."
|
| 1034 |
+
>>> next_sentence = "The sky is blue due to the shorter wavelength of blue light."
|
| 1035 |
+
>>> encoding = tokenizer(prompt, next_sentence, return_tensors="pt")
|
| 1036 |
+
|
| 1037 |
+
>>> outputs = model(**encoding, labels=torch.LongTensor([1]))
|
| 1038 |
+
>>> logits = outputs.logits
|
| 1039 |
+
>>> assert logits[0, 0] < logits[0, 1] # next sentence was random
|
| 1040 |
+
```
|
| 1041 |
+
"""
|
| 1042 |
+
|
| 1043 |
+
outputs = self.bert(
|
| 1044 |
+
input_ids,
|
| 1045 |
+
attention_mask=attention_mask,
|
| 1046 |
+
token_type_ids=token_type_ids,
|
| 1047 |
+
position_ids=position_ids,
|
| 1048 |
+
inputs_embeds=inputs_embeds,
|
| 1049 |
+
return_dict=True,
|
| 1050 |
+
**kwargs,
|
| 1051 |
+
)
|
| 1052 |
+
|
| 1053 |
+
pooled_output = outputs[1]
|
| 1054 |
+
|
| 1055 |
+
seq_relationship_scores = self.cls(pooled_output)
|
| 1056 |
+
|
| 1057 |
+
next_sentence_loss = None
|
| 1058 |
+
if labels is not None:
|
| 1059 |
+
loss_fct = CrossEntropyLoss()
|
| 1060 |
+
next_sentence_loss = loss_fct(seq_relationship_scores.view(-1, 2), labels.view(-1))
|
| 1061 |
+
|
| 1062 |
+
return NextSentencePredictorOutput(
|
| 1063 |
+
loss=next_sentence_loss,
|
| 1064 |
+
logits=seq_relationship_scores,
|
| 1065 |
+
hidden_states=outputs.hidden_states,
|
| 1066 |
+
attentions=outputs.attentions,
|
| 1067 |
+
)
|
| 1068 |
+
|
| 1069 |
+
|
| 1070 |
+
@auto_docstring(
|
| 1071 |
+
custom_intro="""
|
| 1072 |
+
Bert Model transformer with a sequence classification/regression head on top (a linear layer on top of the pooled
|
| 1073 |
+
output) e.g. for GLUE tasks.
|
| 1074 |
+
"""
|
| 1075 |
+
)
|
| 1076 |
+
class BertForSequenceClassification(BertPreTrainedModel):
|
| 1077 |
+
def __init__(self, config):
|
| 1078 |
+
super().__init__(config)
|
| 1079 |
+
self.num_labels = config.num_labels
|
| 1080 |
+
self.config = config
|
| 1081 |
+
|
| 1082 |
+
self.bert = BertModel(config)
|
| 1083 |
+
classifier_dropout = (
|
| 1084 |
+
config.classifier_dropout if config.classifier_dropout is not None else config.hidden_dropout_prob
|
| 1085 |
+
)
|
| 1086 |
+
self.dropout = nn.Dropout(classifier_dropout)
|
| 1087 |
+
self.classifier = nn.Linear(config.hidden_size, config.num_labels)
|
| 1088 |
+
|
| 1089 |
+
# Initialize weights and apply final processing
|
| 1090 |
+
self.post_init()
|
| 1091 |
+
|
| 1092 |
+
@can_return_tuple
|
| 1093 |
+
@auto_docstring
|
| 1094 |
+
def forward(
|
| 1095 |
+
self,
|
| 1096 |
+
input_ids: torch.Tensor | None = None,
|
| 1097 |
+
attention_mask: torch.Tensor | None = None,
|
| 1098 |
+
token_type_ids: torch.Tensor | None = None,
|
| 1099 |
+
position_ids: torch.Tensor | None = None,
|
| 1100 |
+
inputs_embeds: torch.Tensor | None = None,
|
| 1101 |
+
labels: torch.Tensor | None = None,
|
| 1102 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 1103 |
+
) -> tuple[torch.Tensor] | SequenceClassifierOutput:
|
| 1104 |
+
r"""
|
| 1105 |
+
labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*):
|
| 1106 |
+
Labels for computing the sequence classification/regression loss. Indices should be in `[0, ...,
|
| 1107 |
+
config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If
|
| 1108 |
+
`config.num_labels > 1` a classification loss is computed (Cross-Entropy).
|
| 1109 |
+
"""
|
| 1110 |
+
outputs = self.bert(
|
| 1111 |
+
input_ids,
|
| 1112 |
+
attention_mask=attention_mask,
|
| 1113 |
+
token_type_ids=token_type_ids,
|
| 1114 |
+
position_ids=position_ids,
|
| 1115 |
+
inputs_embeds=inputs_embeds,
|
| 1116 |
+
return_dict=True,
|
| 1117 |
+
**kwargs,
|
| 1118 |
+
)
|
| 1119 |
+
|
| 1120 |
+
pooled_output = outputs[1]
|
| 1121 |
+
|
| 1122 |
+
pooled_output = self.dropout(pooled_output)
|
| 1123 |
+
logits = self.classifier(pooled_output)
|
| 1124 |
+
|
| 1125 |
+
loss = None
|
| 1126 |
+
if labels is not None:
|
| 1127 |
+
if self.config.problem_type is None:
|
| 1128 |
+
if self.num_labels == 1:
|
| 1129 |
+
self.config.problem_type = "regression"
|
| 1130 |
+
elif self.num_labels > 1 and (labels.dtype == torch.long or labels.dtype == torch.int):
|
| 1131 |
+
self.config.problem_type = "single_label_classification"
|
| 1132 |
+
else:
|
| 1133 |
+
self.config.problem_type = "multi_label_classification"
|
| 1134 |
+
|
| 1135 |
+
if self.config.problem_type == "regression":
|
| 1136 |
+
loss_fct = MSELoss()
|
| 1137 |
+
if self.num_labels == 1:
|
| 1138 |
+
loss = loss_fct(logits.squeeze(), labels.squeeze())
|
| 1139 |
+
else:
|
| 1140 |
+
loss = loss_fct(logits, labels)
|
| 1141 |
+
elif self.config.problem_type == "single_label_classification":
|
| 1142 |
+
loss_fct = CrossEntropyLoss()
|
| 1143 |
+
loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1))
|
| 1144 |
+
elif self.config.problem_type == "multi_label_classification":
|
| 1145 |
+
loss_fct = BCEWithLogitsLoss()
|
| 1146 |
+
loss = loss_fct(logits, labels)
|
| 1147 |
+
|
| 1148 |
+
return SequenceClassifierOutput(
|
| 1149 |
+
loss=loss,
|
| 1150 |
+
logits=logits,
|
| 1151 |
+
hidden_states=outputs.hidden_states,
|
| 1152 |
+
attentions=outputs.attentions,
|
| 1153 |
+
)
|
| 1154 |
+
|
| 1155 |
+
|
| 1156 |
+
@auto_docstring
|
| 1157 |
+
class BertForMultipleChoice(BertPreTrainedModel):
|
| 1158 |
+
def __init__(self, config):
|
| 1159 |
+
super().__init__(config)
|
| 1160 |
+
|
| 1161 |
+
self.bert = BertModel(config)
|
| 1162 |
+
classifier_dropout = (
|
| 1163 |
+
config.classifier_dropout if config.classifier_dropout is not None else config.hidden_dropout_prob
|
| 1164 |
+
)
|
| 1165 |
+
self.dropout = nn.Dropout(classifier_dropout)
|
| 1166 |
+
self.classifier = nn.Linear(config.hidden_size, 1)
|
| 1167 |
+
|
| 1168 |
+
# Initialize weights and apply final processing
|
| 1169 |
+
self.post_init()
|
| 1170 |
+
|
| 1171 |
+
@can_return_tuple
|
| 1172 |
+
@auto_docstring
|
| 1173 |
+
def forward(
|
| 1174 |
+
self,
|
| 1175 |
+
input_ids: torch.Tensor | None = None,
|
| 1176 |
+
attention_mask: torch.Tensor | None = None,
|
| 1177 |
+
token_type_ids: torch.Tensor | None = None,
|
| 1178 |
+
position_ids: torch.Tensor | None = None,
|
| 1179 |
+
inputs_embeds: torch.Tensor | None = None,
|
| 1180 |
+
labels: torch.Tensor | None = None,
|
| 1181 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 1182 |
+
) -> tuple[torch.Tensor] | MultipleChoiceModelOutput:
|
| 1183 |
+
r"""
|
| 1184 |
+
input_ids (`torch.LongTensor` of shape `(batch_size, num_choices, sequence_length)`):
|
| 1185 |
+
Indices of input sequence tokens in the vocabulary.
|
| 1186 |
+
|
| 1187 |
+
Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and
|
| 1188 |
+
[`PreTrainedTokenizer.__call__`] for details.
|
| 1189 |
+
|
| 1190 |
+
[What are input IDs?](../glossary#input-ids)
|
| 1191 |
+
token_type_ids (`torch.LongTensor` of shape `(batch_size, num_choices, sequence_length)`, *optional*):
|
| 1192 |
+
Segment token indices to indicate first and second portions of the inputs. Indices are selected in `[0,
|
| 1193 |
+
1]`:
|
| 1194 |
+
|
| 1195 |
+
- 0 corresponds to a *sentence A* token,
|
| 1196 |
+
- 1 corresponds to a *sentence B* token.
|
| 1197 |
+
|
| 1198 |
+
[What are token type IDs?](../glossary#token-type-ids)
|
| 1199 |
+
position_ids (`torch.LongTensor` of shape `(batch_size, num_choices, sequence_length)`, *optional*):
|
| 1200 |
+
Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0,
|
| 1201 |
+
config.max_position_embeddings - 1]`.
|
| 1202 |
+
|
| 1203 |
+
[What are position IDs?](../glossary#position-ids)
|
| 1204 |
+
inputs_embeds (`torch.FloatTensor` of shape `(batch_size, num_choices, sequence_length, hidden_size)`, *optional*):
|
| 1205 |
+
Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. This
|
| 1206 |
+
is useful if you want more control over how to convert `input_ids` indices into associated vectors than the
|
| 1207 |
+
model's internal embedding lookup matrix.
|
| 1208 |
+
labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*):
|
| 1209 |
+
Labels for computing the multiple choice classification loss. Indices should be in `[0, ...,
|
| 1210 |
+
num_choices-1]` where `num_choices` is the size of the second dimension of the input tensors. (See
|
| 1211 |
+
`input_ids` above)
|
| 1212 |
+
"""
|
| 1213 |
+
num_choices = input_ids.shape[1] if input_ids is not None else inputs_embeds.shape[1]
|
| 1214 |
+
|
| 1215 |
+
input_ids = input_ids.view(-1, input_ids.size(-1)) if input_ids is not None else None
|
| 1216 |
+
attention_mask = attention_mask.view(-1, attention_mask.size(-1)) if attention_mask is not None else None
|
| 1217 |
+
token_type_ids = token_type_ids.view(-1, token_type_ids.size(-1)) if token_type_ids is not None else None
|
| 1218 |
+
position_ids = position_ids.view(-1, position_ids.size(-1)) if position_ids is not None else None
|
| 1219 |
+
inputs_embeds = (
|
| 1220 |
+
inputs_embeds.view(-1, inputs_embeds.size(-2), inputs_embeds.size(-1))
|
| 1221 |
+
if inputs_embeds is not None
|
| 1222 |
+
else None
|
| 1223 |
+
)
|
| 1224 |
+
|
| 1225 |
+
outputs = self.bert(
|
| 1226 |
+
input_ids,
|
| 1227 |
+
attention_mask=attention_mask,
|
| 1228 |
+
token_type_ids=token_type_ids,
|
| 1229 |
+
position_ids=position_ids,
|
| 1230 |
+
inputs_embeds=inputs_embeds,
|
| 1231 |
+
return_dict=True,
|
| 1232 |
+
**kwargs,
|
| 1233 |
+
)
|
| 1234 |
+
|
| 1235 |
+
pooled_output = outputs[1]
|
| 1236 |
+
|
| 1237 |
+
pooled_output = self.dropout(pooled_output)
|
| 1238 |
+
logits = self.classifier(pooled_output)
|
| 1239 |
+
reshaped_logits = logits.view(-1, num_choices)
|
| 1240 |
+
|
| 1241 |
+
loss = None
|
| 1242 |
+
if labels is not None:
|
| 1243 |
+
loss_fct = CrossEntropyLoss()
|
| 1244 |
+
loss = loss_fct(reshaped_logits, labels)
|
| 1245 |
+
|
| 1246 |
+
return MultipleChoiceModelOutput(
|
| 1247 |
+
loss=loss,
|
| 1248 |
+
logits=reshaped_logits,
|
| 1249 |
+
hidden_states=outputs.hidden_states,
|
| 1250 |
+
attentions=outputs.attentions,
|
| 1251 |
+
)
|
| 1252 |
+
|
| 1253 |
+
|
| 1254 |
+
@auto_docstring
|
| 1255 |
+
class BertForTokenClassification(BertPreTrainedModel):
|
| 1256 |
+
def __init__(self, config):
|
| 1257 |
+
super().__init__(config)
|
| 1258 |
+
self.num_labels = config.num_labels
|
| 1259 |
+
|
| 1260 |
+
self.bert = BertModel(config, add_pooling_layer=False)
|
| 1261 |
+
classifier_dropout = (
|
| 1262 |
+
config.classifier_dropout if config.classifier_dropout is not None else config.hidden_dropout_prob
|
| 1263 |
+
)
|
| 1264 |
+
self.dropout = nn.Dropout(classifier_dropout)
|
| 1265 |
+
self.classifier = nn.Linear(config.hidden_size, config.num_labels)
|
| 1266 |
+
|
| 1267 |
+
# Initialize weights and apply final processing
|
| 1268 |
+
self.post_init()
|
| 1269 |
+
|
| 1270 |
+
@can_return_tuple
|
| 1271 |
+
@auto_docstring
|
| 1272 |
+
def forward(
|
| 1273 |
+
self,
|
| 1274 |
+
input_ids: torch.Tensor | None = None,
|
| 1275 |
+
attention_mask: torch.Tensor | None = None,
|
| 1276 |
+
token_type_ids: torch.Tensor | None = None,
|
| 1277 |
+
position_ids: torch.Tensor | None = None,
|
| 1278 |
+
inputs_embeds: torch.Tensor | None = None,
|
| 1279 |
+
labels: torch.Tensor | None = None,
|
| 1280 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 1281 |
+
) -> tuple[torch.Tensor] | TokenClassifierOutput:
|
| 1282 |
+
r"""
|
| 1283 |
+
labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):
|
| 1284 |
+
Labels for computing the token classification loss. Indices should be in `[0, ..., config.num_labels - 1]`.
|
| 1285 |
+
"""
|
| 1286 |
+
outputs = self.bert(
|
| 1287 |
+
input_ids,
|
| 1288 |
+
attention_mask=attention_mask,
|
| 1289 |
+
token_type_ids=token_type_ids,
|
| 1290 |
+
position_ids=position_ids,
|
| 1291 |
+
inputs_embeds=inputs_embeds,
|
| 1292 |
+
return_dict=True,
|
| 1293 |
+
**kwargs,
|
| 1294 |
+
)
|
| 1295 |
+
|
| 1296 |
+
sequence_output = outputs[0]
|
| 1297 |
+
|
| 1298 |
+
sequence_output = self.dropout(sequence_output)
|
| 1299 |
+
logits = self.classifier(sequence_output)
|
| 1300 |
+
|
| 1301 |
+
loss = None
|
| 1302 |
+
if labels is not None:
|
| 1303 |
+
loss_fct = CrossEntropyLoss()
|
| 1304 |
+
loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1))
|
| 1305 |
+
|
| 1306 |
+
return TokenClassifierOutput(
|
| 1307 |
+
loss=loss,
|
| 1308 |
+
logits=logits,
|
| 1309 |
+
hidden_states=outputs.hidden_states,
|
| 1310 |
+
attentions=outputs.attentions,
|
| 1311 |
+
)
|
| 1312 |
+
|
| 1313 |
+
|
| 1314 |
+
@auto_docstring
|
| 1315 |
+
class BertForQuestionAnswering(BertPreTrainedModel):
|
| 1316 |
+
def __init__(self, config):
|
| 1317 |
+
super().__init__(config)
|
| 1318 |
+
self.num_labels = config.num_labels
|
| 1319 |
+
|
| 1320 |
+
self.bert = BertModel(config, add_pooling_layer=False)
|
| 1321 |
+
self.qa_outputs = nn.Linear(config.hidden_size, config.num_labels)
|
| 1322 |
+
|
| 1323 |
+
# Initialize weights and apply final processing
|
| 1324 |
+
self.post_init()
|
| 1325 |
+
|
| 1326 |
+
@can_return_tuple
|
| 1327 |
+
@auto_docstring
|
| 1328 |
+
def forward(
|
| 1329 |
+
self,
|
| 1330 |
+
input_ids: torch.Tensor | None = None,
|
| 1331 |
+
attention_mask: torch.Tensor | None = None,
|
| 1332 |
+
token_type_ids: torch.Tensor | None = None,
|
| 1333 |
+
position_ids: torch.Tensor | None = None,
|
| 1334 |
+
inputs_embeds: torch.Tensor | None = None,
|
| 1335 |
+
start_positions: torch.Tensor | None = None,
|
| 1336 |
+
end_positions: torch.Tensor | None = None,
|
| 1337 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 1338 |
+
) -> tuple[torch.Tensor] | QuestionAnsweringModelOutput:
|
| 1339 |
+
outputs = self.bert(
|
| 1340 |
+
input_ids,
|
| 1341 |
+
attention_mask=attention_mask,
|
| 1342 |
+
token_type_ids=token_type_ids,
|
| 1343 |
+
position_ids=position_ids,
|
| 1344 |
+
inputs_embeds=inputs_embeds,
|
| 1345 |
+
return_dict=True,
|
| 1346 |
+
**kwargs,
|
| 1347 |
+
)
|
| 1348 |
+
|
| 1349 |
+
sequence_output = outputs[0]
|
| 1350 |
+
|
| 1351 |
+
logits = self.qa_outputs(sequence_output)
|
| 1352 |
+
start_logits, end_logits = logits.split(1, dim=-1)
|
| 1353 |
+
start_logits = start_logits.squeeze(-1).contiguous()
|
| 1354 |
+
end_logits = end_logits.squeeze(-1).contiguous()
|
| 1355 |
+
|
| 1356 |
+
total_loss = None
|
| 1357 |
+
if start_positions is not None and end_positions is not None:
|
| 1358 |
+
# If we are on multi-GPU, split add a dimension
|
| 1359 |
+
if len(start_positions.size()) > 1:
|
| 1360 |
+
start_positions = start_positions.squeeze(-1)
|
| 1361 |
+
if len(end_positions.size()) > 1:
|
| 1362 |
+
end_positions = end_positions.squeeze(-1)
|
| 1363 |
+
# sometimes the start/end positions are outside our model inputs, we ignore these terms
|
| 1364 |
+
ignored_index = start_logits.size(1)
|
| 1365 |
+
start_positions = start_positions.clamp(0, ignored_index)
|
| 1366 |
+
end_positions = end_positions.clamp(0, ignored_index)
|
| 1367 |
+
|
| 1368 |
+
loss_fct = CrossEntropyLoss(ignore_index=ignored_index)
|
| 1369 |
+
start_loss = loss_fct(start_logits, start_positions)
|
| 1370 |
+
end_loss = loss_fct(end_logits, end_positions)
|
| 1371 |
+
total_loss = (start_loss + end_loss) / 2
|
| 1372 |
+
|
| 1373 |
+
return QuestionAnsweringModelOutput(
|
| 1374 |
+
loss=total_loss,
|
| 1375 |
+
start_logits=start_logits,
|
| 1376 |
+
end_logits=end_logits,
|
| 1377 |
+
hidden_states=outputs.hidden_states,
|
| 1378 |
+
attentions=outputs.attentions,
|
| 1379 |
+
)
|
| 1380 |
+
|
| 1381 |
+
|
| 1382 |
+
__all__ = [
|
| 1383 |
+
"BertForMaskedLM",
|
| 1384 |
+
"BertForMultipleChoice",
|
| 1385 |
+
"BertForNextSentencePrediction",
|
| 1386 |
+
"BertForPreTraining",
|
| 1387 |
+
"BertForQuestionAnswering",
|
| 1388 |
+
"BertForSequenceClassification",
|
| 1389 |
+
"BertForTokenClassification",
|
| 1390 |
+
"BertLayer",
|
| 1391 |
+
"BertLMHeadModel",
|
| 1392 |
+
"BertModel",
|
| 1393 |
+
"BertPreTrainedModel",
|
| 1394 |
+
]
|
LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/transformers/models/bert/tokenization_bert.py
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2018 The Google AI Language Team Authors and The HuggingFace Inc. team.
|
| 2 |
+
#
|
| 3 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 4 |
+
# you may not use this file except in compliance with the License.
|
| 5 |
+
# You may obtain a copy of the License at
|
| 6 |
+
#
|
| 7 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 8 |
+
#
|
| 9 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 10 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 11 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 12 |
+
# See the License for the specific language governing permissions and
|
| 13 |
+
# limitations under the License.
|
| 14 |
+
"""Tokenization classes for Bert."""
|
| 15 |
+
|
| 16 |
+
import collections
|
| 17 |
+
|
| 18 |
+
from tokenizers import Tokenizer, decoders, normalizers, pre_tokenizers, processors
|
| 19 |
+
from tokenizers.models import WordPiece
|
| 20 |
+
|
| 21 |
+
from ...tokenization_utils_tokenizers import TokenizersBackend
|
| 22 |
+
from ...utils import logging
|
| 23 |
+
|
| 24 |
+
|
| 25 |
+
logger = logging.get_logger(__name__)
|
| 26 |
+
|
| 27 |
+
VOCAB_FILES_NAMES = {"vocab_file": "vocab.txt", "tokenizer_file": "tokenizer.json"}
|
| 28 |
+
|
| 29 |
+
|
| 30 |
+
def load_vocab(vocab_file):
|
| 31 |
+
"""Loads a vocabulary file into a dictionary."""
|
| 32 |
+
vocab = collections.OrderedDict()
|
| 33 |
+
with open(vocab_file, "r", encoding="utf-8") as reader:
|
| 34 |
+
tokens = reader.readlines()
|
| 35 |
+
for index, token in enumerate(tokens):
|
| 36 |
+
token = token.rstrip("\n")
|
| 37 |
+
vocab[token] = index
|
| 38 |
+
return vocab
|
| 39 |
+
|
| 40 |
+
|
| 41 |
+
class BertTokenizer(TokenizersBackend):
|
| 42 |
+
r"""
|
| 43 |
+
Construct a BERT tokenizer (backed by HuggingFace's tokenizers library). Based on WordPiece.
|
| 44 |
+
|
| 45 |
+
This tokenizer inherits from [`TokenizersBackend`] which contains most of the main methods. Users should refer to
|
| 46 |
+
this superclass for more information regarding those methods.
|
| 47 |
+
|
| 48 |
+
Args:
|
| 49 |
+
vocab (`str` or `dict[str, int]`, *optional*):
|
| 50 |
+
Custom vocabulary dictionary. If not provided, vocabulary is loaded from `vocab_file`.
|
| 51 |
+
do_lower_case (`bool`, *optional*, defaults to `True`):
|
| 52 |
+
Whether or not to lowercase the input when tokenizing.
|
| 53 |
+
unk_token (`str`, *optional*, defaults to `"[UNK]"`):
|
| 54 |
+
The unknown token. A token that is not in the vocabulary cannot be converted to an ID and is set to be this
|
| 55 |
+
token instead.
|
| 56 |
+
sep_token (`str`, *optional*, defaults to `"[SEP]"`):
|
| 57 |
+
The separator token, which is used when building a sequence from multiple sequences, e.g. two sequences for
|
| 58 |
+
sequence classification or for a text and a question for question answering. It is also used as the last
|
| 59 |
+
token of a sequence built with special tokens.
|
| 60 |
+
pad_token (`str`, *optional*, defaults to `"[PAD]"`):
|
| 61 |
+
The token used for padding, for example when batching sequences of different lengths.
|
| 62 |
+
cls_token (`str`, *optional*, defaults to `"[CLS]"`):
|
| 63 |
+
The classifier token which is used when doing sequence classification (classification of the whole sequence
|
| 64 |
+
instead of per-token classification). It is the first token of the sequence when built with special tokens.
|
| 65 |
+
mask_token (`str`, *optional*, defaults to `"[MASK]"`):
|
| 66 |
+
The token used for masking values. This is the token used when training this model with masked language
|
| 67 |
+
modeling. This is the token which the model will try to predict.
|
| 68 |
+
tokenize_chinese_chars (`bool`, *optional*, defaults to `True`):
|
| 69 |
+
Whether or not to tokenize Chinese characters.
|
| 70 |
+
strip_accents (`bool`, *optional*):
|
| 71 |
+
Whether or not to strip all accents. If this option is not specified, then it will be determined by the
|
| 72 |
+
value for `lowercase` (as in the original BERT).
|
| 73 |
+
"""
|
| 74 |
+
|
| 75 |
+
vocab_files_names = VOCAB_FILES_NAMES
|
| 76 |
+
model_input_names = ["input_ids", "token_type_ids", "attention_mask"]
|
| 77 |
+
model = WordPiece
|
| 78 |
+
|
| 79 |
+
def __init__(
|
| 80 |
+
self,
|
| 81 |
+
vocab: str | dict[str, int] | None = None,
|
| 82 |
+
do_lower_case: bool = True,
|
| 83 |
+
unk_token: str = "[UNK]",
|
| 84 |
+
sep_token: str = "[SEP]",
|
| 85 |
+
pad_token: str = "[PAD]",
|
| 86 |
+
cls_token: str = "[CLS]",
|
| 87 |
+
mask_token: str = "[MASK]",
|
| 88 |
+
tokenize_chinese_chars: bool = True,
|
| 89 |
+
strip_accents: bool | None = None,
|
| 90 |
+
**kwargs,
|
| 91 |
+
):
|
| 92 |
+
self.do_lower_case = do_lower_case
|
| 93 |
+
self.tokenize_chinese_chars = tokenize_chinese_chars
|
| 94 |
+
self.strip_accents = strip_accents
|
| 95 |
+
if vocab is None:
|
| 96 |
+
vocab = {
|
| 97 |
+
str(pad_token): 0,
|
| 98 |
+
str(unk_token): 1,
|
| 99 |
+
str(cls_token): 2,
|
| 100 |
+
str(sep_token): 3,
|
| 101 |
+
str(mask_token): 4,
|
| 102 |
+
}
|
| 103 |
+
self._vocab = vocab
|
| 104 |
+
self._tokenizer = Tokenizer(WordPiece(self._vocab, unk_token=str(unk_token)))
|
| 105 |
+
self._tokenizer.normalizer = normalizers.BertNormalizer(
|
| 106 |
+
clean_text=True,
|
| 107 |
+
handle_chinese_chars=tokenize_chinese_chars,
|
| 108 |
+
strip_accents=strip_accents,
|
| 109 |
+
lowercase=do_lower_case,
|
| 110 |
+
)
|
| 111 |
+
self._tokenizer.pre_tokenizer = pre_tokenizers.BertPreTokenizer()
|
| 112 |
+
self._tokenizer.decoder = decoders.WordPiece(prefix="##")
|
| 113 |
+
super().__init__(
|
| 114 |
+
do_lower_case=do_lower_case,
|
| 115 |
+
unk_token=unk_token,
|
| 116 |
+
sep_token=sep_token,
|
| 117 |
+
pad_token=pad_token,
|
| 118 |
+
cls_token=cls_token,
|
| 119 |
+
mask_token=mask_token,
|
| 120 |
+
tokenize_chinese_chars=tokenize_chinese_chars,
|
| 121 |
+
strip_accents=strip_accents,
|
| 122 |
+
**kwargs,
|
| 123 |
+
)
|
| 124 |
+
|
| 125 |
+
cls_token_id = self.cls_token_id if self.cls_token_id is not None else 2
|
| 126 |
+
sep_token_id = self.sep_token_id if self.sep_token_id is not None else 3
|
| 127 |
+
|
| 128 |
+
self._tokenizer.post_processor = processors.TemplateProcessing(
|
| 129 |
+
single=f"{str(self.cls_token)}:0 $A:0 {str(self.sep_token)}:0",
|
| 130 |
+
pair=f"{str(self.cls_token)}:0 $A:0 {str(self.sep_token)}:0 $B:1 {str(self.sep_token)}:1",
|
| 131 |
+
special_tokens=[
|
| 132 |
+
(str(self.cls_token), cls_token_id),
|
| 133 |
+
(str(self.sep_token), sep_token_id),
|
| 134 |
+
],
|
| 135 |
+
)
|
| 136 |
+
|
| 137 |
+
|
| 138 |
+
__all__ = ["BertTokenizer"]
|
| 139 |
+
|
| 140 |
+
BertTokenizerFast = BertTokenizer
|
LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/transformers/models/bert/tokenization_bert_legacy.py
ADDED
|
@@ -0,0 +1,476 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2018 The Google AI Language Team Authors and The HuggingFace Inc. team.
|
| 2 |
+
#
|
| 3 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 4 |
+
# you may not use this file except in compliance with the License.
|
| 5 |
+
# You may obtain a copy of the License at
|
| 6 |
+
#
|
| 7 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 8 |
+
#
|
| 9 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 10 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 11 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 12 |
+
# See the License for the specific language governing permissions and
|
| 13 |
+
# limitations under the License.
|
| 14 |
+
"""Tokenization classes for Bert."""
|
| 15 |
+
|
| 16 |
+
import collections
|
| 17 |
+
import os
|
| 18 |
+
import unicodedata
|
| 19 |
+
|
| 20 |
+
from ...tokenization_python import PreTrainedTokenizer, _is_control, _is_punctuation, _is_whitespace
|
| 21 |
+
from ...utils import logging
|
| 22 |
+
|
| 23 |
+
|
| 24 |
+
logger = logging.get_logger(__name__)
|
| 25 |
+
|
| 26 |
+
VOCAB_FILES_NAMES = {"vocab_file": "vocab.txt"}
|
| 27 |
+
|
| 28 |
+
|
| 29 |
+
def load_vocab(vocab_file):
|
| 30 |
+
"""Loads a vocabulary file into a dictionary."""
|
| 31 |
+
vocab = collections.OrderedDict()
|
| 32 |
+
with open(vocab_file, "r", encoding="utf-8") as reader:
|
| 33 |
+
tokens = reader.readlines()
|
| 34 |
+
for index, token in enumerate(tokens):
|
| 35 |
+
token = token.rstrip("\n")
|
| 36 |
+
vocab[token] = index
|
| 37 |
+
return vocab
|
| 38 |
+
|
| 39 |
+
|
| 40 |
+
def whitespace_tokenize(text):
|
| 41 |
+
"""Runs basic whitespace cleaning and splitting on a piece of text."""
|
| 42 |
+
text = text.strip()
|
| 43 |
+
if not text:
|
| 44 |
+
return []
|
| 45 |
+
tokens = text.split()
|
| 46 |
+
return tokens
|
| 47 |
+
|
| 48 |
+
|
| 49 |
+
class BertTokenizerLegacy(PreTrainedTokenizer):
|
| 50 |
+
r"""
|
| 51 |
+
Construct a BERT tokenizer. Based on WordPiece.
|
| 52 |
+
|
| 53 |
+
This tokenizer inherits from [`PreTrainedTokenizer`] which contains most of the main methods. Users should refer to
|
| 54 |
+
this superclass for more information regarding those methods.
|
| 55 |
+
|
| 56 |
+
Args:
|
| 57 |
+
vocab_file (`str`):
|
| 58 |
+
File containing the vocabulary.
|
| 59 |
+
do_lower_case (`bool`, *optional*, defaults to `True`):
|
| 60 |
+
Whether or not to lowercase the input when tokenizing.
|
| 61 |
+
do_basic_tokenize (`bool`, *optional*, defaults to `True`):
|
| 62 |
+
Whether or not to do basic tokenization before WordPiece.
|
| 63 |
+
never_split (`Iterable`, *optional*):
|
| 64 |
+
Collection of tokens which will never be split during tokenization. Only has an effect when
|
| 65 |
+
`do_basic_tokenize=True`
|
| 66 |
+
unk_token (`str`, *optional*, defaults to `"[UNK]"`):
|
| 67 |
+
The unknown token. A token that is not in the vocabulary cannot be converted to an ID and is set to be this
|
| 68 |
+
token instead.
|
| 69 |
+
sep_token (`str`, *optional*, defaults to `"[SEP]"`):
|
| 70 |
+
The separator token, which is used when building a sequence from multiple sequences, e.g. two sequences for
|
| 71 |
+
sequence classification or for a text and a question for question answering. It is also used as the last
|
| 72 |
+
token of a sequence built with special tokens.
|
| 73 |
+
pad_token (`str`, *optional*, defaults to `"[PAD]"`):
|
| 74 |
+
The token used for padding, for example when batching sequences of different lengths.
|
| 75 |
+
cls_token (`str`, *optional*, defaults to `"[CLS]"`):
|
| 76 |
+
The classifier token which is used when doing sequence classification (classification of the whole sequence
|
| 77 |
+
instead of per-token classification). It is the first token of the sequence when built with special tokens.
|
| 78 |
+
mask_token (`str`, *optional*, defaults to `"[MASK]"`):
|
| 79 |
+
The token used for masking values. This is the token used when training this model with masked language
|
| 80 |
+
modeling. This is the token which the model will try to predict.
|
| 81 |
+
tokenize_chinese_chars (`bool`, *optional*, defaults to `True`):
|
| 82 |
+
Whether or not to tokenize Chinese characters.
|
| 83 |
+
|
| 84 |
+
This should likely be deactivated for Japanese (see this
|
| 85 |
+
[issue](https://github.com/huggingface/transformers/issues/328)).
|
| 86 |
+
strip_accents (`bool`, *optional*):
|
| 87 |
+
Whether or not to strip all accents. If this option is not specified, then it will be determined by the
|
| 88 |
+
value for `lowercase` (as in the original BERT).
|
| 89 |
+
clean_up_tokenization_spaces (`bool`, *optional*, defaults to `True`):
|
| 90 |
+
Whether or not to cleanup spaces after decoding, cleanup consists in removing potential artifacts like
|
| 91 |
+
extra spaces.
|
| 92 |
+
"""
|
| 93 |
+
|
| 94 |
+
vocab_files_names = VOCAB_FILES_NAMES
|
| 95 |
+
|
| 96 |
+
def __init__(
|
| 97 |
+
self,
|
| 98 |
+
vocab_file,
|
| 99 |
+
do_lower_case=True,
|
| 100 |
+
do_basic_tokenize=True,
|
| 101 |
+
never_split=None,
|
| 102 |
+
unk_token="[UNK]",
|
| 103 |
+
sep_token="[SEP]",
|
| 104 |
+
pad_token="[PAD]",
|
| 105 |
+
cls_token="[CLS]",
|
| 106 |
+
mask_token="[MASK]",
|
| 107 |
+
tokenize_chinese_chars=True,
|
| 108 |
+
strip_accents=None,
|
| 109 |
+
clean_up_tokenization_spaces=True,
|
| 110 |
+
**kwargs,
|
| 111 |
+
):
|
| 112 |
+
if not os.path.isfile(vocab_file):
|
| 113 |
+
raise ValueError(
|
| 114 |
+
f"Can't find a vocabulary file at path '{vocab_file}'. To load the vocabulary from a Google pretrained"
|
| 115 |
+
" model use `tokenizer = BertTokenizer.from_pretrained(PRETRAINED_MODEL_NAME)`"
|
| 116 |
+
)
|
| 117 |
+
self.vocab = load_vocab(vocab_file)
|
| 118 |
+
self.ids_to_tokens = collections.OrderedDict([(ids, tok) for tok, ids in self.vocab.items()])
|
| 119 |
+
self.do_basic_tokenize = do_basic_tokenize
|
| 120 |
+
if do_basic_tokenize:
|
| 121 |
+
self.basic_tokenizer = BasicTokenizer(
|
| 122 |
+
do_lower_case=do_lower_case,
|
| 123 |
+
never_split=never_split,
|
| 124 |
+
tokenize_chinese_chars=tokenize_chinese_chars,
|
| 125 |
+
strip_accents=strip_accents,
|
| 126 |
+
)
|
| 127 |
+
|
| 128 |
+
self.wordpiece_tokenizer = WordpieceTokenizer(vocab=self.vocab, unk_token=str(unk_token))
|
| 129 |
+
|
| 130 |
+
super().__init__(
|
| 131 |
+
do_lower_case=do_lower_case,
|
| 132 |
+
do_basic_tokenize=do_basic_tokenize,
|
| 133 |
+
never_split=never_split,
|
| 134 |
+
unk_token=unk_token,
|
| 135 |
+
sep_token=sep_token,
|
| 136 |
+
pad_token=pad_token,
|
| 137 |
+
cls_token=cls_token,
|
| 138 |
+
mask_token=mask_token,
|
| 139 |
+
tokenize_chinese_chars=tokenize_chinese_chars,
|
| 140 |
+
strip_accents=strip_accents,
|
| 141 |
+
clean_up_tokenization_spaces=clean_up_tokenization_spaces,
|
| 142 |
+
**kwargs,
|
| 143 |
+
)
|
| 144 |
+
|
| 145 |
+
@property
|
| 146 |
+
def do_lower_case(self):
|
| 147 |
+
return self.basic_tokenizer.do_lower_case
|
| 148 |
+
|
| 149 |
+
@property
|
| 150 |
+
def vocab_size(self):
|
| 151 |
+
return len(self.vocab)
|
| 152 |
+
|
| 153 |
+
def get_vocab(self):
|
| 154 |
+
return dict(self.vocab, **self.added_tokens_encoder)
|
| 155 |
+
|
| 156 |
+
def _tokenize(self, text, split_special_tokens=False):
|
| 157 |
+
split_tokens = []
|
| 158 |
+
if self.do_basic_tokenize:
|
| 159 |
+
for token in self.basic_tokenizer.tokenize(
|
| 160 |
+
text, never_split=self.all_special_tokens if not split_special_tokens else None
|
| 161 |
+
):
|
| 162 |
+
# If the token is part of the never_split set
|
| 163 |
+
if token in self.basic_tokenizer.never_split:
|
| 164 |
+
split_tokens.append(token)
|
| 165 |
+
else:
|
| 166 |
+
split_tokens += self.wordpiece_tokenizer.tokenize(token)
|
| 167 |
+
else:
|
| 168 |
+
split_tokens = self.wordpiece_tokenizer.tokenize(text)
|
| 169 |
+
return split_tokens
|
| 170 |
+
|
| 171 |
+
def _convert_token_to_id(self, token):
|
| 172 |
+
"""Converts a token (str) in an id using the vocab."""
|
| 173 |
+
return self.vocab.get(token, self.vocab.get(self.unk_token))
|
| 174 |
+
|
| 175 |
+
def _convert_id_to_token(self, index):
|
| 176 |
+
"""Converts an index (integer) in a token (str) using the vocab."""
|
| 177 |
+
return self.ids_to_tokens.get(index, self.unk_token)
|
| 178 |
+
|
| 179 |
+
def convert_tokens_to_string(self, tokens):
|
| 180 |
+
"""Converts a sequence of tokens (string) in a single string."""
|
| 181 |
+
out_string = " ".join(tokens).replace(" ##", "").strip()
|
| 182 |
+
return out_string
|
| 183 |
+
|
| 184 |
+
def build_inputs_with_special_tokens(
|
| 185 |
+
self, token_ids_0: list[int], token_ids_1: list[int] | None = None
|
| 186 |
+
) -> list[int]:
|
| 187 |
+
"""
|
| 188 |
+
Build model inputs from a sequence or a pair of sequence for sequence classification tasks by concatenating and
|
| 189 |
+
adding special tokens. A BERT sequence has the following format:
|
| 190 |
+
|
| 191 |
+
- single sequence: `[CLS] X [SEP]`
|
| 192 |
+
- pair of sequences: `[CLS] A [SEP] B [SEP]`
|
| 193 |
+
|
| 194 |
+
Args:
|
| 195 |
+
token_ids_0 (`List[int]`):
|
| 196 |
+
List of IDs to which the special tokens will be added.
|
| 197 |
+
token_ids_1 (`List[int]`, *optional*):
|
| 198 |
+
Optional second list of IDs for sequence pairs.
|
| 199 |
+
|
| 200 |
+
Returns:
|
| 201 |
+
`List[int]`: List of [input IDs](../glossary#input-ids) with the appropriate special tokens.
|
| 202 |
+
"""
|
| 203 |
+
if token_ids_1 is None:
|
| 204 |
+
return [self.cls_token_id] + token_ids_0 + [self.sep_token_id]
|
| 205 |
+
cls = [self.cls_token_id]
|
| 206 |
+
sep = [self.sep_token_id]
|
| 207 |
+
return cls + token_ids_0 + sep + token_ids_1 + sep
|
| 208 |
+
|
| 209 |
+
def get_special_tokens_mask(
|
| 210 |
+
self, token_ids_0: list[int], token_ids_1: list[int] | None = None, already_has_special_tokens: bool = False
|
| 211 |
+
) -> list[int]:
|
| 212 |
+
"""
|
| 213 |
+
Retrieve sequence ids from a token list that has no special tokens added. This method is called when adding
|
| 214 |
+
special tokens using the tokenizer `prepare_for_model` method.
|
| 215 |
+
|
| 216 |
+
Args:
|
| 217 |
+
token_ids_0 (`List[int]`):
|
| 218 |
+
List of IDs.
|
| 219 |
+
token_ids_1 (`List[int]`, *optional*):
|
| 220 |
+
Optional second list of IDs for sequence pairs.
|
| 221 |
+
already_has_special_tokens (`bool`, *optional*, defaults to `False`):
|
| 222 |
+
Whether or not the token list is already formatted with special tokens for the model.
|
| 223 |
+
|
| 224 |
+
Returns:
|
| 225 |
+
`List[int]`: A list of integers in the range [0, 1]: 1 for a special token, 0 for a sequence token.
|
| 226 |
+
"""
|
| 227 |
+
|
| 228 |
+
if already_has_special_tokens:
|
| 229 |
+
return super().get_special_tokens_mask(
|
| 230 |
+
token_ids_0=token_ids_0, token_ids_1=token_ids_1, already_has_special_tokens=True
|
| 231 |
+
)
|
| 232 |
+
|
| 233 |
+
if token_ids_1 is not None:
|
| 234 |
+
return [1] + ([0] * len(token_ids_0)) + [1] + ([0] * len(token_ids_1)) + [1]
|
| 235 |
+
return [1] + ([0] * len(token_ids_0)) + [1]
|
| 236 |
+
|
| 237 |
+
def save_vocabulary(self, save_directory: str, filename_prefix: str | None = None) -> tuple[str]:
|
| 238 |
+
index = 0
|
| 239 |
+
if os.path.isdir(save_directory):
|
| 240 |
+
vocab_file = os.path.join(
|
| 241 |
+
save_directory, (filename_prefix + "-" if filename_prefix else "") + VOCAB_FILES_NAMES["vocab_file"]
|
| 242 |
+
)
|
| 243 |
+
else:
|
| 244 |
+
vocab_file = (filename_prefix + "-" if filename_prefix else "") + save_directory
|
| 245 |
+
with open(vocab_file, "w", encoding="utf-8") as writer:
|
| 246 |
+
for token, token_index in sorted(self.vocab.items(), key=lambda kv: kv[1]):
|
| 247 |
+
if index != token_index:
|
| 248 |
+
logger.warning(
|
| 249 |
+
f"Saving vocabulary to {vocab_file}: vocabulary indices are not consecutive."
|
| 250 |
+
" Please check that the vocabulary is not corrupted!"
|
| 251 |
+
)
|
| 252 |
+
index = token_index
|
| 253 |
+
writer.write(token + "\n")
|
| 254 |
+
index += 1
|
| 255 |
+
return (vocab_file,)
|
| 256 |
+
|
| 257 |
+
|
| 258 |
+
class BasicTokenizer:
|
| 259 |
+
"""
|
| 260 |
+
Constructs a BasicTokenizer that will run basic tokenization (punctuation splitting, lower casing, etc.).
|
| 261 |
+
|
| 262 |
+
Args:
|
| 263 |
+
do_lower_case (`bool`, *optional*, defaults to `True`):
|
| 264 |
+
Whether or not to lowercase the input when tokenizing.
|
| 265 |
+
never_split (`Iterable`, *optional*):
|
| 266 |
+
Collection of tokens which will never be split during tokenization. Only has an effect when
|
| 267 |
+
`do_basic_tokenize=True`
|
| 268 |
+
tokenize_chinese_chars (`bool`, *optional*, defaults to `True`):
|
| 269 |
+
Whether or not to tokenize Chinese characters.
|
| 270 |
+
|
| 271 |
+
This should likely be deactivated for Japanese (see this
|
| 272 |
+
[issue](https://github.com/huggingface/transformers/issues/328)).
|
| 273 |
+
strip_accents (`bool`, *optional*):
|
| 274 |
+
Whether or not to strip all accents. If this option is not specified, then it will be determined by the
|
| 275 |
+
value for `lowercase` (as in the original BERT).
|
| 276 |
+
do_split_on_punc (`bool`, *optional*, defaults to `True`):
|
| 277 |
+
In some instances we want to skip the basic punctuation splitting so that later tokenization can capture
|
| 278 |
+
the full context of the words, such as contractions.
|
| 279 |
+
"""
|
| 280 |
+
|
| 281 |
+
def __init__(
|
| 282 |
+
self,
|
| 283 |
+
do_lower_case=True,
|
| 284 |
+
never_split=None,
|
| 285 |
+
tokenize_chinese_chars=True,
|
| 286 |
+
strip_accents=None,
|
| 287 |
+
do_split_on_punc=True,
|
| 288 |
+
):
|
| 289 |
+
if never_split is None:
|
| 290 |
+
never_split = []
|
| 291 |
+
self.do_lower_case = do_lower_case
|
| 292 |
+
self.never_split = set(never_split)
|
| 293 |
+
self.tokenize_chinese_chars = tokenize_chinese_chars
|
| 294 |
+
self.strip_accents = strip_accents
|
| 295 |
+
self.do_split_on_punc = do_split_on_punc
|
| 296 |
+
|
| 297 |
+
def tokenize(self, text, never_split=None):
|
| 298 |
+
"""
|
| 299 |
+
Basic Tokenization of a piece of text. For sub-word tokenization, see WordPieceTokenizer.
|
| 300 |
+
|
| 301 |
+
Args:
|
| 302 |
+
never_split (`List[str]`, *optional*)
|
| 303 |
+
Kept for backward compatibility purposes. Now implemented directly at the base class level (see
|
| 304 |
+
[`PreTrainedTokenizer.tokenize`]) List of token not to split.
|
| 305 |
+
"""
|
| 306 |
+
# union() returns a new set by concatenating the two sets.
|
| 307 |
+
never_split = self.never_split.union(set(never_split)) if never_split else self.never_split
|
| 308 |
+
text = self._clean_text(text)
|
| 309 |
+
|
| 310 |
+
# This was added on November 1st, 2018 for the multilingual and Chinese
|
| 311 |
+
# models. This is also applied to the English models now, but it doesn't
|
| 312 |
+
# matter since the English models were not trained on any Chinese data
|
| 313 |
+
# and generally don't have any Chinese data in them (there are Chinese
|
| 314 |
+
# characters in the vocabulary because Wikipedia does have some Chinese
|
| 315 |
+
# words in the English Wikipedia.).
|
| 316 |
+
if self.tokenize_chinese_chars:
|
| 317 |
+
text = self._tokenize_chinese_chars(text)
|
| 318 |
+
# prevents treating the same character with different unicode codepoints as different characters
|
| 319 |
+
unicode_normalized_text = unicodedata.normalize("NFC", text)
|
| 320 |
+
orig_tokens = whitespace_tokenize(unicode_normalized_text)
|
| 321 |
+
split_tokens = []
|
| 322 |
+
for token in orig_tokens:
|
| 323 |
+
if token not in never_split:
|
| 324 |
+
if self.do_lower_case:
|
| 325 |
+
token = token.lower()
|
| 326 |
+
if self.strip_accents is not False:
|
| 327 |
+
token = self._run_strip_accents(token)
|
| 328 |
+
elif self.strip_accents:
|
| 329 |
+
token = self._run_strip_accents(token)
|
| 330 |
+
split_tokens.extend(self._run_split_on_punc(token, never_split))
|
| 331 |
+
|
| 332 |
+
output_tokens = whitespace_tokenize(" ".join(split_tokens))
|
| 333 |
+
return output_tokens
|
| 334 |
+
|
| 335 |
+
def _run_strip_accents(self, text):
|
| 336 |
+
"""Strips accents from a piece of text."""
|
| 337 |
+
text = unicodedata.normalize("NFD", text)
|
| 338 |
+
output = []
|
| 339 |
+
for char in text:
|
| 340 |
+
cat = unicodedata.category(char)
|
| 341 |
+
if cat == "Mn":
|
| 342 |
+
continue
|
| 343 |
+
output.append(char)
|
| 344 |
+
return "".join(output)
|
| 345 |
+
|
| 346 |
+
def _run_split_on_punc(self, text, never_split=None):
|
| 347 |
+
"""Splits punctuation on a piece of text."""
|
| 348 |
+
if not self.do_split_on_punc or (never_split is not None and text in never_split):
|
| 349 |
+
return [text]
|
| 350 |
+
chars = list(text)
|
| 351 |
+
i = 0
|
| 352 |
+
start_new_word = True
|
| 353 |
+
output = []
|
| 354 |
+
while i < len(chars):
|
| 355 |
+
char = chars[i]
|
| 356 |
+
if _is_punctuation(char):
|
| 357 |
+
output.append([char])
|
| 358 |
+
start_new_word = True
|
| 359 |
+
else:
|
| 360 |
+
if start_new_word:
|
| 361 |
+
output.append([])
|
| 362 |
+
start_new_word = False
|
| 363 |
+
output[-1].append(char)
|
| 364 |
+
i += 1
|
| 365 |
+
|
| 366 |
+
return ["".join(x) for x in output]
|
| 367 |
+
|
| 368 |
+
def _tokenize_chinese_chars(self, text):
|
| 369 |
+
"""Adds whitespace around any CJK character."""
|
| 370 |
+
output = []
|
| 371 |
+
for char in text:
|
| 372 |
+
cp = ord(char)
|
| 373 |
+
if self._is_chinese_char(cp):
|
| 374 |
+
output.append(" ")
|
| 375 |
+
output.append(char)
|
| 376 |
+
output.append(" ")
|
| 377 |
+
else:
|
| 378 |
+
output.append(char)
|
| 379 |
+
return "".join(output)
|
| 380 |
+
|
| 381 |
+
def _is_chinese_char(self, cp):
|
| 382 |
+
"""Checks whether CP is the codepoint of a CJK character."""
|
| 383 |
+
# This defines a "chinese character" as anything in the CJK Unicode block:
|
| 384 |
+
# https://en.wikipedia.org/wiki/CJK_Unified_Ideographs_(Unicode_block)
|
| 385 |
+
#
|
| 386 |
+
# Note that the CJK Unicode block is NOT all Japanese and Korean characters,
|
| 387 |
+
# despite its name. The modern Korean Hangul alphabet is a different block,
|
| 388 |
+
# as is Japanese Hiragana and Katakana. Those alphabets are used to write
|
| 389 |
+
# space-separated words, so they are not treated specially and handled
|
| 390 |
+
# like the all of the other languages.
|
| 391 |
+
if (
|
| 392 |
+
(cp >= 0x4E00 and cp <= 0x9FFF)
|
| 393 |
+
or (cp >= 0x3400 and cp <= 0x4DBF)
|
| 394 |
+
or (cp >= 0x20000 and cp <= 0x2A6DF)
|
| 395 |
+
or (cp >= 0x2A700 and cp <= 0x2B73F)
|
| 396 |
+
or (cp >= 0x2B740 and cp <= 0x2B81F)
|
| 397 |
+
or (cp >= 0x2B820 and cp <= 0x2CEAF)
|
| 398 |
+
or (cp >= 0xF900 and cp <= 0xFAFF)
|
| 399 |
+
or (cp >= 0x2F800 and cp <= 0x2FA1F)
|
| 400 |
+
):
|
| 401 |
+
return True
|
| 402 |
+
|
| 403 |
+
return False
|
| 404 |
+
|
| 405 |
+
def _clean_text(self, text):
|
| 406 |
+
"""Performs invalid character removal and whitespace cleanup on text."""
|
| 407 |
+
output = []
|
| 408 |
+
for char in text:
|
| 409 |
+
cp = ord(char)
|
| 410 |
+
if cp == 0 or cp == 0xFFFD or _is_control(char):
|
| 411 |
+
continue
|
| 412 |
+
if _is_whitespace(char):
|
| 413 |
+
output.append(" ")
|
| 414 |
+
else:
|
| 415 |
+
output.append(char)
|
| 416 |
+
return "".join(output)
|
| 417 |
+
|
| 418 |
+
|
| 419 |
+
class WordpieceTokenizer:
|
| 420 |
+
"""Runs WordPiece tokenization."""
|
| 421 |
+
|
| 422 |
+
def __init__(self, vocab, unk_token, max_input_chars_per_word=100):
|
| 423 |
+
self.vocab = vocab
|
| 424 |
+
self.unk_token = unk_token
|
| 425 |
+
self.max_input_chars_per_word = max_input_chars_per_word
|
| 426 |
+
|
| 427 |
+
def tokenize(self, text):
|
| 428 |
+
"""
|
| 429 |
+
Tokenizes a piece of text into its word pieces. This uses a greedy longest-match-first algorithm to perform
|
| 430 |
+
tokenization using the given vocabulary.
|
| 431 |
+
|
| 432 |
+
For example, `input = "unaffable"` will return as output `["un", "##aff", "##able"]`.
|
| 433 |
+
|
| 434 |
+
Args:
|
| 435 |
+
text: A single token or whitespace separated tokens. This should have
|
| 436 |
+
already been passed through *BasicTokenizer*.
|
| 437 |
+
|
| 438 |
+
Returns:
|
| 439 |
+
A list of wordpiece tokens.
|
| 440 |
+
"""
|
| 441 |
+
|
| 442 |
+
output_tokens = []
|
| 443 |
+
for token in whitespace_tokenize(text):
|
| 444 |
+
chars = list(token)
|
| 445 |
+
if len(chars) > self.max_input_chars_per_word:
|
| 446 |
+
output_tokens.append(self.unk_token)
|
| 447 |
+
continue
|
| 448 |
+
|
| 449 |
+
is_bad = False
|
| 450 |
+
start = 0
|
| 451 |
+
sub_tokens = []
|
| 452 |
+
while start < len(chars):
|
| 453 |
+
end = len(chars)
|
| 454 |
+
cur_substr = None
|
| 455 |
+
while start < end:
|
| 456 |
+
substr = "".join(chars[start:end])
|
| 457 |
+
if start > 0:
|
| 458 |
+
substr = "##" + substr
|
| 459 |
+
if substr in self.vocab:
|
| 460 |
+
cur_substr = substr
|
| 461 |
+
break
|
| 462 |
+
end -= 1
|
| 463 |
+
if cur_substr is None:
|
| 464 |
+
is_bad = True
|
| 465 |
+
break
|
| 466 |
+
sub_tokens.append(cur_substr)
|
| 467 |
+
start = end
|
| 468 |
+
|
| 469 |
+
if is_bad:
|
| 470 |
+
output_tokens.append(self.unk_token)
|
| 471 |
+
else:
|
| 472 |
+
output_tokens.extend(sub_tokens)
|
| 473 |
+
return output_tokens
|
| 474 |
+
|
| 475 |
+
|
| 476 |
+
__all__ = ["BasicTokenizer", "BertTokenizerLegacy", "WordpieceTokenizer"]
|
LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/transformers/models/qwen3_vl/__init__.py
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2025 The Qwen Team and The HuggingFace Inc. team. All rights reserved.
|
| 2 |
+
#
|
| 3 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 4 |
+
# you may not use this file except in compliance with the License.
|
| 5 |
+
# You may obtain a copy of the License at
|
| 6 |
+
#
|
| 7 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 8 |
+
#
|
| 9 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 10 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 11 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 12 |
+
# See the License for the specific language governing permissions and
|
| 13 |
+
# limitations under the License.
|
| 14 |
+
from typing import TYPE_CHECKING
|
| 15 |
+
|
| 16 |
+
from ...utils import _LazyModule
|
| 17 |
+
from ...utils.import_utils import define_import_structure
|
| 18 |
+
|
| 19 |
+
|
| 20 |
+
if TYPE_CHECKING:
|
| 21 |
+
from .configuration_qwen3_vl import *
|
| 22 |
+
from .modeling_qwen3_vl import *
|
| 23 |
+
from .processing_qwen3_vl import *
|
| 24 |
+
from .video_processing_qwen3_vl import *
|
| 25 |
+
else:
|
| 26 |
+
import sys
|
| 27 |
+
|
| 28 |
+
_file = globals()["__file__"]
|
| 29 |
+
sys.modules[__name__] = _LazyModule(__name__, _file, define_import_structure(_file), module_spec=__spec__)
|
LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/transformers/models/qwen3_vl/configuration_qwen3_vl.py
ADDED
|
@@ -0,0 +1,150 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨
|
| 2 |
+
# This file was automatically generated from src/transformers/models/qwen3_vl/modular_qwen3_vl.py.
|
| 3 |
+
# Do NOT edit this file manually as any edits will be overwritten by the generation of
|
| 4 |
+
# the file from the modular. If any change should be done, please apply the change to the
|
| 5 |
+
# modular_qwen3_vl.py file directly. One of our CI enforces this.
|
| 6 |
+
# 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨
|
| 7 |
+
# Copyright 2025 The Qwen Team and The HuggingFace Inc. team. All rights reserved.
|
| 8 |
+
#
|
| 9 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 10 |
+
# you may not use this file except in compliance with the License.
|
| 11 |
+
# You may obtain a copy of the License at
|
| 12 |
+
#
|
| 13 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 14 |
+
#
|
| 15 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 16 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 17 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 18 |
+
# See the License for the specific language governing permissions and
|
| 19 |
+
# limitations under the License.
|
| 20 |
+
from huggingface_hub.dataclasses import strict
|
| 21 |
+
|
| 22 |
+
from ...configuration_utils import PreTrainedConfig
|
| 23 |
+
from ...modeling_rope_utils import RopeParameters
|
| 24 |
+
from ...utils import auto_docstring
|
| 25 |
+
|
| 26 |
+
|
| 27 |
+
@auto_docstring(checkpoint="Qwen/Qwen3-VL-4B-Instruct")
|
| 28 |
+
@strict
|
| 29 |
+
class Qwen3VLVisionConfig(PreTrainedConfig):
|
| 30 |
+
r"""
|
| 31 |
+
out_hidden_size (`int`, *optional*, defaults to 3584):
|
| 32 |
+
The output hidden size of the vision model.
|
| 33 |
+
num_position_embeddings (`int`, *optional*, defaults to 2304):
|
| 34 |
+
The maximum sequence length that this model might ever be used with
|
| 35 |
+
deepstack_visual_indexes (`list[int]`, *optional*, defaults to `[8, 16, 24]`):
|
| 36 |
+
Indexed of layers for deepstack embeddings.
|
| 37 |
+
"""
|
| 38 |
+
|
| 39 |
+
model_type = "qwen3_vl_vision"
|
| 40 |
+
base_config_key = "vision_config"
|
| 41 |
+
|
| 42 |
+
depth: int = 27
|
| 43 |
+
hidden_size: int = 1152
|
| 44 |
+
hidden_act: str = "gelu_pytorch_tanh"
|
| 45 |
+
intermediate_size: int = 4304
|
| 46 |
+
num_heads: int = 16
|
| 47 |
+
in_channels: int = 3
|
| 48 |
+
patch_size: int | list[int] | tuple[int, int] = 16
|
| 49 |
+
spatial_merge_size: int = 2
|
| 50 |
+
temporal_patch_size: int | list[int] | tuple[int, int] = 2
|
| 51 |
+
out_hidden_size: int = 3584
|
| 52 |
+
num_position_embeddings: int = 2304
|
| 53 |
+
deepstack_visual_indexes: list[int] | tuple[int, ...] = (8, 16, 24)
|
| 54 |
+
initializer_range: float = 0.02
|
| 55 |
+
|
| 56 |
+
|
| 57 |
+
@auto_docstring(checkpoint="Qwen/Qwen3-VL-4B-Instruct")
|
| 58 |
+
@strict
|
| 59 |
+
class Qwen3VLTextConfig(PreTrainedConfig):
|
| 60 |
+
r"""
|
| 61 |
+
Example:
|
| 62 |
+
|
| 63 |
+
```python
|
| 64 |
+
>>> from transformers import Qwen3VLTextModel, Qwen3VLTextConfig
|
| 65 |
+
|
| 66 |
+
>>> # Initializing a Qwen3VL style configuration
|
| 67 |
+
>>> configuration = Qwen3VLTextConfig()
|
| 68 |
+
|
| 69 |
+
>>> # Initializing a model from the Qwen3-VL-7B style configuration
|
| 70 |
+
>>> model = Qwen3VLTextModel(configuration)
|
| 71 |
+
|
| 72 |
+
>>> # Accessing the model configuration
|
| 73 |
+
>>> configuration = model.config
|
| 74 |
+
```"""
|
| 75 |
+
|
| 76 |
+
model_type = "qwen3_vl_text"
|
| 77 |
+
base_config_key = "text_config"
|
| 78 |
+
default_theta = 500000.0
|
| 79 |
+
ignore_keys_at_rope_validation = {"mrope_section", "mrope_interleaved"}
|
| 80 |
+
|
| 81 |
+
vocab_size: int = 151936
|
| 82 |
+
hidden_size: int = 4096
|
| 83 |
+
intermediate_size: int = 22016
|
| 84 |
+
num_hidden_layers: int = 32
|
| 85 |
+
num_attention_heads: int = 32
|
| 86 |
+
num_key_value_heads: int | None = 32
|
| 87 |
+
head_dim: int = 128
|
| 88 |
+
hidden_act: str = "silu"
|
| 89 |
+
max_position_embeddings: int = 128000
|
| 90 |
+
initializer_range: float = 0.02
|
| 91 |
+
rms_norm_eps: float = 1e-6
|
| 92 |
+
use_cache: bool = True
|
| 93 |
+
rope_parameters: RopeParameters | dict | None = None
|
| 94 |
+
attention_bias: bool = False
|
| 95 |
+
attention_dropout: float | int = 0.0
|
| 96 |
+
pad_token_id: int | None = None
|
| 97 |
+
|
| 98 |
+
def __post_init__(self, **kwargs):
|
| 99 |
+
if self.num_key_value_heads is None:
|
| 100 |
+
self.num_key_value_heads = self.num_attention_heads
|
| 101 |
+
|
| 102 |
+
super().__post_init__(**kwargs)
|
| 103 |
+
|
| 104 |
+
|
| 105 |
+
@auto_docstring(checkpoint="Qwen/Qwen3-VL-4B-Instruct")
|
| 106 |
+
@strict
|
| 107 |
+
class Qwen3VLConfig(PreTrainedConfig):
|
| 108 |
+
r"""
|
| 109 |
+
Example:
|
| 110 |
+
|
| 111 |
+
```python
|
| 112 |
+
>>> from transformers import Qwen3VLForConditionalGeneration, Qwen3VLConfig
|
| 113 |
+
|
| 114 |
+
>>> # Initializing a Qwen3-VL style configuration
|
| 115 |
+
>>> configuration = Qwen3VLConfig()
|
| 116 |
+
|
| 117 |
+
>>> # Initializing a model from the Qwen3-VL-4B style configuration
|
| 118 |
+
>>> model = Qwen3VLForConditionalGeneration(configuration)
|
| 119 |
+
|
| 120 |
+
>>> # Accessing the model configuration
|
| 121 |
+
>>> configuration = model.config
|
| 122 |
+
```"""
|
| 123 |
+
|
| 124 |
+
model_type = "qwen3_vl"
|
| 125 |
+
sub_configs = {"vision_config": Qwen3VLVisionConfig, "text_config": Qwen3VLTextConfig}
|
| 126 |
+
keys_to_ignore_at_inference = ["past_key_values"]
|
| 127 |
+
|
| 128 |
+
text_config: dict | PreTrainedConfig | None = None
|
| 129 |
+
vision_config: dict | PreTrainedConfig | None = None
|
| 130 |
+
image_token_id: int = 151655
|
| 131 |
+
video_token_id: int = 151656
|
| 132 |
+
vision_start_token_id: int = 151652
|
| 133 |
+
vision_end_token_id: int = 151653
|
| 134 |
+
tie_word_embeddings: bool = False
|
| 135 |
+
|
| 136 |
+
def __post_init__(self, **kwargs):
|
| 137 |
+
if isinstance(self.vision_config, dict):
|
| 138 |
+
self.vision_config = self.sub_configs["vision_config"](**self.vision_config)
|
| 139 |
+
elif self.vision_config is None:
|
| 140 |
+
self.vision_config = self.sub_configs["vision_config"]()
|
| 141 |
+
|
| 142 |
+
if isinstance(self.text_config, dict):
|
| 143 |
+
self.text_config = self.sub_configs["text_config"](**self.text_config)
|
| 144 |
+
elif self.text_config is None:
|
| 145 |
+
self.text_config = self.sub_configs["text_config"]()
|
| 146 |
+
|
| 147 |
+
super().__post_init__(**kwargs)
|
| 148 |
+
|
| 149 |
+
|
| 150 |
+
__all__ = ["Qwen3VLConfig", "Qwen3VLTextConfig", "Qwen3VLVisionConfig"]
|
LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/transformers/models/qwen3_vl/modeling_qwen3_vl.py
ADDED
|
@@ -0,0 +1,1683 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨
|
| 2 |
+
# This file was automatically generated from src/transformers/models/qwen3_vl/modular_qwen3_vl.py.
|
| 3 |
+
# Do NOT edit this file manually as any edits will be overwritten by the generation of
|
| 4 |
+
# the file from the modular. If any change should be done, please apply the change to the
|
| 5 |
+
# modular_qwen3_vl.py file directly. One of our CI enforces this.
|
| 6 |
+
# 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨
|
| 7 |
+
# Copyright 2025 The Qwen Team and The HuggingFace Inc. team. All rights reserved.
|
| 8 |
+
#
|
| 9 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 10 |
+
# you may not use this file except in compliance with the License.
|
| 11 |
+
# You may obtain a copy of the License at
|
| 12 |
+
#
|
| 13 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 14 |
+
#
|
| 15 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 16 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 17 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 18 |
+
# See the License for the specific language governing permissions and
|
| 19 |
+
# limitations under the License.
|
| 20 |
+
|
| 21 |
+
import itertools
|
| 22 |
+
import warnings
|
| 23 |
+
from collections.abc import Callable
|
| 24 |
+
from dataclasses import dataclass
|
| 25 |
+
from typing import Any, Optional
|
| 26 |
+
|
| 27 |
+
import torch
|
| 28 |
+
import torch.nn as nn
|
| 29 |
+
|
| 30 |
+
from ... import initialization as init
|
| 31 |
+
from ...activations import ACT2FN
|
| 32 |
+
from ...cache_utils import Cache, DynamicCache
|
| 33 |
+
from ...generation import GenerationMixin
|
| 34 |
+
from ...integrations import use_kernel_forward_from_hub, use_kernel_func_from_hub, use_kernelized_func
|
| 35 |
+
from ...masking_utils import create_causal_mask
|
| 36 |
+
from ...modeling_flash_attention_utils import FlashAttentionKwargs
|
| 37 |
+
from ...modeling_layers import GradientCheckpointingLayer
|
| 38 |
+
from ...modeling_outputs import BaseModelOutputWithPast, BaseModelOutputWithPooling, ModelOutput
|
| 39 |
+
from ...modeling_rope_utils import ROPE_INIT_FUNCTIONS, dynamic_rope_update
|
| 40 |
+
from ...modeling_utils import ALL_ATTENTION_FUNCTIONS, PreTrainedModel
|
| 41 |
+
from ...processing_utils import Unpack
|
| 42 |
+
from ...utils import TransformersKwargs, auto_docstring, can_return_tuple, torch_compilable_check
|
| 43 |
+
from ...utils.generic import (
|
| 44 |
+
accepts_precomputed_kwargs,
|
| 45 |
+
is_flash_attention_requested,
|
| 46 |
+
maybe_autocast,
|
| 47 |
+
merge_with_config_defaults,
|
| 48 |
+
)
|
| 49 |
+
from ...utils.output_capturing import capture_outputs
|
| 50 |
+
from ...vision_utils import get_vision_bilinear_indices_and_weights, get_vision_cu_seqlens, get_vision_position_ids
|
| 51 |
+
from .configuration_qwen3_vl import Qwen3VLConfig, Qwen3VLTextConfig, Qwen3VLVisionConfig
|
| 52 |
+
|
| 53 |
+
|
| 54 |
+
@auto_docstring
|
| 55 |
+
@dataclass
|
| 56 |
+
class BaseModelOutputWithDeepstackFeatures(BaseModelOutputWithPooling):
|
| 57 |
+
r"""
|
| 58 |
+
deepstack_features (`List[torch.FloatTensor]`, *optional*):
|
| 59 |
+
List of hidden-states (feature maps) from deepstack layers.
|
| 60 |
+
"""
|
| 61 |
+
|
| 62 |
+
deepstack_features: list[torch.FloatTensor] | None = None
|
| 63 |
+
|
| 64 |
+
|
| 65 |
+
class Qwen3VLVisionMLP(nn.Module):
|
| 66 |
+
def __init__(self, config):
|
| 67 |
+
super().__init__()
|
| 68 |
+
self.hidden_size = config.hidden_size
|
| 69 |
+
self.intermediate_size = config.intermediate_size
|
| 70 |
+
self.linear_fc1 = nn.Linear(self.hidden_size, self.intermediate_size, bias=True)
|
| 71 |
+
self.linear_fc2 = nn.Linear(self.intermediate_size, self.hidden_size, bias=True)
|
| 72 |
+
self.act_fn = ACT2FN[config.hidden_act]
|
| 73 |
+
|
| 74 |
+
def forward(self, hidden_state):
|
| 75 |
+
return self.linear_fc2(self.act_fn(self.linear_fc1(hidden_state)))
|
| 76 |
+
|
| 77 |
+
|
| 78 |
+
class Qwen3VLVisionPatchEmbed(nn.Module):
|
| 79 |
+
def __init__(self, config) -> None:
|
| 80 |
+
super().__init__()
|
| 81 |
+
self.patch_size = config.patch_size
|
| 82 |
+
self.temporal_patch_size = config.temporal_patch_size
|
| 83 |
+
self.in_channels = config.in_channels
|
| 84 |
+
self.embed_dim = config.hidden_size
|
| 85 |
+
|
| 86 |
+
kernel_size = [self.temporal_patch_size, self.patch_size, self.patch_size]
|
| 87 |
+
self.proj = nn.Conv3d(self.in_channels, self.embed_dim, kernel_size=kernel_size, stride=kernel_size, bias=True)
|
| 88 |
+
|
| 89 |
+
def forward(self, hidden_states: torch.Tensor) -> torch.Tensor:
|
| 90 |
+
target_dtype = self.proj.weight.dtype
|
| 91 |
+
hidden_states = hidden_states.view(
|
| 92 |
+
-1, self.in_channels, self.temporal_patch_size, self.patch_size, self.patch_size
|
| 93 |
+
)
|
| 94 |
+
hidden_states = self.proj(hidden_states.to(dtype=target_dtype)).view(-1, self.embed_dim)
|
| 95 |
+
return hidden_states
|
| 96 |
+
|
| 97 |
+
|
| 98 |
+
class Qwen3VLVisionRotaryEmbedding(nn.Module):
|
| 99 |
+
inv_freq: torch.Tensor # fix linting for `register_buffer`
|
| 100 |
+
|
| 101 |
+
def __init__(self, dim: int, theta: float = 10000.0) -> None:
|
| 102 |
+
super().__init__()
|
| 103 |
+
self.dim = dim
|
| 104 |
+
self.theta = theta
|
| 105 |
+
inv_freq = 1.0 / (theta ** (torch.arange(0, dim, 2, dtype=torch.float) / dim))
|
| 106 |
+
self.register_buffer("inv_freq", inv_freq, persistent=False)
|
| 107 |
+
|
| 108 |
+
def forward(self, position_ids: torch.Tensor) -> torch.Tensor:
|
| 109 |
+
return (position_ids.unsqueeze(-1) * self.inv_freq).flatten(1)
|
| 110 |
+
|
| 111 |
+
|
| 112 |
+
class Qwen3VLVisionPatchMerger(nn.Module):
|
| 113 |
+
def __init__(self, config: Qwen3VLVisionConfig, use_postshuffle_norm=False) -> None:
|
| 114 |
+
super().__init__()
|
| 115 |
+
self.hidden_size = config.hidden_size * (config.spatial_merge_size**2)
|
| 116 |
+
self.use_postshuffle_norm = use_postshuffle_norm
|
| 117 |
+
self.norm = nn.LayerNorm(self.hidden_size if use_postshuffle_norm else config.hidden_size, eps=1e-6)
|
| 118 |
+
self.linear_fc1 = nn.Linear(self.hidden_size, self.hidden_size)
|
| 119 |
+
self.act_fn = nn.GELU()
|
| 120 |
+
self.linear_fc2 = nn.Linear(self.hidden_size, config.out_hidden_size)
|
| 121 |
+
|
| 122 |
+
def forward(self, x: torch.Tensor) -> torch.Tensor:
|
| 123 |
+
x = self.norm(x.view(-1, self.hidden_size) if self.use_postshuffle_norm else x).view(-1, self.hidden_size)
|
| 124 |
+
x = self.linear_fc2(self.act_fn(self.linear_fc1(x)))
|
| 125 |
+
return x
|
| 126 |
+
|
| 127 |
+
|
| 128 |
+
def rotate_half(x):
|
| 129 |
+
"""Rotates half the hidden dims of the input."""
|
| 130 |
+
x1 = x[..., : x.shape[-1] // 2]
|
| 131 |
+
x2 = x[..., x.shape[-1] // 2 :]
|
| 132 |
+
return torch.cat((-x2, x1), dim=-1)
|
| 133 |
+
|
| 134 |
+
|
| 135 |
+
def apply_rotary_pos_emb_vision(
|
| 136 |
+
q: torch.Tensor, k: torch.Tensor, cos: torch.Tensor, sin: torch.Tensor
|
| 137 |
+
) -> tuple[torch.Tensor, torch.Tensor]:
|
| 138 |
+
orig_q_dtype = q.dtype
|
| 139 |
+
orig_k_dtype = k.dtype
|
| 140 |
+
q, k = q.float(), k.float()
|
| 141 |
+
cos, sin = cos.unsqueeze(-2).float(), sin.unsqueeze(-2).float()
|
| 142 |
+
q_embed = (q * cos) + (rotate_half(q) * sin)
|
| 143 |
+
k_embed = (k * cos) + (rotate_half(k) * sin)
|
| 144 |
+
q_embed = q_embed.to(orig_q_dtype)
|
| 145 |
+
k_embed = k_embed.to(orig_k_dtype)
|
| 146 |
+
return q_embed, k_embed
|
| 147 |
+
|
| 148 |
+
|
| 149 |
+
def repeat_kv(hidden_states: torch.Tensor, n_rep: int) -> torch.Tensor:
|
| 150 |
+
"""
|
| 151 |
+
This is the equivalent of torch.repeat_interleave(x, dim=1, repeats=n_rep). The hidden states go from (batch,
|
| 152 |
+
num_key_value_heads, seqlen, head_dim) to (batch, num_attention_heads, seqlen, head_dim)
|
| 153 |
+
"""
|
| 154 |
+
batch, num_key_value_heads, slen, head_dim = hidden_states.shape
|
| 155 |
+
if n_rep == 1:
|
| 156 |
+
return hidden_states
|
| 157 |
+
hidden_states = hidden_states[:, :, None, :, :].expand(batch, num_key_value_heads, n_rep, slen, head_dim)
|
| 158 |
+
return hidden_states.reshape(batch, num_key_value_heads * n_rep, slen, head_dim)
|
| 159 |
+
|
| 160 |
+
|
| 161 |
+
def eager_attention_forward(
|
| 162 |
+
module: nn.Module,
|
| 163 |
+
query: torch.Tensor,
|
| 164 |
+
key: torch.Tensor,
|
| 165 |
+
value: torch.Tensor,
|
| 166 |
+
attention_mask: torch.Tensor | None,
|
| 167 |
+
scaling: float,
|
| 168 |
+
dropout: float = 0.0,
|
| 169 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 170 |
+
):
|
| 171 |
+
key_states = repeat_kv(key, module.num_key_value_groups)
|
| 172 |
+
value_states = repeat_kv(value, module.num_key_value_groups)
|
| 173 |
+
|
| 174 |
+
attn_weights = torch.matmul(query, key_states.transpose(2, 3)) * scaling
|
| 175 |
+
if attention_mask is not None:
|
| 176 |
+
attn_weights = attn_weights + attention_mask
|
| 177 |
+
|
| 178 |
+
attn_weights = nn.functional.softmax(attn_weights, dim=-1, dtype=torch.float32).to(query.dtype)
|
| 179 |
+
attn_weights = nn.functional.dropout(attn_weights, p=dropout, training=module.training)
|
| 180 |
+
attn_output = torch.matmul(attn_weights, value_states)
|
| 181 |
+
attn_output = attn_output.transpose(1, 2).contiguous()
|
| 182 |
+
|
| 183 |
+
return attn_output, attn_weights
|
| 184 |
+
|
| 185 |
+
|
| 186 |
+
class Qwen3VLVisionAttention(nn.Module):
|
| 187 |
+
def __init__(self, config: Qwen3VLVisionConfig) -> None:
|
| 188 |
+
super().__init__()
|
| 189 |
+
self.dim = config.hidden_size
|
| 190 |
+
self.num_heads = config.num_heads
|
| 191 |
+
self.head_dim = self.dim // self.num_heads
|
| 192 |
+
self.num_key_value_groups = 1 # needed for eager attention
|
| 193 |
+
self.qkv = nn.Linear(self.dim, self.dim * 3, bias=True)
|
| 194 |
+
self.proj = nn.Linear(self.dim, self.dim)
|
| 195 |
+
self.scaling = self.head_dim**-0.5
|
| 196 |
+
self.config = config
|
| 197 |
+
self.attention_dropout = 0.0
|
| 198 |
+
self.is_causal = False
|
| 199 |
+
|
| 200 |
+
def forward(
|
| 201 |
+
self,
|
| 202 |
+
hidden_states: torch.Tensor,
|
| 203 |
+
cu_seqlens: torch.Tensor,
|
| 204 |
+
rotary_pos_emb: torch.Tensor | None = None,
|
| 205 |
+
position_embeddings: tuple[torch.Tensor, torch.Tensor] | None = None,
|
| 206 |
+
**kwargs,
|
| 207 |
+
) -> torch.Tensor:
|
| 208 |
+
seq_length = hidden_states.shape[0]
|
| 209 |
+
query_states, key_states, value_states = (
|
| 210 |
+
self.qkv(hidden_states).reshape(seq_length, 3, self.num_heads, -1).permute(1, 0, 2, 3).unbind(0)
|
| 211 |
+
)
|
| 212 |
+
cos, sin = position_embeddings
|
| 213 |
+
query_states, key_states = apply_rotary_pos_emb_vision(query_states, key_states, cos, sin)
|
| 214 |
+
|
| 215 |
+
query_states = query_states.transpose(0, 1).unsqueeze(0)
|
| 216 |
+
key_states = key_states.transpose(0, 1).unsqueeze(0)
|
| 217 |
+
value_states = value_states.transpose(0, 1).unsqueeze(0)
|
| 218 |
+
|
| 219 |
+
attention_interface: Callable = ALL_ATTENTION_FUNCTIONS.get_interface(
|
| 220 |
+
self.config._attn_implementation, eager_attention_forward
|
| 221 |
+
)
|
| 222 |
+
|
| 223 |
+
if is_flash_attention_requested(self.config):
|
| 224 |
+
# Flash Attention: Use cu_seqlens for variable length attention
|
| 225 |
+
max_seqlen = (cu_seqlens[1:] - cu_seqlens[:-1]).max()
|
| 226 |
+
attn_output, _ = attention_interface(
|
| 227 |
+
self,
|
| 228 |
+
query_states,
|
| 229 |
+
key_states,
|
| 230 |
+
value_states,
|
| 231 |
+
attention_mask=None,
|
| 232 |
+
scaling=self.scaling,
|
| 233 |
+
dropout=0.0 if not self.training else self.attention_dropout,
|
| 234 |
+
cu_seq_lens_q=cu_seqlens,
|
| 235 |
+
cu_seq_lens_k=cu_seqlens,
|
| 236 |
+
max_length_q=max_seqlen,
|
| 237 |
+
max_length_k=max_seqlen,
|
| 238 |
+
is_causal=False,
|
| 239 |
+
**kwargs,
|
| 240 |
+
)
|
| 241 |
+
else:
|
| 242 |
+
# Other implementations: Process each chunk separately
|
| 243 |
+
lengths = cu_seqlens[1:] - cu_seqlens[:-1]
|
| 244 |
+
splits = [
|
| 245 |
+
torch.split(tensor, lengths.tolist(), dim=2) for tensor in (query_states, key_states, value_states)
|
| 246 |
+
]
|
| 247 |
+
|
| 248 |
+
attn_outputs = [
|
| 249 |
+
attention_interface(
|
| 250 |
+
self,
|
| 251 |
+
q,
|
| 252 |
+
k,
|
| 253 |
+
v,
|
| 254 |
+
attention_mask=None,
|
| 255 |
+
scaling=self.scaling,
|
| 256 |
+
dropout=0.0 if not self.training else self.attention_dropout,
|
| 257 |
+
is_causal=False,
|
| 258 |
+
**kwargs,
|
| 259 |
+
)[0]
|
| 260 |
+
for q, k, v in zip(*splits)
|
| 261 |
+
]
|
| 262 |
+
attn_output = torch.cat(attn_outputs, dim=1)
|
| 263 |
+
|
| 264 |
+
attn_output = attn_output.reshape(seq_length, -1).contiguous()
|
| 265 |
+
attn_output = self.proj(attn_output)
|
| 266 |
+
return attn_output
|
| 267 |
+
|
| 268 |
+
|
| 269 |
+
class Qwen3VLVisionBlock(GradientCheckpointingLayer):
|
| 270 |
+
def __init__(self, config, attn_implementation: str = "sdpa") -> None:
|
| 271 |
+
super().__init__()
|
| 272 |
+
self.norm1 = nn.LayerNorm(config.hidden_size, eps=1e-6)
|
| 273 |
+
self.norm2 = nn.LayerNorm(config.hidden_size, eps=1e-6)
|
| 274 |
+
self.attn = Qwen3VLVisionAttention(config=config)
|
| 275 |
+
self.mlp = Qwen3VLVisionMLP(config=config)
|
| 276 |
+
|
| 277 |
+
@auto_docstring
|
| 278 |
+
def forward(
|
| 279 |
+
self,
|
| 280 |
+
hidden_states: torch.Tensor,
|
| 281 |
+
cu_seqlens: torch.Tensor,
|
| 282 |
+
rotary_pos_emb: torch.Tensor | None = None,
|
| 283 |
+
position_embeddings: tuple[torch.Tensor, torch.Tensor] | None = None,
|
| 284 |
+
**kwargs,
|
| 285 |
+
) -> torch.Tensor:
|
| 286 |
+
r"""
|
| 287 |
+
cu_seqlens (`torch.Tensor`):
|
| 288 |
+
Cumulative sequence lengths used for packed variable-length attention in Flash Attention kernels.
|
| 289 |
+
rotary_pos_emb (`torch.Tensor`, *optional*):
|
| 290 |
+
Precomputed rotary positional embeddings applied to the vision attention query/key states.
|
| 291 |
+
"""
|
| 292 |
+
hidden_states = hidden_states + self.attn(
|
| 293 |
+
self.norm1(hidden_states),
|
| 294 |
+
cu_seqlens=cu_seqlens,
|
| 295 |
+
rotary_pos_emb=rotary_pos_emb,
|
| 296 |
+
position_embeddings=position_embeddings,
|
| 297 |
+
**kwargs,
|
| 298 |
+
)
|
| 299 |
+
hidden_states = hidden_states + self.mlp(self.norm2(hidden_states))
|
| 300 |
+
return hidden_states
|
| 301 |
+
|
| 302 |
+
|
| 303 |
+
class Qwen3VLTextRotaryEmbedding(nn.Module):
|
| 304 |
+
inv_freq: torch.Tensor # fix linting for `register_buffer`
|
| 305 |
+
|
| 306 |
+
def __init__(self, config: Qwen3VLTextConfig, device=None):
|
| 307 |
+
super().__init__()
|
| 308 |
+
self.max_seq_len_cached = config.max_position_embeddings
|
| 309 |
+
self.original_max_seq_len = config.max_position_embeddings
|
| 310 |
+
|
| 311 |
+
self.config = config
|
| 312 |
+
|
| 313 |
+
self.rope_type = self.config.rope_parameters["rope_type"]
|
| 314 |
+
rope_init_fn: Callable = self.compute_default_rope_parameters
|
| 315 |
+
if self.rope_type != "default":
|
| 316 |
+
rope_init_fn = ROPE_INIT_FUNCTIONS[self.rope_type]
|
| 317 |
+
inv_freq, self.attention_scaling = rope_init_fn(self.config, device)
|
| 318 |
+
|
| 319 |
+
self.register_buffer("inv_freq", inv_freq, persistent=False)
|
| 320 |
+
self.register_buffer("original_inv_freq", inv_freq.clone(), persistent=False)
|
| 321 |
+
|
| 322 |
+
self.mrope_section = config.rope_parameters.get("mrope_section", [24, 20, 20])
|
| 323 |
+
|
| 324 |
+
@staticmethod
|
| 325 |
+
def compute_default_rope_parameters(
|
| 326 |
+
config: Qwen3VLTextConfig | None = None,
|
| 327 |
+
device: Optional["torch.device"] = None,
|
| 328 |
+
seq_len: int | None = None,
|
| 329 |
+
) -> tuple["torch.Tensor", float]:
|
| 330 |
+
"""
|
| 331 |
+
Computes the inverse frequencies according to the original RoPE implementation
|
| 332 |
+
Args:
|
| 333 |
+
config ([`~transformers.PreTrainedConfig`]):
|
| 334 |
+
The model configuration.
|
| 335 |
+
device (`torch.device`):
|
| 336 |
+
The device to use for initialization of the inverse frequencies.
|
| 337 |
+
seq_len (`int`, *optional*):
|
| 338 |
+
The current sequence length. Unused for this type of RoPE.
|
| 339 |
+
Returns:
|
| 340 |
+
Tuple of (`torch.Tensor`, `float`), containing the inverse frequencies for the RoPE embeddings and the
|
| 341 |
+
post-processing scaling factor applied to the computed cos/sin (unused in this type of RoPE).
|
| 342 |
+
"""
|
| 343 |
+
base = config.rope_parameters["rope_theta"]
|
| 344 |
+
dim = getattr(config, "head_dim", None) or config.hidden_size // config.num_attention_heads
|
| 345 |
+
|
| 346 |
+
attention_factor = 1.0 # Unused in this type of RoPE
|
| 347 |
+
|
| 348 |
+
# Compute the inverse frequencies
|
| 349 |
+
inv_freq = 1.0 / (
|
| 350 |
+
base ** (torch.arange(0, dim, 2, dtype=torch.int64).to(device=device, dtype=torch.float) / dim)
|
| 351 |
+
)
|
| 352 |
+
return inv_freq, attention_factor
|
| 353 |
+
|
| 354 |
+
@torch.no_grad()
|
| 355 |
+
@dynamic_rope_update # power user: used with advanced RoPE types (e.g. dynamic rope)
|
| 356 |
+
def forward(self, x, position_ids):
|
| 357 |
+
# In contrast to other models, Qwen3VL has different position ids for the grids
|
| 358 |
+
# So we expand the inv_freq to shape (3, ...)
|
| 359 |
+
if position_ids.ndim == 2:
|
| 360 |
+
position_ids = position_ids[None, ...].expand(3, position_ids.shape[0], -1)
|
| 361 |
+
inv_freq_expanded = (
|
| 362 |
+
self.inv_freq[None, None, :, None].float().expand(3, position_ids.shape[1], -1, 1).to(x.device)
|
| 363 |
+
)
|
| 364 |
+
position_ids_expanded = position_ids[:, :, None, :].float() # shape (3, bs, 1, positions)
|
| 365 |
+
|
| 366 |
+
device_type = x.device.type if isinstance(x.device.type, str) and x.device.type != "mps" else "cpu"
|
| 367 |
+
with maybe_autocast(device_type=device_type, enabled=False): # Force float32
|
| 368 |
+
freqs = (inv_freq_expanded.float() @ position_ids_expanded.float()).transpose(2, 3)
|
| 369 |
+
freqs = self.apply_interleaved_mrope(freqs, self.mrope_section)
|
| 370 |
+
emb = torch.cat((freqs, freqs), dim=-1)
|
| 371 |
+
cos = emb.cos() * self.attention_scaling
|
| 372 |
+
sin = emb.sin() * self.attention_scaling
|
| 373 |
+
|
| 374 |
+
return cos.to(dtype=x.dtype), sin.to(dtype=x.dtype)
|
| 375 |
+
|
| 376 |
+
def apply_interleaved_mrope(self, freqs, mrope_section):
|
| 377 |
+
"""Apply interleaved MRoPE to 3D rotary embeddings.
|
| 378 |
+
Reorganizes frequency layout from chunked [TTT...HHH...WWW] to
|
| 379 |
+
interleaved [THWTHWTHW...TT], preserving frequency continuity.
|
| 380 |
+
args:
|
| 381 |
+
x: (3, bs, seq_len, head_dim // 2)
|
| 382 |
+
mrope_section: (3,)
|
| 383 |
+
returns:
|
| 384 |
+
x_t: (bs, seq_len, head_dim // 2)
|
| 385 |
+
"""
|
| 386 |
+
freqs_t = freqs[0] # just overwrite the first dimension T
|
| 387 |
+
for dim, offset in enumerate((1, 2), start=1): # H, W
|
| 388 |
+
length = mrope_section[dim] * 3
|
| 389 |
+
idx = slice(offset, length, 3)
|
| 390 |
+
freqs_t[..., idx] = freqs[dim, ..., idx]
|
| 391 |
+
return freqs_t
|
| 392 |
+
|
| 393 |
+
|
| 394 |
+
@use_kernel_forward_from_hub("RMSNorm")
|
| 395 |
+
class Qwen3VLTextRMSNorm(nn.Module):
|
| 396 |
+
def __init__(self, hidden_size, eps: float = 1e-6) -> None:
|
| 397 |
+
"""
|
| 398 |
+
Qwen3VLTextRMSNorm is equivalent to T5LayerNorm
|
| 399 |
+
"""
|
| 400 |
+
super().__init__()
|
| 401 |
+
self.weight = nn.Parameter(torch.ones(hidden_size))
|
| 402 |
+
self.variance_epsilon = eps
|
| 403 |
+
|
| 404 |
+
def forward(self, hidden_states: torch.Tensor) -> torch.Tensor:
|
| 405 |
+
input_dtype = hidden_states.dtype
|
| 406 |
+
hidden_states = hidden_states.to(torch.float32)
|
| 407 |
+
variance = hidden_states.pow(2).mean(-1, keepdim=True)
|
| 408 |
+
hidden_states = hidden_states * torch.rsqrt(variance + self.variance_epsilon)
|
| 409 |
+
return self.weight * hidden_states.to(input_dtype)
|
| 410 |
+
|
| 411 |
+
def extra_repr(self):
|
| 412 |
+
return f"{tuple(self.weight.shape)}, eps={self.variance_epsilon}"
|
| 413 |
+
|
| 414 |
+
|
| 415 |
+
@use_kernel_func_from_hub("rotary_pos_emb")
|
| 416 |
+
def apply_rotary_pos_emb(q, k, cos, sin, unsqueeze_dim=1):
|
| 417 |
+
"""Applies Rotary Position Embedding to the query and key tensors.
|
| 418 |
+
|
| 419 |
+
Args:
|
| 420 |
+
q (`torch.Tensor`): The query tensor.
|
| 421 |
+
k (`torch.Tensor`): The key tensor.
|
| 422 |
+
cos (`torch.Tensor`): The cosine part of the rotary embedding.
|
| 423 |
+
sin (`torch.Tensor`): The sine part of the rotary embedding.
|
| 424 |
+
unsqueeze_dim (`int`, *optional*, defaults to 1):
|
| 425 |
+
The 'unsqueeze_dim' argument specifies the dimension along which to unsqueeze cos[position_ids] and
|
| 426 |
+
sin[position_ids] so that they can be properly broadcasted to the dimensions of q and k. For example, note
|
| 427 |
+
that cos[position_ids] and sin[position_ids] have the shape [batch_size, seq_len, head_dim]. Then, if q and
|
| 428 |
+
k have the shape [batch_size, heads, seq_len, head_dim], then setting unsqueeze_dim=1 makes
|
| 429 |
+
cos[position_ids] and sin[position_ids] broadcastable to the shapes of q and k. Similarly, if q and k have
|
| 430 |
+
the shape [batch_size, seq_len, heads, head_dim], then set unsqueeze_dim=2.
|
| 431 |
+
Returns:
|
| 432 |
+
`tuple(torch.Tensor)` comprising of the query and key tensors rotated using the Rotary Position Embedding.
|
| 433 |
+
"""
|
| 434 |
+
cos = cos.unsqueeze(unsqueeze_dim)
|
| 435 |
+
sin = sin.unsqueeze(unsqueeze_dim)
|
| 436 |
+
q_embed = (q * cos) + (rotate_half(q) * sin)
|
| 437 |
+
k_embed = (k * cos) + (rotate_half(k) * sin)
|
| 438 |
+
return q_embed, k_embed
|
| 439 |
+
|
| 440 |
+
|
| 441 |
+
@use_kernelized_func(apply_rotary_pos_emb)
|
| 442 |
+
class Qwen3VLTextAttention(nn.Module):
|
| 443 |
+
"""Multi-headed attention from 'Attention Is All You Need' paper"""
|
| 444 |
+
|
| 445 |
+
def __init__(self, config: Qwen3VLTextConfig, layer_idx: int):
|
| 446 |
+
super().__init__()
|
| 447 |
+
self.layer_type = config.layer_types[layer_idx] if hasattr(config, "layer_types") else None
|
| 448 |
+
self.config = config
|
| 449 |
+
self.layer_idx = layer_idx
|
| 450 |
+
self.head_dim = getattr(config, "head_dim", config.hidden_size // config.num_attention_heads)
|
| 451 |
+
self.num_key_value_groups = config.num_attention_heads // config.num_key_value_heads
|
| 452 |
+
self.scaling = self.head_dim**-0.5
|
| 453 |
+
self.attention_dropout = config.attention_dropout
|
| 454 |
+
self.is_causal = True
|
| 455 |
+
|
| 456 |
+
self.q_proj = nn.Linear(
|
| 457 |
+
config.hidden_size, config.num_attention_heads * self.head_dim, bias=config.attention_bias
|
| 458 |
+
)
|
| 459 |
+
self.k_proj = nn.Linear(
|
| 460 |
+
config.hidden_size, config.num_key_value_heads * self.head_dim, bias=config.attention_bias
|
| 461 |
+
)
|
| 462 |
+
self.v_proj = nn.Linear(
|
| 463 |
+
config.hidden_size, config.num_key_value_heads * self.head_dim, bias=config.attention_bias
|
| 464 |
+
)
|
| 465 |
+
self.o_proj = nn.Linear(
|
| 466 |
+
config.num_attention_heads * self.head_dim, config.hidden_size, bias=config.attention_bias
|
| 467 |
+
)
|
| 468 |
+
self.q_norm = Qwen3VLTextRMSNorm(self.head_dim, eps=config.rms_norm_eps) # unlike olmo, only on the head dim!
|
| 469 |
+
self.k_norm = Qwen3VLTextRMSNorm(
|
| 470 |
+
self.head_dim, eps=config.rms_norm_eps
|
| 471 |
+
) # thus post q_norm does not need reshape
|
| 472 |
+
|
| 473 |
+
def forward(
|
| 474 |
+
self,
|
| 475 |
+
hidden_states: torch.Tensor,
|
| 476 |
+
position_embeddings: tuple[torch.Tensor, torch.Tensor],
|
| 477 |
+
attention_mask: torch.Tensor | None,
|
| 478 |
+
past_key_values: Cache | None = None,
|
| 479 |
+
**kwargs: Unpack[FlashAttentionKwargs],
|
| 480 |
+
) -> tuple[torch.Tensor, torch.Tensor | None]:
|
| 481 |
+
input_shape = hidden_states.shape[:-1]
|
| 482 |
+
hidden_shape = (*input_shape, -1, self.head_dim)
|
| 483 |
+
|
| 484 |
+
query_states = self.q_norm(self.q_proj(hidden_states).view(hidden_shape)).transpose(1, 2)
|
| 485 |
+
key_states = self.k_norm(self.k_proj(hidden_states).view(hidden_shape)).transpose(1, 2)
|
| 486 |
+
value_states = self.v_proj(hidden_states).view(hidden_shape).transpose(1, 2)
|
| 487 |
+
|
| 488 |
+
cos, sin = position_embeddings
|
| 489 |
+
query_states, key_states = apply_rotary_pos_emb(query_states, key_states, cos, sin)
|
| 490 |
+
|
| 491 |
+
if past_key_values is not None:
|
| 492 |
+
key_states, value_states = past_key_values.update(key_states, value_states, self.layer_idx)
|
| 493 |
+
|
| 494 |
+
attention_interface: Callable = ALL_ATTENTION_FUNCTIONS.get_interface(
|
| 495 |
+
self.config._attn_implementation, eager_attention_forward
|
| 496 |
+
)
|
| 497 |
+
|
| 498 |
+
attn_output, attn_weights = attention_interface(
|
| 499 |
+
self,
|
| 500 |
+
query_states,
|
| 501 |
+
key_states,
|
| 502 |
+
value_states,
|
| 503 |
+
attention_mask,
|
| 504 |
+
dropout=0.0 if not self.training else self.attention_dropout,
|
| 505 |
+
scaling=self.scaling,
|
| 506 |
+
**kwargs,
|
| 507 |
+
)
|
| 508 |
+
|
| 509 |
+
attn_output = attn_output.reshape(*input_shape, -1).contiguous()
|
| 510 |
+
attn_output = self.o_proj(attn_output)
|
| 511 |
+
return attn_output, attn_weights
|
| 512 |
+
|
| 513 |
+
|
| 514 |
+
class Qwen3VLTextMLP(nn.Module):
|
| 515 |
+
def __init__(self, config):
|
| 516 |
+
super().__init__()
|
| 517 |
+
self.config = config
|
| 518 |
+
self.hidden_size = config.hidden_size
|
| 519 |
+
self.intermediate_size = config.intermediate_size
|
| 520 |
+
self.gate_proj = nn.Linear(self.hidden_size, self.intermediate_size, bias=False)
|
| 521 |
+
self.up_proj = nn.Linear(self.hidden_size, self.intermediate_size, bias=False)
|
| 522 |
+
self.down_proj = nn.Linear(self.intermediate_size, self.hidden_size, bias=False)
|
| 523 |
+
self.act_fn = ACT2FN[config.hidden_act]
|
| 524 |
+
|
| 525 |
+
def forward(self, x):
|
| 526 |
+
down_proj = self.down_proj(self.act_fn(self.gate_proj(x)) * self.up_proj(x))
|
| 527 |
+
return down_proj
|
| 528 |
+
|
| 529 |
+
|
| 530 |
+
class Qwen3VLTextDecoderLayer(GradientCheckpointingLayer):
|
| 531 |
+
def __init__(self, config: Qwen3VLTextConfig, layer_idx: int):
|
| 532 |
+
super().__init__()
|
| 533 |
+
self.hidden_size = config.hidden_size
|
| 534 |
+
|
| 535 |
+
self.self_attn = Qwen3VLTextAttention(config=config, layer_idx=layer_idx)
|
| 536 |
+
|
| 537 |
+
self.mlp = Qwen3VLTextMLP(config)
|
| 538 |
+
self.input_layernorm = Qwen3VLTextRMSNorm(config.hidden_size, eps=config.rms_norm_eps)
|
| 539 |
+
self.post_attention_layernorm = Qwen3VLTextRMSNorm(config.hidden_size, eps=config.rms_norm_eps)
|
| 540 |
+
|
| 541 |
+
def forward(
|
| 542 |
+
self,
|
| 543 |
+
hidden_states: torch.Tensor,
|
| 544 |
+
position_embeddings: tuple[torch.Tensor, torch.Tensor],
|
| 545 |
+
attention_mask: torch.Tensor | None = None,
|
| 546 |
+
position_ids: torch.LongTensor | None = None,
|
| 547 |
+
past_key_values: Cache | None = None,
|
| 548 |
+
use_cache: bool | None = False,
|
| 549 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 550 |
+
) -> torch.Tensor:
|
| 551 |
+
residual = hidden_states
|
| 552 |
+
hidden_states = self.input_layernorm(hidden_states)
|
| 553 |
+
# Self Attention
|
| 554 |
+
hidden_states, _ = self.self_attn(
|
| 555 |
+
hidden_states=hidden_states,
|
| 556 |
+
attention_mask=attention_mask,
|
| 557 |
+
position_ids=position_ids,
|
| 558 |
+
past_key_values=past_key_values,
|
| 559 |
+
use_cache=use_cache,
|
| 560 |
+
position_embeddings=position_embeddings,
|
| 561 |
+
**kwargs,
|
| 562 |
+
)
|
| 563 |
+
hidden_states = residual + hidden_states
|
| 564 |
+
|
| 565 |
+
# Fully Connected
|
| 566 |
+
residual = hidden_states
|
| 567 |
+
hidden_states = self.post_attention_layernorm(hidden_states)
|
| 568 |
+
hidden_states = self.mlp(hidden_states)
|
| 569 |
+
hidden_states = residual + hidden_states
|
| 570 |
+
return hidden_states
|
| 571 |
+
|
| 572 |
+
|
| 573 |
+
@auto_docstring(
|
| 574 |
+
custom_intro="""
|
| 575 |
+
Base class for Llava outputs, with hidden states and attentions.
|
| 576 |
+
"""
|
| 577 |
+
)
|
| 578 |
+
@dataclass
|
| 579 |
+
class Qwen3VLModelOutputWithPast(ModelOutput):
|
| 580 |
+
r"""
|
| 581 |
+
past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`):
|
| 582 |
+
It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache).
|
| 583 |
+
|
| 584 |
+
Contains pre-computed hidden-states (key and values in the self-attention blocks) that can be used (see
|
| 585 |
+
`past_key_values` input) to speed up sequential decoding.
|
| 586 |
+
rope_deltas (`torch.LongTensor` of shape `(batch_size, )`, *optional*):
|
| 587 |
+
The rope index difference between sequence length and multimodal rope.
|
| 588 |
+
"""
|
| 589 |
+
|
| 590 |
+
last_hidden_state: torch.FloatTensor | None = None
|
| 591 |
+
past_key_values: Cache | None = None
|
| 592 |
+
hidden_states: tuple[torch.FloatTensor] | None = None
|
| 593 |
+
attentions: tuple[torch.FloatTensor] | None = None
|
| 594 |
+
rope_deltas: torch.LongTensor | None = None
|
| 595 |
+
|
| 596 |
+
|
| 597 |
+
@auto_docstring
|
| 598 |
+
class Qwen3VLPreTrainedModel(PreTrainedModel):
|
| 599 |
+
config: Qwen3VLConfig
|
| 600 |
+
base_model_prefix = "model"
|
| 601 |
+
input_modalities = ("image", "video", "text")
|
| 602 |
+
supports_gradient_checkpointing = True
|
| 603 |
+
_no_split_modules = ["Qwen3VLTextDecoderLayer", "Qwen3VLVisionBlock"]
|
| 604 |
+
_skip_keys_device_placement = ["past_key_values"]
|
| 605 |
+
_supports_flash_attn = True
|
| 606 |
+
_supports_sdpa = True
|
| 607 |
+
|
| 608 |
+
_can_compile_fullgraph = True
|
| 609 |
+
_supports_attention_backend = True
|
| 610 |
+
_can_record_outputs = {
|
| 611 |
+
"hidden_states": Qwen3VLTextDecoderLayer,
|
| 612 |
+
"attentions": Qwen3VLTextAttention,
|
| 613 |
+
}
|
| 614 |
+
|
| 615 |
+
def _init_weights(self, module):
|
| 616 |
+
super()._init_weights(module)
|
| 617 |
+
if isinstance(module, Qwen3VLVisionRotaryEmbedding):
|
| 618 |
+
inv_freq = 1.0 / (module.theta ** (torch.arange(0, module.dim, 2, dtype=torch.float) / module.dim))
|
| 619 |
+
init.copy_(module.inv_freq, inv_freq)
|
| 620 |
+
|
| 621 |
+
|
| 622 |
+
class Qwen3VLVisionModel(Qwen3VLPreTrainedModel):
|
| 623 |
+
config: Qwen3VLVisionConfig
|
| 624 |
+
input_modalities = ("image", "video")
|
| 625 |
+
_no_split_modules = ["Qwen3VLVisionBlock"]
|
| 626 |
+
_can_record_outputs = {
|
| 627 |
+
"hidden_states": Qwen3VLVisionBlock,
|
| 628 |
+
"attentions": Qwen3VLVisionAttention,
|
| 629 |
+
}
|
| 630 |
+
|
| 631 |
+
def __init__(self, config, *inputs, **kwargs) -> None:
|
| 632 |
+
super().__init__(config, *inputs, **kwargs)
|
| 633 |
+
self.spatial_merge_size = config.spatial_merge_size
|
| 634 |
+
self.patch_size = config.patch_size
|
| 635 |
+
self.spatial_merge_unit = self.spatial_merge_size * self.spatial_merge_size
|
| 636 |
+
|
| 637 |
+
self.patch_embed = Qwen3VLVisionPatchEmbed(
|
| 638 |
+
config=config,
|
| 639 |
+
)
|
| 640 |
+
|
| 641 |
+
self.pos_embed = nn.Embedding(config.num_position_embeddings, config.hidden_size)
|
| 642 |
+
self.num_grid_per_side = int(config.num_position_embeddings**0.5)
|
| 643 |
+
|
| 644 |
+
head_dim = config.hidden_size // config.num_heads
|
| 645 |
+
self.rotary_pos_emb = Qwen3VLVisionRotaryEmbedding(head_dim // 2)
|
| 646 |
+
|
| 647 |
+
self.blocks = nn.ModuleList([Qwen3VLVisionBlock(config) for _ in range(config.depth)])
|
| 648 |
+
self.merger = Qwen3VLVisionPatchMerger(
|
| 649 |
+
config=config,
|
| 650 |
+
use_postshuffle_norm=False,
|
| 651 |
+
)
|
| 652 |
+
|
| 653 |
+
self.deepstack_visual_indexes = config.deepstack_visual_indexes
|
| 654 |
+
self.deepstack_merger_list = nn.ModuleList(
|
| 655 |
+
[
|
| 656 |
+
Qwen3VLVisionPatchMerger(
|
| 657 |
+
config=config,
|
| 658 |
+
use_postshuffle_norm=True,
|
| 659 |
+
)
|
| 660 |
+
for _ in range(len(config.deepstack_visual_indexes))
|
| 661 |
+
]
|
| 662 |
+
)
|
| 663 |
+
|
| 664 |
+
self.gradient_checkpointing = False
|
| 665 |
+
|
| 666 |
+
self.post_init()
|
| 667 |
+
|
| 668 |
+
def rot_pos_emb(self, grid_thw: torch.Tensor) -> torch.Tensor:
|
| 669 |
+
warnings.warn(
|
| 670 |
+
f"`{self.__class__.__name__}.rot_pos_emb` is deprecated and will be removed in v5.11. Use `get_vision_position_ids` from `transformers.vision_utils` and apply the rotary embedding module.",
|
| 671 |
+
FutureWarning,
|
| 672 |
+
stacklevel=2,
|
| 673 |
+
)
|
| 674 |
+
position_ids = get_vision_position_ids(grid_thw, self.spatial_merge_size)
|
| 675 |
+
rotary_pos_emb = self.rotary_pos_emb(position_ids)
|
| 676 |
+
return rotary_pos_emb
|
| 677 |
+
|
| 678 |
+
def fast_pos_embed_interpolate(self, grid_thw):
|
| 679 |
+
warnings.warn(
|
| 680 |
+
f"`{self.__class__.__name__}.fast_pos_embed_interpolate` is deprecated and will be removed in v5.11. Use `get_vision_bilinear_indices_and_weights` from `transformers.vision_utils` and apply `self.pos_embed`.",
|
| 681 |
+
FutureWarning,
|
| 682 |
+
stacklevel=2,
|
| 683 |
+
)
|
| 684 |
+
bilinear_indices, bilinear_weights = get_vision_bilinear_indices_and_weights(
|
| 685 |
+
grid_thw,
|
| 686 |
+
num_grid_per_side=self.num_grid_per_side,
|
| 687 |
+
spatial_merge_size=self.config.spatial_merge_size,
|
| 688 |
+
)
|
| 689 |
+
return (self.pos_embed(bilinear_indices) * bilinear_weights[:, :, None]).sum(0)
|
| 690 |
+
|
| 691 |
+
@merge_with_config_defaults
|
| 692 |
+
@capture_outputs
|
| 693 |
+
def forward(
|
| 694 |
+
self, hidden_states: torch.Tensor, grid_thw: torch.Tensor, **kwargs: Unpack[TransformersKwargs]
|
| 695 |
+
) -> tuple | BaseModelOutputWithDeepstackFeatures:
|
| 696 |
+
"""
|
| 697 |
+
Args:
|
| 698 |
+
hidden_states (`torch.Tensor` of shape `(seq_len, hidden_size)`):
|
| 699 |
+
The final hidden states of the model.
|
| 700 |
+
grid_thw (`torch.Tensor` of shape `(num_images_or_videos, 3)`):
|
| 701 |
+
The temporal, height and width of feature shape of each image in LLM.
|
| 702 |
+
|
| 703 |
+
Returns:
|
| 704 |
+
`torch.Tensor`: hidden_states.
|
| 705 |
+
"""
|
| 706 |
+
bilinear_indices, bilinear_weights = get_vision_bilinear_indices_and_weights(
|
| 707 |
+
grid_thw,
|
| 708 |
+
num_grid_per_side=self.num_grid_per_side,
|
| 709 |
+
spatial_merge_size=self.config.spatial_merge_size,
|
| 710 |
+
kwargs=kwargs,
|
| 711 |
+
)
|
| 712 |
+
position_ids = get_vision_position_ids(grid_thw, self.spatial_merge_size, kwargs=kwargs)
|
| 713 |
+
cu_seqlens = get_vision_cu_seqlens(grid_thw, kwargs=kwargs)
|
| 714 |
+
|
| 715 |
+
hidden_states = self.patch_embed(hidden_states)
|
| 716 |
+
pos_embeds = (self.pos_embed(bilinear_indices) * bilinear_weights[:, :, None]).sum(0)
|
| 717 |
+
hidden_states = hidden_states + pos_embeds.to(hidden_states.dtype)
|
| 718 |
+
rotary_pos_emb = self.rotary_pos_emb(position_ids)
|
| 719 |
+
|
| 720 |
+
seq_len, _ = hidden_states.size()
|
| 721 |
+
hidden_states = hidden_states.reshape(seq_len, -1)
|
| 722 |
+
rotary_pos_emb = rotary_pos_emb.reshape(seq_len, -1)
|
| 723 |
+
emb = torch.cat((rotary_pos_emb, rotary_pos_emb), dim=-1)
|
| 724 |
+
position_embeddings = (emb.cos(), emb.sin())
|
| 725 |
+
|
| 726 |
+
deepstack_feature_lists = []
|
| 727 |
+
for layer_num, blk in enumerate(self.blocks):
|
| 728 |
+
hidden_states = blk(
|
| 729 |
+
hidden_states,
|
| 730 |
+
cu_seqlens=cu_seqlens,
|
| 731 |
+
position_embeddings=position_embeddings,
|
| 732 |
+
**kwargs,
|
| 733 |
+
)
|
| 734 |
+
if layer_num in self.deepstack_visual_indexes:
|
| 735 |
+
deepstack_feature = self.deepstack_merger_list[self.deepstack_visual_indexes.index(layer_num)](
|
| 736 |
+
hidden_states
|
| 737 |
+
)
|
| 738 |
+
deepstack_feature_lists.append(deepstack_feature)
|
| 739 |
+
|
| 740 |
+
merged_hidden_states = self.merger(hidden_states)
|
| 741 |
+
|
| 742 |
+
return BaseModelOutputWithDeepstackFeatures(
|
| 743 |
+
last_hidden_state=hidden_states,
|
| 744 |
+
pooler_output=merged_hidden_states,
|
| 745 |
+
deepstack_features=deepstack_feature_lists,
|
| 746 |
+
)
|
| 747 |
+
|
| 748 |
+
|
| 749 |
+
@auto_docstring(
|
| 750 |
+
custom_intro=(
|
| 751 |
+
"Text part of Qwen3VL, "
|
| 752 |
+
"not a pure text-only model, as DeepStack integrates visual features into the early hidden states."
|
| 753 |
+
)
|
| 754 |
+
)
|
| 755 |
+
class Qwen3VLTextModel(Qwen3VLPreTrainedModel):
|
| 756 |
+
config: Qwen3VLTextConfig
|
| 757 |
+
input_modalities = ("text",)
|
| 758 |
+
_no_split_modules = ["Qwen3VLTextDecoderLayer"]
|
| 759 |
+
|
| 760 |
+
def __init__(self, config: Qwen3VLTextConfig):
|
| 761 |
+
super().__init__(config)
|
| 762 |
+
self.padding_idx = config.pad_token_id
|
| 763 |
+
self.vocab_size = config.vocab_size
|
| 764 |
+
|
| 765 |
+
self.embed_tokens = nn.Embedding(config.vocab_size, config.hidden_size, self.padding_idx)
|
| 766 |
+
self.layers = nn.ModuleList(
|
| 767 |
+
[Qwen3VLTextDecoderLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)]
|
| 768 |
+
)
|
| 769 |
+
self.norm = Qwen3VLTextRMSNorm(config.hidden_size, eps=config.rms_norm_eps)
|
| 770 |
+
self.rotary_emb = Qwen3VLTextRotaryEmbedding(config=config)
|
| 771 |
+
self.gradient_checkpointing = False
|
| 772 |
+
|
| 773 |
+
# Initialize weights and apply final processing
|
| 774 |
+
self.post_init()
|
| 775 |
+
|
| 776 |
+
@merge_with_config_defaults
|
| 777 |
+
@capture_outputs
|
| 778 |
+
@auto_docstring
|
| 779 |
+
def forward(
|
| 780 |
+
self,
|
| 781 |
+
input_ids: torch.LongTensor | None = None,
|
| 782 |
+
attention_mask: torch.Tensor | None = None,
|
| 783 |
+
position_ids: torch.LongTensor | None = None,
|
| 784 |
+
past_key_values: Cache | None = None,
|
| 785 |
+
inputs_embeds: torch.FloatTensor | None = None,
|
| 786 |
+
use_cache: bool | None = None,
|
| 787 |
+
# args for deepstack
|
| 788 |
+
visual_pos_masks: torch.Tensor | None = None,
|
| 789 |
+
deepstack_visual_embeds: list[torch.Tensor] | None = None,
|
| 790 |
+
**kwargs: Unpack[FlashAttentionKwargs],
|
| 791 |
+
) -> tuple | BaseModelOutputWithPast:
|
| 792 |
+
r"""
|
| 793 |
+
visual_pos_masks (`torch.Tensor` of shape `(batch_size, seqlen)`, *optional*):
|
| 794 |
+
The mask of the visual positions.
|
| 795 |
+
deepstack_visual_embeds (`list[torch.Tensor]`, *optional*):
|
| 796 |
+
The deepstack visual embeddings. The shape is (num_layers, visual_seqlen, embed_dim).
|
| 797 |
+
The feature is extracted from the different visual encoder layers, and fed to the decoder
|
| 798 |
+
hidden states. It's from the paper DeepStack(https://arxiv.org/abs/2406.04334).
|
| 799 |
+
"""
|
| 800 |
+
if (input_ids is None) ^ (inputs_embeds is not None):
|
| 801 |
+
raise ValueError("You must specify exactly one of input_ids or inputs_embeds")
|
| 802 |
+
|
| 803 |
+
# torch.jit.trace() doesn't support cache objects in the output
|
| 804 |
+
if use_cache and past_key_values is None and not torch.jit.is_tracing():
|
| 805 |
+
past_key_values = DynamicCache(config=self.config)
|
| 806 |
+
|
| 807 |
+
if inputs_embeds is None:
|
| 808 |
+
inputs_embeds = self.embed_tokens(input_ids)
|
| 809 |
+
|
| 810 |
+
# the hard coded `4` is for text, temporal, height and width.
|
| 811 |
+
if position_ids is None:
|
| 812 |
+
past_seen_tokens = past_key_values.get_seq_length() if past_key_values is not None else 0
|
| 813 |
+
position_ids = torch.arange(inputs_embeds.shape[1], device=inputs_embeds.device) + past_seen_tokens
|
| 814 |
+
position_ids = position_ids.view(1, 1, -1).expand(4, inputs_embeds.shape[0], -1)
|
| 815 |
+
elif position_ids.ndim == 2:
|
| 816 |
+
position_ids = position_ids[None, ...].expand(4, position_ids.shape[0], -1)
|
| 817 |
+
|
| 818 |
+
if position_ids.ndim == 3 and position_ids.shape[0] == 4:
|
| 819 |
+
text_position_ids = position_ids[0]
|
| 820 |
+
position_ids = position_ids[1:]
|
| 821 |
+
else:
|
| 822 |
+
text_position_ids = None
|
| 823 |
+
|
| 824 |
+
attention_mask = create_causal_mask(
|
| 825 |
+
config=self.config,
|
| 826 |
+
inputs_embeds=inputs_embeds,
|
| 827 |
+
attention_mask=attention_mask,
|
| 828 |
+
past_key_values=past_key_values,
|
| 829 |
+
position_ids=text_position_ids,
|
| 830 |
+
)
|
| 831 |
+
|
| 832 |
+
hidden_states = inputs_embeds
|
| 833 |
+
|
| 834 |
+
# create position embeddings to be shared across the decoder layers
|
| 835 |
+
position_embeddings = self.rotary_emb(hidden_states, position_ids)
|
| 836 |
+
|
| 837 |
+
# decoder layers
|
| 838 |
+
for layer_idx, decoder_layer in enumerate(self.layers):
|
| 839 |
+
layer_outputs = decoder_layer(
|
| 840 |
+
hidden_states,
|
| 841 |
+
attention_mask=attention_mask,
|
| 842 |
+
position_ids=text_position_ids,
|
| 843 |
+
past_key_values=past_key_values,
|
| 844 |
+
position_embeddings=position_embeddings,
|
| 845 |
+
**kwargs,
|
| 846 |
+
)
|
| 847 |
+
hidden_states = layer_outputs
|
| 848 |
+
|
| 849 |
+
# add visual features to the hidden states of first several layers
|
| 850 |
+
if deepstack_visual_embeds is not None and layer_idx in range(len(deepstack_visual_embeds)):
|
| 851 |
+
hidden_states = self._deepstack_process(
|
| 852 |
+
hidden_states,
|
| 853 |
+
visual_pos_masks,
|
| 854 |
+
deepstack_visual_embeds[layer_idx],
|
| 855 |
+
)
|
| 856 |
+
|
| 857 |
+
hidden_states = self.norm(hidden_states)
|
| 858 |
+
|
| 859 |
+
return BaseModelOutputWithPast(
|
| 860 |
+
last_hidden_state=hidden_states,
|
| 861 |
+
past_key_values=past_key_values,
|
| 862 |
+
)
|
| 863 |
+
|
| 864 |
+
def _deepstack_process(
|
| 865 |
+
self, hidden_states: torch.Tensor, visual_pos_masks: torch.Tensor, visual_embeds: torch.Tensor
|
| 866 |
+
):
|
| 867 |
+
visual_pos_masks = visual_pos_masks.to(hidden_states.device)
|
| 868 |
+
visual_embeds = visual_embeds.to(hidden_states.device, hidden_states.dtype)
|
| 869 |
+
hidden_states = hidden_states.clone()
|
| 870 |
+
local_this = hidden_states[visual_pos_masks, :] + visual_embeds
|
| 871 |
+
hidden_states[visual_pos_masks, :] = local_this
|
| 872 |
+
return hidden_states
|
| 873 |
+
|
| 874 |
+
|
| 875 |
+
@auto_docstring
|
| 876 |
+
class Qwen3VLModel(Qwen3VLPreTrainedModel):
|
| 877 |
+
base_model_prefix = "model"
|
| 878 |
+
# Reference: fix gemma3 grad acc #37208
|
| 879 |
+
accepts_loss_kwargs = False
|
| 880 |
+
config: Qwen3VLConfig
|
| 881 |
+
_no_split_modules = ["Qwen3VLTextDecoderLayer", "Qwen3VLVisionBlock"]
|
| 882 |
+
|
| 883 |
+
def __init__(self, config):
|
| 884 |
+
super().__init__(config)
|
| 885 |
+
self.visual = Qwen3VLVisionModel._from_config(config.vision_config)
|
| 886 |
+
self.language_model = Qwen3VLTextModel._from_config(config.text_config)
|
| 887 |
+
self.rope_deltas = None # cache rope_deltas here
|
| 888 |
+
|
| 889 |
+
# Initialize weights and apply final processing
|
| 890 |
+
self.post_init()
|
| 891 |
+
|
| 892 |
+
def get_vision_position_ids(
|
| 893 |
+
self,
|
| 894 |
+
start_position: int,
|
| 895 |
+
grid_thw: list[int, int, int] | torch.Tensor,
|
| 896 |
+
temp_merge_size: int = 1,
|
| 897 |
+
spatial_merge_size: int = 1,
|
| 898 |
+
time_interval: int = 1,
|
| 899 |
+
device: str | torch.device | None = None,
|
| 900 |
+
):
|
| 901 |
+
"""
|
| 902 |
+
Compute 3D positional indices for vision tokens derived from a single image or video input.
|
| 903 |
+
|
| 904 |
+
The positions are generated from the input grid defined by temporal (T), height (H), and
|
| 905 |
+
width (W) dimensions. Temporal and spatial dimensions can be downscaled according to the
|
| 906 |
+
merge sizes used in the vision backbone. The resulting positions are offset by `start_position`.
|
| 907 |
+
|
| 908 |
+
Args:
|
| 909 |
+
start_position (`int`):
|
| 910 |
+
Offset added to all computed positional indices.
|
| 911 |
+
grid_thw (`Sequence[int]` or `torch.Tensor` of shape `(3,)`):
|
| 912 |
+
The (T, H, W) grid representing the feature layout of the current image or video after patch embedding.
|
| 913 |
+
temp_merge_size (`int`, *optional*):
|
| 914 |
+
Factor by which the temporal dimension is reduced in the backbone. The temporal grid size is divided
|
| 915 |
+
by this value. Defaults to 1.
|
| 916 |
+
spatial_merge_size (`int`, *optional*):
|
| 917 |
+
Factor by which the spatial dimensions (H and W) are reduced in the backbone. Both H and W are divided
|
| 918 |
+
by this value. Defaults to 1.
|
| 919 |
+
time_interval (`int`, *optional*):
|
| 920 |
+
Spacing factor applied between consecutive temporal position indices.Defaults to 1.
|
| 921 |
+
device (`str` or `torch.device`, *optional*):
|
| 922 |
+
Device on which the resulting tensor is allocated. If `None`, uses the current default device.
|
| 923 |
+
|
| 924 |
+
Returns:
|
| 925 |
+
torch.LongTensor of shape (3, sequence_length):
|
| 926 |
+
Positional indices for temporal, height, and width dimensions,
|
| 927 |
+
flattened into sequence form and offset by `start_position`.
|
| 928 |
+
"""
|
| 929 |
+
llm_grid_t, llm_grid_h, llm_grid_w = (
|
| 930 |
+
grid_thw[0].item() // temp_merge_size,
|
| 931 |
+
grid_thw[1].item() // spatial_merge_size,
|
| 932 |
+
grid_thw[2].item() // spatial_merge_size,
|
| 933 |
+
)
|
| 934 |
+
|
| 935 |
+
# Add `start_position` after arange for compile
|
| 936 |
+
position_temporal = torch.arange(llm_grid_t, device=device) * time_interval
|
| 937 |
+
position_width = torch.arange(llm_grid_w, device=device) + start_position
|
| 938 |
+
position_height = torch.arange(llm_grid_h, device=device) + start_position
|
| 939 |
+
|
| 940 |
+
# Repeat the positions per each grid and per video frame. Repeat patterns are important
|
| 941 |
+
# do not modify without checking values!
|
| 942 |
+
position_width = position_width.repeat(llm_grid_h * llm_grid_t)
|
| 943 |
+
position_height = position_height.repeat_interleave(llm_grid_w).repeat(llm_grid_t)
|
| 944 |
+
# Important: add `start_positions` after applying `time_interval`, order matters
|
| 945 |
+
position_temporal = position_temporal.repeat_interleave(llm_grid_h * llm_grid_w) + start_position
|
| 946 |
+
vision_position_ids = torch.stack([position_temporal, position_height, position_width], dim=0)
|
| 947 |
+
|
| 948 |
+
return vision_position_ids
|
| 949 |
+
|
| 950 |
+
def get_rope_index(
|
| 951 |
+
self,
|
| 952 |
+
input_ids: torch.LongTensor,
|
| 953 |
+
mm_token_type_ids: torch.IntTensor,
|
| 954 |
+
image_grid_thw: torch.LongTensor | None = None,
|
| 955 |
+
video_grid_thw: torch.LongTensor | None = None,
|
| 956 |
+
attention_mask: torch.Tensor | None = None,
|
| 957 |
+
**kwargs,
|
| 958 |
+
) -> tuple[torch.Tensor, torch.Tensor]:
|
| 959 |
+
"""
|
| 960 |
+
Difference from Qwen2VL/Qwen2.5VL's get_rope_index:
|
| 961 |
+
- Since Qwen3.5 use timestamps to separate videos, like <t1> <vision_start> <frame1> <vision_end> <t2> <vision_start> <frame2> <vision_end>, the video_grid_thw should also be split too.
|
| 962 |
+
|
| 963 |
+
Args:
|
| 964 |
+
input_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`):
|
| 965 |
+
Indices of input sequence tokens in the vocabulary. Padding will be ignored by default should you provide
|
| 966 |
+
it.
|
| 967 |
+
mm_token_type_ids (`torch.IntTensor` of shape `(batch_size, sequence_length)`):
|
| 968 |
+
Token type ids matching each modality to a different value in the input sequence, i.e. text (0), image (1), video (2).
|
| 969 |
+
image_grid_thw (`torch.LongTensor` of shape `(num_images, 3)`, *optional*):
|
| 970 |
+
The temporal, height and width of feature shape of each image in LLM.
|
| 971 |
+
video_grid_thw (`torch.LongTensor` of shape `(num_videos, 3)`, *optional*):
|
| 972 |
+
The temporal, height and width of feature shape of each video in LLM.
|
| 973 |
+
attention_mask (`torch.Tensor` of shape `(batch_size, sequence_length)`, *optional*):
|
| 974 |
+
Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`:
|
| 975 |
+
|
| 976 |
+
- 1 for tokens that are **not masked**,
|
| 977 |
+
- 0 for tokens that are **masked**.
|
| 978 |
+
|
| 979 |
+
Returns:
|
| 980 |
+
position_ids (`torch.LongTensor` of shape `(3, batch_size, sequence_length)`)
|
| 981 |
+
mrope_position_deltas (`torch.Tensor` of shape `(batch_size)`)
|
| 982 |
+
"""
|
| 983 |
+
|
| 984 |
+
# Separate video grid thw into multiple grids because timestamps are used to separate videos.
|
| 985 |
+
if video_grid_thw is not None:
|
| 986 |
+
video_grid_thw = torch.repeat_interleave(video_grid_thw, video_grid_thw[:, 0], dim=0)
|
| 987 |
+
video_grid_thw[:, 0] = 1
|
| 988 |
+
spatial_merge_size = self.config.vision_config.spatial_merge_size
|
| 989 |
+
|
| 990 |
+
mrope_position_deltas = []
|
| 991 |
+
position_ids = torch.zeros(
|
| 992 |
+
3,
|
| 993 |
+
input_ids.shape[0],
|
| 994 |
+
input_ids.shape[1],
|
| 995 |
+
dtype=input_ids.dtype,
|
| 996 |
+
device=input_ids.device,
|
| 997 |
+
)
|
| 998 |
+
grid_iters = {
|
| 999 |
+
1: iter(image_grid_thw) if image_grid_thw is not None else None,
|
| 1000 |
+
2: iter(video_grid_thw) if video_grid_thw is not None else None,
|
| 1001 |
+
}
|
| 1002 |
+
|
| 1003 |
+
for batch_idx, current_input_ids in enumerate(input_ids):
|
| 1004 |
+
input_token_type = mm_token_type_ids[batch_idx]
|
| 1005 |
+
if attention_mask is not None:
|
| 1006 |
+
current_input_ids = current_input_ids[attention_mask[batch_idx].bool()]
|
| 1007 |
+
input_token_type = input_token_type[attention_mask[batch_idx].bool()]
|
| 1008 |
+
|
| 1009 |
+
input_type_group = []
|
| 1010 |
+
for key, group in itertools.groupby(enumerate(input_token_type.tolist()), lambda x: x[1]):
|
| 1011 |
+
group = list(group)
|
| 1012 |
+
start_index = group[0][0]
|
| 1013 |
+
end_index = group[-1][0] + 1
|
| 1014 |
+
input_type_group.append((key, start_index, end_index))
|
| 1015 |
+
|
| 1016 |
+
current_pos = 0
|
| 1017 |
+
llm_pos_ids_list = []
|
| 1018 |
+
for modality_type, start_idx, end_idx in input_type_group:
|
| 1019 |
+
# text == 0
|
| 1020 |
+
if modality_type == 0:
|
| 1021 |
+
text_len = end_idx - start_idx
|
| 1022 |
+
llm_pos_ids_list.append(
|
| 1023 |
+
torch.arange(text_len, device=input_ids.device).view(1, -1).expand(3, -1) + current_pos
|
| 1024 |
+
)
|
| 1025 |
+
current_pos += text_len
|
| 1026 |
+
# image == 1, video == 2
|
| 1027 |
+
else:
|
| 1028 |
+
grid_thw = next(grid_iters[modality_type])
|
| 1029 |
+
vision_position_ids = self.get_vision_position_ids(
|
| 1030 |
+
current_pos, grid_thw, 1, spatial_merge_size, device=input_ids.device
|
| 1031 |
+
)
|
| 1032 |
+
llm_pos_ids_list.append(vision_position_ids)
|
| 1033 |
+
current_pos += max(grid_thw[1], grid_thw[2]) // spatial_merge_size
|
| 1034 |
+
llm_positions = torch.cat(llm_pos_ids_list, dim=1).reshape(3, -1)
|
| 1035 |
+
if attention_mask is not None:
|
| 1036 |
+
position_ids[:, batch_idx, attention_mask[batch_idx].bool()] = llm_positions.to(position_ids.device)
|
| 1037 |
+
else:
|
| 1038 |
+
position_ids[:, batch_idx] = llm_positions.to(position_ids.device)
|
| 1039 |
+
mrope_position_deltas.append(llm_positions.max() + 1 - len(current_input_ids))
|
| 1040 |
+
mrope_position_deltas = torch.tensor(mrope_position_deltas, device=input_ids.device).unsqueeze(1)
|
| 1041 |
+
return position_ids, mrope_position_deltas
|
| 1042 |
+
|
| 1043 |
+
@accepts_precomputed_kwargs(modality="video")
|
| 1044 |
+
@can_return_tuple
|
| 1045 |
+
@auto_docstring
|
| 1046 |
+
def get_video_features(
|
| 1047 |
+
self,
|
| 1048 |
+
pixel_values_videos: torch.FloatTensor,
|
| 1049 |
+
video_grid_thw: torch.LongTensor | None = None,
|
| 1050 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 1051 |
+
) -> tuple | BaseModelOutputWithDeepstackFeatures:
|
| 1052 |
+
r"""
|
| 1053 |
+
pixel_values_videos (`torch.FloatTensor` of shape `(batch_size, num_channels, image_size, image_size)`):
|
| 1054 |
+
The tensors corresponding to the input videos.
|
| 1055 |
+
video_grid_thw (`torch.LongTensor` of shape `(num_videos, 3)`, *optional*):
|
| 1056 |
+
The temporal, height and width of feature shape of each video in LLM.
|
| 1057 |
+
"""
|
| 1058 |
+
# Same implementation as for images
|
| 1059 |
+
return self.get_image_features(pixel_values_videos, video_grid_thw, **kwargs)
|
| 1060 |
+
|
| 1061 |
+
@accepts_precomputed_kwargs(modality="image")
|
| 1062 |
+
@can_return_tuple
|
| 1063 |
+
@auto_docstring
|
| 1064 |
+
def get_image_features(
|
| 1065 |
+
self,
|
| 1066 |
+
pixel_values: torch.FloatTensor,
|
| 1067 |
+
image_grid_thw: torch.LongTensor | None = None,
|
| 1068 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 1069 |
+
) -> tuple | BaseModelOutputWithDeepstackFeatures:
|
| 1070 |
+
r"""
|
| 1071 |
+
pixel_values (`torch.FloatTensor` of shape `(batch_size, num_channels, image_size, image_size)`):
|
| 1072 |
+
The tensors corresponding to the input images.
|
| 1073 |
+
image_grid_thw (`torch.LongTensor` of shape `(num_images, 3)`, *optional*):
|
| 1074 |
+
The temporal, height and width of feature shape of each image in LLM.
|
| 1075 |
+
"""
|
| 1076 |
+
pixel_values = pixel_values.type(self.visual.dtype)
|
| 1077 |
+
vision_output: BaseModelOutputWithDeepstackFeatures = self.visual(
|
| 1078 |
+
pixel_values, grid_thw=image_grid_thw, return_dict=True, **kwargs
|
| 1079 |
+
)
|
| 1080 |
+
image_embeds = vision_output.pooler_output
|
| 1081 |
+
split_sizes = (image_grid_thw.prod(-1) // self.visual.spatial_merge_size**2).tolist()
|
| 1082 |
+
image_embeds = torch.split(image_embeds, split_sizes)
|
| 1083 |
+
vision_output.pooler_output = image_embeds
|
| 1084 |
+
|
| 1085 |
+
return vision_output
|
| 1086 |
+
|
| 1087 |
+
def get_placeholder_mask(
|
| 1088 |
+
self,
|
| 1089 |
+
input_ids: torch.LongTensor,
|
| 1090 |
+
inputs_embeds: torch.FloatTensor,
|
| 1091 |
+
image_features: torch.FloatTensor | None = None,
|
| 1092 |
+
video_features: torch.FloatTensor | None = None,
|
| 1093 |
+
):
|
| 1094 |
+
"""
|
| 1095 |
+
Obtains multimodal placeholder mask from `input_ids` or `inputs_embeds`, and checks that the placeholder token count is
|
| 1096 |
+
equal to the length of multimodal features. If the lengths are different, an error is raised.
|
| 1097 |
+
"""
|
| 1098 |
+
if input_ids is None:
|
| 1099 |
+
special_image_mask = inputs_embeds == self.get_input_embeddings()(
|
| 1100 |
+
torch.tensor(self.config.image_token_id, dtype=torch.long, device=inputs_embeds.device)
|
| 1101 |
+
)
|
| 1102 |
+
special_image_mask = special_image_mask.all(-1)
|
| 1103 |
+
special_video_mask = inputs_embeds == self.get_input_embeddings()(
|
| 1104 |
+
torch.tensor(self.config.video_token_id, dtype=torch.long, device=inputs_embeds.device)
|
| 1105 |
+
)
|
| 1106 |
+
special_video_mask = special_video_mask.all(-1)
|
| 1107 |
+
else:
|
| 1108 |
+
special_image_mask = input_ids == self.config.image_token_id
|
| 1109 |
+
special_video_mask = input_ids == self.config.video_token_id
|
| 1110 |
+
|
| 1111 |
+
n_image_tokens = special_image_mask.sum()
|
| 1112 |
+
special_image_mask = special_image_mask.unsqueeze(-1).expand_as(inputs_embeds).to(inputs_embeds.device)
|
| 1113 |
+
if image_features is not None:
|
| 1114 |
+
torch_compilable_check(
|
| 1115 |
+
inputs_embeds[special_image_mask].numel() == image_features.numel(),
|
| 1116 |
+
f"Image features and image tokens do not match, tokens: {n_image_tokens}, features: {image_features.shape[0]}",
|
| 1117 |
+
)
|
| 1118 |
+
|
| 1119 |
+
n_video_tokens = special_video_mask.sum()
|
| 1120 |
+
special_video_mask = special_video_mask.unsqueeze(-1).expand_as(inputs_embeds).to(inputs_embeds.device)
|
| 1121 |
+
if video_features is not None:
|
| 1122 |
+
torch_compilable_check(
|
| 1123 |
+
inputs_embeds[special_video_mask].numel() == video_features.numel(),
|
| 1124 |
+
f"Video features and video tokens do not match, tokens: {n_video_tokens}, features: {video_features.shape[0]}",
|
| 1125 |
+
)
|
| 1126 |
+
return special_image_mask, special_video_mask
|
| 1127 |
+
|
| 1128 |
+
def compute_3d_position_ids(
|
| 1129 |
+
self,
|
| 1130 |
+
input_ids: torch.Tensor | None,
|
| 1131 |
+
inputs_embeds: torch.Tensor | None,
|
| 1132 |
+
image_grid_thw: torch.Tensor | None = None,
|
| 1133 |
+
video_grid_thw: torch.Tensor | None = None,
|
| 1134 |
+
attention_mask: torch.Tensor | None = None,
|
| 1135 |
+
past_key_values: torch.Tensor | None = None,
|
| 1136 |
+
mm_token_type_ids: torch.IntTensor | None = None,
|
| 1137 |
+
) -> torch.Tensor | None:
|
| 1138 |
+
past_key_values_length = 0 if past_key_values is None else past_key_values.get_seq_length()
|
| 1139 |
+
has_multimodal = image_grid_thw is not None or video_grid_thw is not None
|
| 1140 |
+
if has_multimodal and mm_token_type_ids is None and input_ids is not None:
|
| 1141 |
+
raise ValueError(
|
| 1142 |
+
"Multimodal data was passed (via `image_grid_thw` or `video_grid_thw`) but `mm_token_type_ids` is "
|
| 1143 |
+
"missing. Please pass `mm_token_type_ids` to the model so that multimodal RoPE (M-RoPE) can be "
|
| 1144 |
+
"computed correctly. `mm_token_type_ids` is returned by the processor alongside `input_ids`."
|
| 1145 |
+
)
|
| 1146 |
+
can_compute_mrope = input_ids is not None and mm_token_type_ids is not None and has_multimodal
|
| 1147 |
+
|
| 1148 |
+
if can_compute_mrope and (self.rope_deltas is None or past_key_values_length == 0):
|
| 1149 |
+
position_ids, rope_deltas = self.get_rope_index(
|
| 1150 |
+
input_ids,
|
| 1151 |
+
image_grid_thw=image_grid_thw,
|
| 1152 |
+
video_grid_thw=video_grid_thw,
|
| 1153 |
+
attention_mask=attention_mask,
|
| 1154 |
+
mm_token_type_ids=mm_token_type_ids,
|
| 1155 |
+
)
|
| 1156 |
+
self.rope_deltas = rope_deltas
|
| 1157 |
+
# Use pre-calculated rope-deltas to infer correct 3D position ids during incremental
|
| 1158 |
+
# generation (past_key_values_length > 0) or when only inputs_embeds is provided (no input_ids
|
| 1159 |
+
# to recompute from). Skip when input_ids is provided without past_key_values to avoid shape
|
| 1160 |
+
# mismatches from stale rope_deltas (e.g., training forward pass after generation).
|
| 1161 |
+
elif self.rope_deltas is not None and (past_key_values_length > 0 or input_ids is None):
|
| 1162 |
+
batch_size, seq_length, _ = inputs_embeds.shape
|
| 1163 |
+
if attention_mask is not None:
|
| 1164 |
+
position_ids = attention_mask.long().cumsum(-1) - 1
|
| 1165 |
+
position_ids = position_ids.masked_fill(attention_mask == 0, 0)
|
| 1166 |
+
position_ids = position_ids.view(1, batch_size, -1).repeat(3, 1, 1).to(inputs_embeds.device)
|
| 1167 |
+
else:
|
| 1168 |
+
position_ids = torch.arange(past_key_values_length, past_key_values_length + seq_length)
|
| 1169 |
+
position_ids = position_ids.view(1, 1, -1).expand(3, batch_size, -1).to(inputs_embeds.device)
|
| 1170 |
+
delta = self.rope_deltas.repeat_interleave(batch_size // self.rope_deltas.shape[0], dim=0)
|
| 1171 |
+
position_ids = position_ids + delta.to(device=inputs_embeds.device)
|
| 1172 |
+
else:
|
| 1173 |
+
# Can't build correct 3D positions. Let the model infer it
|
| 1174 |
+
position_ids = None
|
| 1175 |
+
return position_ids
|
| 1176 |
+
|
| 1177 |
+
@auto_docstring
|
| 1178 |
+
@can_return_tuple
|
| 1179 |
+
def forward(
|
| 1180 |
+
self,
|
| 1181 |
+
input_ids: torch.LongTensor = None,
|
| 1182 |
+
attention_mask: torch.Tensor | None = None,
|
| 1183 |
+
position_ids: torch.LongTensor | None = None,
|
| 1184 |
+
past_key_values: Cache | None = None,
|
| 1185 |
+
inputs_embeds: torch.FloatTensor | None = None,
|
| 1186 |
+
pixel_values: torch.Tensor | None = None,
|
| 1187 |
+
pixel_values_videos: torch.FloatTensor | None = None,
|
| 1188 |
+
image_grid_thw: torch.LongTensor | None = None,
|
| 1189 |
+
video_grid_thw: torch.LongTensor | None = None,
|
| 1190 |
+
mm_token_type_ids: torch.IntTensor | None = None,
|
| 1191 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 1192 |
+
) -> tuple | Qwen3VLModelOutputWithPast:
|
| 1193 |
+
r"""
|
| 1194 |
+
image_grid_thw (`torch.LongTensor` of shape `(num_images, 3)`, *optional*):
|
| 1195 |
+
The temporal, height and width of feature shape of each image in LLM.
|
| 1196 |
+
video_grid_thw (`torch.LongTensor` of shape `(num_videos, 3)`, *optional*):
|
| 1197 |
+
The temporal, height and width of feature shape of each video in LLM.
|
| 1198 |
+
"""
|
| 1199 |
+
if (input_ids is None) ^ (inputs_embeds is not None):
|
| 1200 |
+
raise ValueError("You must specify exactly one of input_ids or inputs_embeds")
|
| 1201 |
+
|
| 1202 |
+
if inputs_embeds is None:
|
| 1203 |
+
inputs_embeds = self.get_input_embeddings()(input_ids)
|
| 1204 |
+
|
| 1205 |
+
image_mask = None
|
| 1206 |
+
video_mask = None
|
| 1207 |
+
|
| 1208 |
+
if pixel_values is not None:
|
| 1209 |
+
image_outputs: BaseModelOutputWithDeepstackFeatures = self.get_image_features(
|
| 1210 |
+
pixel_values, image_grid_thw, return_dict=True, **kwargs
|
| 1211 |
+
)
|
| 1212 |
+
image_embeds = image_outputs.pooler_output
|
| 1213 |
+
deepstack_image_embeds = image_outputs.deepstack_features
|
| 1214 |
+
image_embeds = torch.cat(image_embeds, dim=0).to(inputs_embeds.device, inputs_embeds.dtype)
|
| 1215 |
+
image_mask, _ = self.get_placeholder_mask(
|
| 1216 |
+
input_ids, inputs_embeds=inputs_embeds, image_features=image_embeds
|
| 1217 |
+
)
|
| 1218 |
+
inputs_embeds = inputs_embeds.masked_scatter(image_mask, image_embeds)
|
| 1219 |
+
|
| 1220 |
+
if pixel_values_videos is not None:
|
| 1221 |
+
video_outputs: BaseModelOutputWithDeepstackFeatures = self.get_video_features(
|
| 1222 |
+
pixel_values_videos, video_grid_thw, return_dict=True, **kwargs
|
| 1223 |
+
)
|
| 1224 |
+
video_embeds = video_outputs.pooler_output
|
| 1225 |
+
deepstack_video_embeds = video_outputs.deepstack_features
|
| 1226 |
+
video_embeds = torch.cat(video_embeds, dim=0).to(inputs_embeds.device, inputs_embeds.dtype)
|
| 1227 |
+
_, video_mask = self.get_placeholder_mask(
|
| 1228 |
+
input_ids, inputs_embeds=inputs_embeds, video_features=video_embeds
|
| 1229 |
+
)
|
| 1230 |
+
inputs_embeds = inputs_embeds.masked_scatter(video_mask, video_embeds)
|
| 1231 |
+
|
| 1232 |
+
visual_pos_masks = None
|
| 1233 |
+
deepstack_visual_embeds = None
|
| 1234 |
+
if image_mask is not None and video_mask is not None:
|
| 1235 |
+
# aggregate visual_pos_masks and deepstack_visual_embeds
|
| 1236 |
+
image_mask = image_mask[..., 0]
|
| 1237 |
+
video_mask = video_mask[..., 0]
|
| 1238 |
+
visual_pos_masks = image_mask | video_mask
|
| 1239 |
+
deepstack_visual_embeds = []
|
| 1240 |
+
image_mask_joint = image_mask[visual_pos_masks]
|
| 1241 |
+
video_mask_joint = video_mask[visual_pos_masks]
|
| 1242 |
+
for img_embed, vid_embed in zip(deepstack_image_embeds, deepstack_video_embeds):
|
| 1243 |
+
embed_joint = img_embed.new_zeros(visual_pos_masks.sum(), img_embed.shape[-1]).to(img_embed.device)
|
| 1244 |
+
embed_joint[image_mask_joint, :] = img_embed
|
| 1245 |
+
embed_joint[video_mask_joint, :] = vid_embed
|
| 1246 |
+
deepstack_visual_embeds.append(embed_joint)
|
| 1247 |
+
elif image_mask is not None:
|
| 1248 |
+
image_mask = image_mask[..., 0]
|
| 1249 |
+
visual_pos_masks = image_mask
|
| 1250 |
+
deepstack_visual_embeds = deepstack_image_embeds
|
| 1251 |
+
elif video_mask is not None:
|
| 1252 |
+
video_mask = video_mask[..., 0]
|
| 1253 |
+
visual_pos_masks = video_mask
|
| 1254 |
+
deepstack_visual_embeds = deepstack_video_embeds
|
| 1255 |
+
|
| 1256 |
+
if position_ids is None:
|
| 1257 |
+
position_ids = self.compute_3d_position_ids(
|
| 1258 |
+
input_ids=input_ids,
|
| 1259 |
+
image_grid_thw=image_grid_thw,
|
| 1260 |
+
video_grid_thw=video_grid_thw,
|
| 1261 |
+
inputs_embeds=inputs_embeds,
|
| 1262 |
+
attention_mask=attention_mask,
|
| 1263 |
+
past_key_values=past_key_values,
|
| 1264 |
+
mm_token_type_ids=mm_token_type_ids,
|
| 1265 |
+
)
|
| 1266 |
+
|
| 1267 |
+
outputs = self.language_model(
|
| 1268 |
+
input_ids=None,
|
| 1269 |
+
position_ids=position_ids,
|
| 1270 |
+
attention_mask=attention_mask,
|
| 1271 |
+
past_key_values=past_key_values,
|
| 1272 |
+
inputs_embeds=inputs_embeds,
|
| 1273 |
+
visual_pos_masks=visual_pos_masks,
|
| 1274 |
+
deepstack_visual_embeds=deepstack_visual_embeds,
|
| 1275 |
+
**kwargs,
|
| 1276 |
+
)
|
| 1277 |
+
|
| 1278 |
+
return Qwen3VLModelOutputWithPast(
|
| 1279 |
+
**outputs,
|
| 1280 |
+
rope_deltas=self.rope_deltas,
|
| 1281 |
+
)
|
| 1282 |
+
|
| 1283 |
+
|
| 1284 |
+
@auto_docstring(
|
| 1285 |
+
custom_intro="""
|
| 1286 |
+
Base class for Qwen3VL causal language model (or autoregressive) outputs.
|
| 1287 |
+
"""
|
| 1288 |
+
)
|
| 1289 |
+
@dataclass
|
| 1290 |
+
class Qwen3VLCausalLMOutputWithPast(ModelOutput):
|
| 1291 |
+
r"""
|
| 1292 |
+
loss (`torch.FloatTensor` of shape `(1,)`, *optional*, returned when `labels` is provided):
|
| 1293 |
+
Language modeling loss (for next-token prediction).
|
| 1294 |
+
logits (`torch.FloatTensor` of shape `(batch_size, sequence_length, config.vocab_size)`):
|
| 1295 |
+
Prediction scores of the language modeling head (scores for each vocabulary token before SoftMax).
|
| 1296 |
+
past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`):
|
| 1297 |
+
It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache).
|
| 1298 |
+
|
| 1299 |
+
Contains pre-computed hidden-states (key and values in the self-attention blocks) that can be used (see
|
| 1300 |
+
`past_key_values` input) to speed up sequential decoding.
|
| 1301 |
+
rope_deltas (`torch.LongTensor` of shape `(batch_size, )`, *optional*):
|
| 1302 |
+
The rope index difference between sequence length and multimodal rope.
|
| 1303 |
+
"""
|
| 1304 |
+
|
| 1305 |
+
loss: torch.FloatTensor | None = None
|
| 1306 |
+
logits: torch.FloatTensor | None = None
|
| 1307 |
+
past_key_values: Cache | None = None
|
| 1308 |
+
hidden_states: tuple[torch.FloatTensor] | None = None
|
| 1309 |
+
attentions: tuple[torch.FloatTensor] | None = None
|
| 1310 |
+
rope_deltas: torch.LongTensor | None = None
|
| 1311 |
+
|
| 1312 |
+
|
| 1313 |
+
class Qwen3VLForConditionalGeneration(Qwen3VLPreTrainedModel, GenerationMixin):
|
| 1314 |
+
_tied_weights_keys = {"lm_head.weight": "model.language_model.embed_tokens.weight"}
|
| 1315 |
+
# Reference: fix gemma3 grad acc #37208
|
| 1316 |
+
accepts_loss_kwargs = False
|
| 1317 |
+
config: Qwen3VLConfig
|
| 1318 |
+
|
| 1319 |
+
def __init__(self, config):
|
| 1320 |
+
super().__init__(config)
|
| 1321 |
+
self.model = Qwen3VLModel(config)
|
| 1322 |
+
self.lm_head = nn.Linear(config.text_config.hidden_size, config.text_config.vocab_size, bias=False)
|
| 1323 |
+
|
| 1324 |
+
self.post_init()
|
| 1325 |
+
|
| 1326 |
+
@auto_docstring
|
| 1327 |
+
def get_video_features(
|
| 1328 |
+
self,
|
| 1329 |
+
pixel_values_videos: torch.FloatTensor,
|
| 1330 |
+
video_grid_thw: torch.LongTensor | None = None,
|
| 1331 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 1332 |
+
) -> tuple | BaseModelOutputWithDeepstackFeatures:
|
| 1333 |
+
r"""
|
| 1334 |
+
pixel_values_videos (`torch.FloatTensor` of shape `(batch_size, num_channels, image_size, image_size)`):
|
| 1335 |
+
The tensors corresponding to the input videos.
|
| 1336 |
+
video_grid_thw (`torch.LongTensor` of shape `(num_videos, 3)`, *optional*):
|
| 1337 |
+
The temporal, height and width of feature shape of each video in LLM.
|
| 1338 |
+
"""
|
| 1339 |
+
return self.model.get_video_features(pixel_values_videos, video_grid_thw, **kwargs)
|
| 1340 |
+
|
| 1341 |
+
@auto_docstring
|
| 1342 |
+
def get_image_features(
|
| 1343 |
+
self,
|
| 1344 |
+
pixel_values: torch.FloatTensor,
|
| 1345 |
+
image_grid_thw: torch.LongTensor | None = None,
|
| 1346 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 1347 |
+
) -> tuple | BaseModelOutputWithDeepstackFeatures:
|
| 1348 |
+
r"""
|
| 1349 |
+
pixel_values (`torch.FloatTensor` of shape `(batch_size, num_channels, image_size, image_size)`):
|
| 1350 |
+
The tensors corresponding to the input images.
|
| 1351 |
+
image_grid_thw (`torch.LongTensor` of shape `(num_images, 3)`, *optional*):
|
| 1352 |
+
The temporal, height and width of feature shape of each image in LLM.
|
| 1353 |
+
"""
|
| 1354 |
+
return self.model.get_image_features(pixel_values, image_grid_thw, **kwargs)
|
| 1355 |
+
|
| 1356 |
+
@can_return_tuple
|
| 1357 |
+
def forward(
|
| 1358 |
+
self,
|
| 1359 |
+
input_ids: torch.LongTensor = None,
|
| 1360 |
+
attention_mask: torch.Tensor | None = None,
|
| 1361 |
+
position_ids: torch.LongTensor | None = None,
|
| 1362 |
+
past_key_values: Cache | None = None,
|
| 1363 |
+
inputs_embeds: torch.FloatTensor | None = None,
|
| 1364 |
+
labels: torch.LongTensor | None = None,
|
| 1365 |
+
pixel_values: torch.Tensor | None = None,
|
| 1366 |
+
pixel_values_videos: torch.FloatTensor | None = None,
|
| 1367 |
+
image_grid_thw: torch.LongTensor | None = None,
|
| 1368 |
+
video_grid_thw: torch.LongTensor | None = None,
|
| 1369 |
+
mm_token_type_ids: torch.IntTensor | None = None,
|
| 1370 |
+
logits_to_keep: int | torch.Tensor = 0,
|
| 1371 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 1372 |
+
) -> tuple | Qwen3VLCausalLMOutputWithPast:
|
| 1373 |
+
r"""
|
| 1374 |
+
labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):
|
| 1375 |
+
Labels for computing the masked language modeling loss. Indices should either be in `[0, ...,
|
| 1376 |
+
config.vocab_size]` or -100 (see `input_ids` docstring). Tokens with indices set to `-100` are ignored
|
| 1377 |
+
(masked), the loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]`.
|
| 1378 |
+
image_grid_thw (`torch.LongTensor` of shape `(num_images, 3)`, *optional*):
|
| 1379 |
+
The temporal, height and width of feature shape of each image in LLM.
|
| 1380 |
+
video_grid_thw (`torch.LongTensor` of shape `(num_videos, 3)`, *optional*):
|
| 1381 |
+
The temporal, height and width of feature shape of each video in LLM.
|
| 1382 |
+
|
| 1383 |
+
Example:
|
| 1384 |
+
|
| 1385 |
+
```python
|
| 1386 |
+
>>> from transformers import AutoProcessor, Qwen3VLForConditionalGeneration
|
| 1387 |
+
|
| 1388 |
+
>>> model = Qwen3VLForConditionalGeneration.from_pretrained("Qwen/Qwen3-VL-8B-Instruct")
|
| 1389 |
+
>>> processor = AutoProcessor.from_pretrained("Qwen/Qwen3-VL-8B-Instruct")
|
| 1390 |
+
|
| 1391 |
+
>>> messages = [
|
| 1392 |
+
{
|
| 1393 |
+
"role": "user",
|
| 1394 |
+
"content": [
|
| 1395 |
+
{
|
| 1396 |
+
"type": "image",
|
| 1397 |
+
"image": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/pipeline-cat-chonk.jpeg",
|
| 1398 |
+
},
|
| 1399 |
+
{"type": "text", "text": "Describe the image."},
|
| 1400 |
+
],
|
| 1401 |
+
}
|
| 1402 |
+
]
|
| 1403 |
+
|
| 1404 |
+
>>> inputs = processor.apply_chat_template(
|
| 1405 |
+
messages,
|
| 1406 |
+
tokenize=True,
|
| 1407 |
+
add_generation_prompt=True,
|
| 1408 |
+
return_dict=True,
|
| 1409 |
+
return_tensors="pt"
|
| 1410 |
+
)
|
| 1411 |
+
|
| 1412 |
+
>>> # Generate
|
| 1413 |
+
>>> generated_ids = model.generate(**inputs, max_new_tokens=1024)
|
| 1414 |
+
>>> generated_ids_trimmed = [out_ids[len(in_ids) :] for in_ids, out_ids in zip(inputs.input_ids, generated_ids)]
|
| 1415 |
+
>>> output_text = processor.batch_decode(generated_ids_trimmed, skip_special_tokens=True, clean_up_tokenization_spaces=False)[0]
|
| 1416 |
+
>>> print(output_text)
|
| 1417 |
+
```
|
| 1418 |
+
"""
|
| 1419 |
+
|
| 1420 |
+
outputs = self.model(
|
| 1421 |
+
input_ids=input_ids,
|
| 1422 |
+
pixel_values=pixel_values,
|
| 1423 |
+
pixel_values_videos=pixel_values_videos,
|
| 1424 |
+
image_grid_thw=image_grid_thw,
|
| 1425 |
+
video_grid_thw=video_grid_thw,
|
| 1426 |
+
position_ids=position_ids,
|
| 1427 |
+
attention_mask=attention_mask,
|
| 1428 |
+
past_key_values=past_key_values,
|
| 1429 |
+
inputs_embeds=inputs_embeds,
|
| 1430 |
+
mm_token_type_ids=mm_token_type_ids,
|
| 1431 |
+
**kwargs,
|
| 1432 |
+
)
|
| 1433 |
+
|
| 1434 |
+
hidden_states = outputs[0]
|
| 1435 |
+
|
| 1436 |
+
# Only compute necessary logits, and do not upcast them to float if we are not computing the loss
|
| 1437 |
+
slice_indices = slice(-logits_to_keep, None) if isinstance(logits_to_keep, int) else logits_to_keep
|
| 1438 |
+
logits = self.lm_head(hidden_states[:, slice_indices, :])
|
| 1439 |
+
|
| 1440 |
+
loss = None
|
| 1441 |
+
if labels is not None:
|
| 1442 |
+
loss = self.loss_function(logits=logits, labels=labels, vocab_size=self.config.text_config.vocab_size)
|
| 1443 |
+
|
| 1444 |
+
return Qwen3VLCausalLMOutputWithPast(
|
| 1445 |
+
loss=loss,
|
| 1446 |
+
logits=logits,
|
| 1447 |
+
past_key_values=outputs.past_key_values,
|
| 1448 |
+
hidden_states=outputs.hidden_states,
|
| 1449 |
+
attentions=outputs.attentions,
|
| 1450 |
+
rope_deltas=outputs.rope_deltas,
|
| 1451 |
+
)
|
| 1452 |
+
|
| 1453 |
+
def prepare_inputs_for_generation(
|
| 1454 |
+
self,
|
| 1455 |
+
input_ids,
|
| 1456 |
+
past_key_values=None,
|
| 1457 |
+
attention_mask=None,
|
| 1458 |
+
inputs_embeds=None,
|
| 1459 |
+
position_ids=None,
|
| 1460 |
+
use_cache=True,
|
| 1461 |
+
pixel_values=None,
|
| 1462 |
+
pixel_values_videos=None,
|
| 1463 |
+
image_grid_thw=None,
|
| 1464 |
+
video_grid_thw=None,
|
| 1465 |
+
is_first_iteration=False,
|
| 1466 |
+
**kwargs,
|
| 1467 |
+
):
|
| 1468 |
+
# Overwritten -- in specific circumstances we don't want to forward image inputs to the model
|
| 1469 |
+
|
| 1470 |
+
model_inputs = super().prepare_inputs_for_generation(
|
| 1471 |
+
input_ids,
|
| 1472 |
+
past_key_values=past_key_values,
|
| 1473 |
+
attention_mask=attention_mask,
|
| 1474 |
+
inputs_embeds=inputs_embeds,
|
| 1475 |
+
position_ids=position_ids,
|
| 1476 |
+
pixel_values=pixel_values,
|
| 1477 |
+
pixel_values_videos=pixel_values_videos,
|
| 1478 |
+
image_grid_thw=image_grid_thw,
|
| 1479 |
+
video_grid_thw=video_grid_thw,
|
| 1480 |
+
use_cache=use_cache,
|
| 1481 |
+
is_first_iteration=is_first_iteration,
|
| 1482 |
+
**kwargs,
|
| 1483 |
+
)
|
| 1484 |
+
|
| 1485 |
+
if not is_first_iteration and use_cache:
|
| 1486 |
+
model_inputs["pixel_values"] = None
|
| 1487 |
+
model_inputs["pixel_values_videos"] = None
|
| 1488 |
+
|
| 1489 |
+
return model_inputs
|
| 1490 |
+
|
| 1491 |
+
def _prepare_position_ids_for_generation(self, inputs_tensor, model_kwargs):
|
| 1492 |
+
# Overwritten -- requires 3D position ids
|
| 1493 |
+
|
| 1494 |
+
text_positions = super()._prepare_position_ids_for_generation(inputs_tensor, model_kwargs)
|
| 1495 |
+
|
| 1496 |
+
# Early exit in case we are continuing generation from past kv
|
| 1497 |
+
past_length = 0
|
| 1498 |
+
if (cache := model_kwargs.get("past_key_values")) is not None:
|
| 1499 |
+
past_length = cache.get_seq_length()
|
| 1500 |
+
if past_length != 0 and self.model.rope_deltas is not None:
|
| 1501 |
+
position_ids = text_positions[None, ...] + self.model.rope_deltas
|
| 1502 |
+
return position_ids
|
| 1503 |
+
|
| 1504 |
+
# Otherwise compute 3d position ids for vision tokens and concat with text position ids
|
| 1505 |
+
if "input_ids" in model_kwargs and model_kwargs["input_ids"].shape[1] > 0:
|
| 1506 |
+
inputs_tensor = model_kwargs["input_ids"]
|
| 1507 |
+
|
| 1508 |
+
is_input_ids = len(inputs_tensor.shape) == 2 and inputs_tensor.dtype in [torch.int, torch.long]
|
| 1509 |
+
if (
|
| 1510 |
+
is_input_ids
|
| 1511 |
+
and model_kwargs.get("mm_token_type_ids") is not None
|
| 1512 |
+
and (model_kwargs.get("image_grid_thw") is not None or model_kwargs.get("video_grid_thw") is not None)
|
| 1513 |
+
):
|
| 1514 |
+
model_kwargs = {k: v for k, v in model_kwargs.items() if k != "input_ids"}
|
| 1515 |
+
vision_positions, rope_deltas = self.model.get_rope_index(inputs_tensor, **model_kwargs)
|
| 1516 |
+
self.model.rope_deltas = rope_deltas
|
| 1517 |
+
else:
|
| 1518 |
+
vision_positions = text_positions.unsqueeze(0).expand(3, -1, -1)
|
| 1519 |
+
self.model.rope_deltas = torch.zeros(
|
| 1520 |
+
inputs_tensor.shape[0], 1, dtype=torch.long, device=inputs_tensor.device
|
| 1521 |
+
)
|
| 1522 |
+
|
| 1523 |
+
# Concatenate "text + vision" positions into [4, bs, seq-len]
|
| 1524 |
+
text_positions = text_positions[None, ...]
|
| 1525 |
+
position_ids = torch.cat([text_positions, vision_positions], dim=0)
|
| 1526 |
+
|
| 1527 |
+
return position_ids
|
| 1528 |
+
|
| 1529 |
+
def _get_image_nums_and_video_nums(
|
| 1530 |
+
self,
|
| 1531 |
+
input_ids: torch.LongTensor | None,
|
| 1532 |
+
inputs_embeds: torch.Tensor | None = None,
|
| 1533 |
+
) -> tuple[torch.Tensor, torch.Tensor]:
|
| 1534 |
+
"""
|
| 1535 |
+
Get the number of images and videos for each sample to calculate the separation length of the sample tensor.
|
| 1536 |
+
These parameters are not passed through the processor to avoid unpredictable impacts from interface modifications.
|
| 1537 |
+
|
| 1538 |
+
Args:
|
| 1539 |
+
input_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`):
|
| 1540 |
+
Indices of input sequence tokens in the vocabulary.
|
| 1541 |
+
|
| 1542 |
+
Returns:
|
| 1543 |
+
image_nums (`torch.LongTensor` of shape `(batch_size, num_images_sample)`)
|
| 1544 |
+
video_nums (`torch.LongTensor` of shape `(batch_size, num_videos_sample)`)
|
| 1545 |
+
"""
|
| 1546 |
+
image_token_id = self.config.image_token_id
|
| 1547 |
+
video_token_id = self.config.video_token_id
|
| 1548 |
+
vision_start_token_id = self.config.vision_start_token_id
|
| 1549 |
+
|
| 1550 |
+
if inputs_embeds is not None:
|
| 1551 |
+
vision_start_mask = (
|
| 1552 |
+
inputs_embeds
|
| 1553 |
+
== self.get_input_embeddings()(
|
| 1554 |
+
torch.tensor(vision_start_token_id, dtype=torch.long, device=inputs_embeds.device)
|
| 1555 |
+
)
|
| 1556 |
+
)[..., 0]
|
| 1557 |
+
image_mask = (
|
| 1558 |
+
inputs_embeds
|
| 1559 |
+
== self.get_input_embeddings()(
|
| 1560 |
+
torch.tensor(image_token_id, dtype=torch.long, device=inputs_embeds.device)
|
| 1561 |
+
)
|
| 1562 |
+
)[..., 0]
|
| 1563 |
+
video_mask = (
|
| 1564 |
+
inputs_embeds
|
| 1565 |
+
== self.get_input_embeddings()(
|
| 1566 |
+
torch.tensor(video_token_id, dtype=torch.long, device=inputs_embeds.device)
|
| 1567 |
+
)
|
| 1568 |
+
)[..., 0]
|
| 1569 |
+
else:
|
| 1570 |
+
vision_start_mask = input_ids == vision_start_token_id
|
| 1571 |
+
image_mask = input_ids == image_token_id
|
| 1572 |
+
video_mask = input_ids == video_token_id
|
| 1573 |
+
|
| 1574 |
+
vision_first_mask = torch.roll(vision_start_mask, shifts=1, dims=1)
|
| 1575 |
+
image_nums = torch.sum(vision_first_mask & image_mask, dim=1)
|
| 1576 |
+
video_nums = torch.sum(vision_first_mask & video_mask, dim=1)
|
| 1577 |
+
|
| 1578 |
+
return image_nums, video_nums
|
| 1579 |
+
|
| 1580 |
+
def _expand_inputs_for_generation(
|
| 1581 |
+
self,
|
| 1582 |
+
expand_size: int = 1,
|
| 1583 |
+
is_encoder_decoder: bool = False,
|
| 1584 |
+
input_ids: torch.LongTensor | None = None,
|
| 1585 |
+
**model_kwargs,
|
| 1586 |
+
) -> tuple[torch.LongTensor, dict[str, Any]]:
|
| 1587 |
+
# Overwritten -- Qwen3VL use timestamps and remove second_per_grid_ts
|
| 1588 |
+
# Support for expanding tensors without a batch size dimension
|
| 1589 |
+
# e.g., pixel_values, image_grid_thw, pixel_values_videos, video_grid_thw
|
| 1590 |
+
# pixel_values.shape[0] is sum(seqlen_images for samples)
|
| 1591 |
+
# image_grid_thw.shape[0] is sum(num_images for samples)
|
| 1592 |
+
|
| 1593 |
+
if expand_size == 1:
|
| 1594 |
+
return input_ids, model_kwargs
|
| 1595 |
+
|
| 1596 |
+
visual_keys = ["pixel_values", "image_grid_thw", "pixel_values_videos", "video_grid_thw"]
|
| 1597 |
+
|
| 1598 |
+
def _expand_dict_for_generation_visual(dict_to_expand):
|
| 1599 |
+
image_grid_thw = model_kwargs.get("image_grid_thw", None)
|
| 1600 |
+
video_grid_thw = model_kwargs.get("video_grid_thw", None)
|
| 1601 |
+
image_nums, video_nums = self._get_image_nums_and_video_nums(
|
| 1602 |
+
input_ids, inputs_embeds=model_kwargs.get("inputs_embeds", None)
|
| 1603 |
+
)
|
| 1604 |
+
|
| 1605 |
+
# video_nums: (batch_size,)
|
| 1606 |
+
# since video_nums is the number of videos in the input dependent on the input_ids(vision_start),
|
| 1607 |
+
# but qwen3vl append vision_start to each frame of each video, so we need to recover the real video_nums according to video_grid_thw
|
| 1608 |
+
if video_grid_thw is not None:
|
| 1609 |
+
cumulative_frame_counts = torch.cumsum(video_grid_thw[:, 0], dim=0)
|
| 1610 |
+
cumulative_token_video_counts = torch.cumsum(video_nums, dim=0)
|
| 1611 |
+
# Find video boundaries in cumulative_frame_counts
|
| 1612 |
+
video_boundary_indices = torch.searchsorted(cumulative_frame_counts, cumulative_token_video_counts)
|
| 1613 |
+
# example: video_boundary_indices = [3, 5] means video_nums = [4, 2]
|
| 1614 |
+
video_nums = torch.diff(torch.cat([-video_boundary_indices.new_ones(1), video_boundary_indices]))
|
| 1615 |
+
|
| 1616 |
+
def _repeat_interleave_samples(x, lengths, repeat_times):
|
| 1617 |
+
samples = torch.split(x, lengths)
|
| 1618 |
+
repeat_args = [repeat_times] + [1] * (x.dim() - 1)
|
| 1619 |
+
result = torch.cat([sample.repeat(*repeat_args) for sample in samples], dim=0)
|
| 1620 |
+
return result
|
| 1621 |
+
|
| 1622 |
+
for key in dict_to_expand:
|
| 1623 |
+
if key == "pixel_values":
|
| 1624 |
+
# split images into samples
|
| 1625 |
+
samples = torch.split(image_grid_thw, list(image_nums))
|
| 1626 |
+
# compute the sequence length of images for each sample
|
| 1627 |
+
lengths = [torch.prod(sample, dim=1).sum() for sample in samples]
|
| 1628 |
+
dict_to_expand[key] = _repeat_interleave_samples(
|
| 1629 |
+
dict_to_expand[key], lengths=lengths, repeat_times=expand_size
|
| 1630 |
+
)
|
| 1631 |
+
elif key == "image_grid_thw":
|
| 1632 |
+
# get the num of images for each sample
|
| 1633 |
+
lengths = list(image_nums)
|
| 1634 |
+
dict_to_expand[key] = _repeat_interleave_samples(
|
| 1635 |
+
dict_to_expand[key], lengths=lengths, repeat_times=expand_size
|
| 1636 |
+
)
|
| 1637 |
+
elif key == "pixel_values_videos":
|
| 1638 |
+
samples = torch.split(video_grid_thw, list(video_nums))
|
| 1639 |
+
lengths = [torch.prod(sample, dim=1).sum() for sample in samples]
|
| 1640 |
+
dict_to_expand[key] = _repeat_interleave_samples(
|
| 1641 |
+
dict_to_expand[key], lengths=lengths, repeat_times=expand_size
|
| 1642 |
+
)
|
| 1643 |
+
elif key == "video_grid_thw":
|
| 1644 |
+
lengths = list(video_nums)
|
| 1645 |
+
dict_to_expand[key] = _repeat_interleave_samples(
|
| 1646 |
+
dict_to_expand[key], lengths=lengths, repeat_times=expand_size
|
| 1647 |
+
)
|
| 1648 |
+
return dict_to_expand
|
| 1649 |
+
|
| 1650 |
+
def _expand_dict_for_generation(dict_to_expand):
|
| 1651 |
+
for key in dict_to_expand:
|
| 1652 |
+
if key == "position_ids" and dict_to_expand[key].ndim == 3:
|
| 1653 |
+
dict_to_expand[key] = dict_to_expand[key].repeat_interleave(expand_size, dim=1)
|
| 1654 |
+
elif (
|
| 1655 |
+
dict_to_expand[key] is not None
|
| 1656 |
+
and isinstance(dict_to_expand[key], torch.Tensor)
|
| 1657 |
+
and key not in visual_keys
|
| 1658 |
+
):
|
| 1659 |
+
dict_to_expand[key] = dict_to_expand[key].repeat_interleave(expand_size, dim=0)
|
| 1660 |
+
return dict_to_expand
|
| 1661 |
+
|
| 1662 |
+
model_kwargs = _expand_dict_for_generation_visual(model_kwargs)
|
| 1663 |
+
|
| 1664 |
+
if input_ids is not None:
|
| 1665 |
+
input_ids = input_ids.repeat_interleave(expand_size, dim=0)
|
| 1666 |
+
|
| 1667 |
+
model_kwargs = _expand_dict_for_generation(model_kwargs)
|
| 1668 |
+
|
| 1669 |
+
if is_encoder_decoder:
|
| 1670 |
+
if model_kwargs.get("encoder_outputs") is None:
|
| 1671 |
+
raise ValueError("If `is_encoder_decoder` is True, make sure that `encoder_outputs` is defined.")
|
| 1672 |
+
model_kwargs["encoder_outputs"] = _expand_dict_for_generation(model_kwargs["encoder_outputs"])
|
| 1673 |
+
|
| 1674 |
+
return input_ids, model_kwargs
|
| 1675 |
+
|
| 1676 |
+
|
| 1677 |
+
__all__ = [
|
| 1678 |
+
"Qwen3VLVisionModel",
|
| 1679 |
+
"Qwen3VLForConditionalGeneration",
|
| 1680 |
+
"Qwen3VLModel",
|
| 1681 |
+
"Qwen3VLPreTrainedModel",
|
| 1682 |
+
"Qwen3VLTextModel",
|
| 1683 |
+
]
|