JinghuiLuAstronaut commited on
Commit
3adf19f
·
verified ·
1 Parent(s): 860a3d6

Add files using upload-large-folder tool

Browse files
Files changed (20) hide show
  1. LTA_openwebtext_dualt/logs/lm1b_len128_lognormal_atoms_sde_watch/infer_lta_lm1b_classic_c1024_len128_lognormalatoms_gbs512_4gpu_20260522_step_0041000_logistic_normal_t1p45.log +76 -0
  2. LTA_openwebtext_dualt/logs/lm1b_len128_lognormal_atoms_sde_watch/infer_lta_lm1b_classic_c1024_len128_lognormalatoms_gbs512_4gpu_20260522_step_0044000_logistic_normal_t1p45.log +76 -0
  3. LTA_openwebtext_dualt/logs/lm1b_len128_lognormal_atoms_sde_watch/infer_lta_lm1b_classic_c1024_len128_lognormalatoms_gbs512_4gpu_20260522_step_0058000_logistic_normal_t1p45.log +76 -0
  4. LTA_openwebtext_dualt/logs/lm1b_len128_lognormal_atoms_sde_watch/infer_lta_lm1b_classic_c1024_len128_lognormalatoms_gbs512_4gpu_20260522_step_0078000_logistic_normal_t1p45.log +76 -0
  5. LTA_openwebtext_dualt/logs/lm1b_len128_lognormal_atoms_sde_watch/infer_lta_lm1b_classic_c1024_len128_lognormalatoms_gbs512_4gpu_20260522_step_0100000_logistic_normal_t1p45.log +76 -0
  6. LTA_openwebtext_dualt/logs/lm1b_len128_lognormal_atoms_sde_watch/infer_lta_lm1b_classic_c1024_len128_lognormalatoms_gbs512_4gpu_20260522_step_0111000_logistic_normal_t1p45.log +76 -0
  7. LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/transformers/models/grounding_dino/__init__.py +30 -0
  8. LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/transformers/models/grounding_dino/configuration_grounding_dino.py +154 -0
  9. LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/transformers/models/grounding_dino/image_processing_grounding_dino.py +740 -0
  10. LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/transformers/models/grounding_dino/image_processing_pil_grounding_dino.py +770 -0
  11. LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/transformers/models/grounding_dino/modeling_grounding_dino.py +0 -0
  12. LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/transformers/models/grounding_dino/modular_grounding_dino.py +201 -0
  13. LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/transformers/models/grounding_dino/processing_grounding_dino.py +236 -0
  14. LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/transformers/models/paddleocr_vl/image_processing_pil_paddleocr_vl.py +251 -0
  15. LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/transformers/models/paddleocr_vl/modular_paddleocr_vl.py +1166 -0
  16. LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/transformers/models/phi/__init__.py +27 -0
  17. LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/transformers/models/phi/configuration_phi.py +92 -0
  18. LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/transformers/models/phi/modeling_phi.py +494 -0
  19. LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/transformers/models/phi/modular_phi.py +288 -0
  20. LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/transformers/models/wav2vec2/tokenization_wav2vec2.py +653 -0
LTA_openwebtext_dualt/logs/lm1b_len128_lognormal_atoms_sde_watch/infer_lta_lm1b_classic_c1024_len128_lognormalatoms_gbs512_4gpu_20260522_step_0041000_logistic_normal_t1p45.log ADDED
@@ -0,0 +1,76 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [watch-lognormal-sde] 2026-05-23_02:22:41 infer runs/lta_lm1b_classic_c1024_len128_lognormalatoms_gbs512_4gpu_20260522/step_0041000.pt -> docs/lta_samples/metrics_20260522/lm1b_len128_lognormal_atoms_every1k_logistic_normal_sde_t1p45_steps128_n256/lta_lm1b_classic_c1024_len128_lognormalatoms_gbs512_4gpu_20260522/step_0041000
2
+ [load] runs/lta_lm1b_classic_c1024_len128_lognormalatoms_gbs512_4gpu_20260522/step_0041000.pt
3
+ [ckpt] step=41000
4
+ [sde] generated 16/256
5
+ [sde] generated 32/256
6
+ [sde] generated 48/256
7
+ [sde] generated 64/256
8
+ [sde] generated 80/256
9
+ [sde] generated 96/256
10
+ [sde] generated 112/256
11
+ [sde] generated 128/256
12
+ [sde] generated 144/256
13
+ [sde] generated 160/256
14
+ [sde] generated 176/256
15
+ [sde] generated 192/256
16
+ [sde] generated 208/256
17
+ [sde] generated 224/256
18
+ [sde] generated 240/256
19
+ [sde] generated 256/256
20
+ [score] loading scorer: /e2e-data/evad-tech-vla/wanghan58/models/flowtext_scorers/gpt2-large-standard
21
+ [summary] {
22
+ "type": "summary",
23
+ "checkpoint": "runs/lta_lm1b_classic_c1024_len128_lognormalatoms_gbs512_4gpu_20260522/step_0041000.pt",
24
+ "step": 41000,
25
+ "decode": {
26
+ "decode_rule": "logistic_normal_resample_sde",
27
+ "steps": 128,
28
+ "model_t_mode": "const0.5",
29
+ "mean_mode": "anchor_semantic",
30
+ "endpoint_floor": 0.0,
31
+ "concentration_min": 1.0,
32
+ "concentration_max": 1024.0,
33
+ "endpoint_temp": 1.45,
34
+ "support_power": 1.0,
35
+ "semantic_power": 1.0,
36
+ "noise_init": "logistic_normal",
37
+ "noise_sigma": 3.0,
38
+ "noise_dirichlet_concentration": 1.0,
39
+ "sde_resample": "logistic_normal",
40
+ "logistic_normal_sigma_min": 0.18,
41
+ "logistic_normal_sigma_max": 3.0,
42
+ "logistic_normal_tau_min": 0.65,
43
+ "logistic_normal_tau_max": 1.0,
44
+ "final_from": "blend_0.5",
45
+ "n_samples": 256,
46
+ "seed": 20260522
47
+ },
48
+ "raw_genppl": {
49
+ "ppl": 31.959699001405166,
50
+ "nll_per_token": 3.4644757028751627,
51
+ "tokens": 33772,
52
+ "kept_samples": 256,
53
+ "total_samples": 256,
54
+ "empty_rate": 0.0,
55
+ "skipped_samples": 0
56
+ },
57
+ "stripped_genppl": {
58
+ "ppl": 43.125531460957724,
59
+ "nll_per_token": 3.7641151990079402,
60
+ "tokens": 28054,
61
+ "kept_samples": 256,
62
+ "total_samples": 256,
63
+ "empty_rate": 0.0,
64
+ "skipped_samples": 0
65
+ },
66
+ "diversity": {
67
+ "sample_entropy": 3.479193027152298,
68
+ "unique_tokens": 1853,
69
+ "token_count": 32768,
70
+ "distinct_1": 0.056549072265625,
71
+ "distinct_2": 0.27079232283464566,
72
+ "top_token_mass": 0.1614990234375
73
+ }
74
+ }
75
+ [done] docs/lta_samples/metrics_20260522/lm1b_len128_lognormal_atoms_every1k_logistic_normal_sde_t1p45_steps128_n256/lta_lm1b_classic_c1024_len128_lognormalatoms_gbs512_4gpu_20260522/step_0041000/sde_steps128_samples256_scored.jsonl
76
+ [watch-lognormal-sde] 2026-05-23_02:24:08 done step_0041000
LTA_openwebtext_dualt/logs/lm1b_len128_lognormal_atoms_sde_watch/infer_lta_lm1b_classic_c1024_len128_lognormalatoms_gbs512_4gpu_20260522_step_0044000_logistic_normal_t1p45.log ADDED
@@ -0,0 +1,76 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [watch-lognormal-sde] 2026-05-23_02:39:50 infer runs/lta_lm1b_classic_c1024_len128_lognormalatoms_gbs512_4gpu_20260522/step_0044000.pt -> docs/lta_samples/metrics_20260522/lm1b_len128_lognormal_atoms_every1k_logistic_normal_sde_t1p45_steps128_n256/lta_lm1b_classic_c1024_len128_lognormalatoms_gbs512_4gpu_20260522/step_0044000
2
+ [load] runs/lta_lm1b_classic_c1024_len128_lognormalatoms_gbs512_4gpu_20260522/step_0044000.pt
3
+ [ckpt] step=44000
4
+ [sde] generated 16/256
5
+ [sde] generated 32/256
6
+ [sde] generated 48/256
7
+ [sde] generated 64/256
8
+ [sde] generated 80/256
9
+ [sde] generated 96/256
10
+ [sde] generated 112/256
11
+ [sde] generated 128/256
12
+ [sde] generated 144/256
13
+ [sde] generated 160/256
14
+ [sde] generated 176/256
15
+ [sde] generated 192/256
16
+ [sde] generated 208/256
17
+ [sde] generated 224/256
18
+ [sde] generated 240/256
19
+ [sde] generated 256/256
20
+ [score] loading scorer: /e2e-data/evad-tech-vla/wanghan58/models/flowtext_scorers/gpt2-large-standard
21
+ [summary] {
22
+ "type": "summary",
23
+ "checkpoint": "runs/lta_lm1b_classic_c1024_len128_lognormalatoms_gbs512_4gpu_20260522/step_0044000.pt",
24
+ "step": 44000,
25
+ "decode": {
26
+ "decode_rule": "logistic_normal_resample_sde",
27
+ "steps": 128,
28
+ "model_t_mode": "const0.5",
29
+ "mean_mode": "anchor_semantic",
30
+ "endpoint_floor": 0.0,
31
+ "concentration_min": 1.0,
32
+ "concentration_max": 1024.0,
33
+ "endpoint_temp": 1.45,
34
+ "support_power": 1.0,
35
+ "semantic_power": 1.0,
36
+ "noise_init": "logistic_normal",
37
+ "noise_sigma": 3.0,
38
+ "noise_dirichlet_concentration": 1.0,
39
+ "sde_resample": "logistic_normal",
40
+ "logistic_normal_sigma_min": 0.18,
41
+ "logistic_normal_sigma_max": 3.0,
42
+ "logistic_normal_tau_min": 0.65,
43
+ "logistic_normal_tau_max": 1.0,
44
+ "final_from": "blend_0.5",
45
+ "n_samples": 256,
46
+ "seed": 20260522
47
+ },
48
+ "raw_genppl": {
49
+ "ppl": 32.26168999125419,
50
+ "nll_per_token": 3.473880457910618,
51
+ "tokens": 37407,
52
+ "kept_samples": 256,
53
+ "total_samples": 256,
54
+ "empty_rate": 0.0,
55
+ "skipped_samples": 0
56
+ },
57
+ "stripped_genppl": {
58
+ "ppl": 45.33257688069376,
59
+ "nll_per_token": 3.814025910473437,
60
+ "tokens": 30936,
61
+ "kept_samples": 256,
62
+ "total_samples": 256,
63
+ "empty_rate": 0.0,
64
+ "skipped_samples": 0
65
+ },
66
+ "diversity": {
67
+ "sample_entropy": 3.762322860547607,
68
+ "unique_tokens": 2281,
69
+ "token_count": 32768,
70
+ "distinct_1": 0.069610595703125,
71
+ "distinct_2": 0.3466412401574803,
72
+ "top_token_mass": 0.08233642578125
73
+ }
74
+ }
75
+ [done] docs/lta_samples/metrics_20260522/lm1b_len128_lognormal_atoms_every1k_logistic_normal_sde_t1p45_steps128_n256/lta_lm1b_classic_c1024_len128_lognormalatoms_gbs512_4gpu_20260522/step_0044000/sde_steps128_samples256_scored.jsonl
76
+ [watch-lognormal-sde] 2026-05-23_02:41:18 done step_0044000
LTA_openwebtext_dualt/logs/lm1b_len128_lognormal_atoms_sde_watch/infer_lta_lm1b_classic_c1024_len128_lognormalatoms_gbs512_4gpu_20260522_step_0058000_logistic_normal_t1p45.log ADDED
@@ -0,0 +1,76 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [watch-lognormal-sde] 2026-05-23_03:57:25 infer runs/lta_lm1b_classic_c1024_len128_lognormalatoms_gbs512_4gpu_20260522/step_0058000.pt -> docs/lta_samples/metrics_20260522/lm1b_len128_lognormal_atoms_every1k_logistic_normal_sde_t1p45_steps128_n256/lta_lm1b_classic_c1024_len128_lognormalatoms_gbs512_4gpu_20260522/step_0058000
2
+ [load] runs/lta_lm1b_classic_c1024_len128_lognormalatoms_gbs512_4gpu_20260522/step_0058000.pt
3
+ [ckpt] step=58000
4
+ [sde] generated 16/256
5
+ [sde] generated 32/256
6
+ [sde] generated 48/256
7
+ [sde] generated 64/256
8
+ [sde] generated 80/256
9
+ [sde] generated 96/256
10
+ [sde] generated 112/256
11
+ [sde] generated 128/256
12
+ [sde] generated 144/256
13
+ [sde] generated 160/256
14
+ [sde] generated 176/256
15
+ [sde] generated 192/256
16
+ [sde] generated 208/256
17
+ [sde] generated 224/256
18
+ [sde] generated 240/256
19
+ [sde] generated 256/256
20
+ [score] loading scorer: /e2e-data/evad-tech-vla/wanghan58/models/flowtext_scorers/gpt2-large-standard
21
+ [summary] {
22
+ "type": "summary",
23
+ "checkpoint": "runs/lta_lm1b_classic_c1024_len128_lognormalatoms_gbs512_4gpu_20260522/step_0058000.pt",
24
+ "step": 58000,
25
+ "decode": {
26
+ "decode_rule": "logistic_normal_resample_sde",
27
+ "steps": 128,
28
+ "model_t_mode": "const0.5",
29
+ "mean_mode": "anchor_semantic",
30
+ "endpoint_floor": 0.0,
31
+ "concentration_min": 1.0,
32
+ "concentration_max": 1024.0,
33
+ "endpoint_temp": 1.45,
34
+ "support_power": 1.0,
35
+ "semantic_power": 1.0,
36
+ "noise_init": "logistic_normal",
37
+ "noise_sigma": 3.0,
38
+ "noise_dirichlet_concentration": 1.0,
39
+ "sde_resample": "logistic_normal",
40
+ "logistic_normal_sigma_min": 0.18,
41
+ "logistic_normal_sigma_max": 3.0,
42
+ "logistic_normal_tau_min": 0.65,
43
+ "logistic_normal_tau_max": 1.0,
44
+ "final_from": "blend_0.5",
45
+ "n_samples": 256,
46
+ "seed": 20260522
47
+ },
48
+ "raw_genppl": {
49
+ "ppl": 22.644016386381047,
50
+ "nll_per_token": 3.1198956398263795,
51
+ "tokens": 29279,
52
+ "kept_samples": 256,
53
+ "total_samples": 256,
54
+ "empty_rate": 0.0,
55
+ "skipped_samples": 0
56
+ },
57
+ "stripped_genppl": {
58
+ "ppl": 25.275855534336973,
59
+ "nll_per_token": 3.229849613367773,
60
+ "tokens": 25192,
61
+ "kept_samples": 256,
62
+ "total_samples": 256,
63
+ "empty_rate": 0.0,
64
+ "skipped_samples": 0
65
+ },
66
+ "diversity": {
67
+ "sample_entropy": 2.5701193369342867,
68
+ "unique_tokens": 1509,
69
+ "token_count": 32768,
70
+ "distinct_1": 0.046051025390625,
71
+ "distinct_2": 0.22038016732283464,
72
+ "top_token_mass": 0.255035400390625
73
+ }
74
+ }
75
+ [done] docs/lta_samples/metrics_20260522/lm1b_len128_lognormal_atoms_every1k_logistic_normal_sde_t1p45_steps128_n256/lta_lm1b_classic_c1024_len128_lognormalatoms_gbs512_4gpu_20260522/step_0058000/sde_steps128_samples256_scored.jsonl
76
+ [watch-lognormal-sde] 2026-05-23_03:58:53 done step_0058000
LTA_openwebtext_dualt/logs/lm1b_len128_lognormal_atoms_sde_watch/infer_lta_lm1b_classic_c1024_len128_lognormalatoms_gbs512_4gpu_20260522_step_0078000_logistic_normal_t1p45.log ADDED
@@ -0,0 +1,76 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [watch-lognormal-sde] 2026-05-23_05:49:24 infer runs/lta_lm1b_classic_c1024_len128_lognormalatoms_gbs512_4gpu_20260522/step_0078000.pt -> docs/lta_samples/metrics_20260522/lm1b_len128_lognormal_atoms_every1k_logistic_normal_sde_t1p45_steps128_n256/lta_lm1b_classic_c1024_len128_lognormalatoms_gbs512_4gpu_20260522/step_0078000
2
+ [load] runs/lta_lm1b_classic_c1024_len128_lognormalatoms_gbs512_4gpu_20260522/step_0078000.pt
3
+ [ckpt] step=78000
4
+ [sde] generated 16/256
5
+ [sde] generated 32/256
6
+ [sde] generated 48/256
7
+ [sde] generated 64/256
8
+ [sde] generated 80/256
9
+ [sde] generated 96/256
10
+ [sde] generated 112/256
11
+ [sde] generated 128/256
12
+ [sde] generated 144/256
13
+ [sde] generated 160/256
14
+ [sde] generated 176/256
15
+ [sde] generated 192/256
16
+ [sde] generated 208/256
17
+ [sde] generated 224/256
18
+ [sde] generated 240/256
19
+ [sde] generated 256/256
20
+ [score] loading scorer: /e2e-data/evad-tech-vla/wanghan58/models/flowtext_scorers/gpt2-large-standard
21
+ [summary] {
22
+ "type": "summary",
23
+ "checkpoint": "runs/lta_lm1b_classic_c1024_len128_lognormalatoms_gbs512_4gpu_20260522/step_0078000.pt",
24
+ "step": 78000,
25
+ "decode": {
26
+ "decode_rule": "logistic_normal_resample_sde",
27
+ "steps": 128,
28
+ "model_t_mode": "const0.5",
29
+ "mean_mode": "anchor_semantic",
30
+ "endpoint_floor": 0.0,
31
+ "concentration_min": 1.0,
32
+ "concentration_max": 1024.0,
33
+ "endpoint_temp": 1.45,
34
+ "support_power": 1.0,
35
+ "semantic_power": 1.0,
36
+ "noise_init": "logistic_normal",
37
+ "noise_sigma": 3.0,
38
+ "noise_dirichlet_concentration": 1.0,
39
+ "sde_resample": "logistic_normal",
40
+ "logistic_normal_sigma_min": 0.18,
41
+ "logistic_normal_sigma_max": 3.0,
42
+ "logistic_normal_tau_min": 0.65,
43
+ "logistic_normal_tau_max": 1.0,
44
+ "final_from": "blend_0.5",
45
+ "n_samples": 256,
46
+ "seed": 20260522
47
+ },
48
+ "raw_genppl": {
49
+ "ppl": 35.235910671082934,
50
+ "nll_per_token": 3.5620657520837877,
51
+ "tokens": 34380,
52
+ "kept_samples": 256,
53
+ "total_samples": 256,
54
+ "empty_rate": 0.0,
55
+ "skipped_samples": 0
56
+ },
57
+ "stripped_genppl": {
58
+ "ppl": 47.37867967964612,
59
+ "nll_per_token": 3.858172331724505,
60
+ "tokens": 28780,
61
+ "kept_samples": 256,
62
+ "total_samples": 256,
63
+ "empty_rate": 0.0,
64
+ "skipped_samples": 0
65
+ },
66
+ "diversity": {
67
+ "sample_entropy": 3.532626321220521,
68
+ "unique_tokens": 1960,
69
+ "token_count": 32768,
70
+ "distinct_1": 0.059814453125,
71
+ "distinct_2": 0.30880905511811024,
72
+ "top_token_mass": 0.15240478515625
73
+ }
74
+ }
75
+ [done] docs/lta_samples/metrics_20260522/lm1b_len128_lognormal_atoms_every1k_logistic_normal_sde_t1p45_steps128_n256/lta_lm1b_classic_c1024_len128_lognormalatoms_gbs512_4gpu_20260522/step_0078000/sde_steps128_samples256_scored.jsonl
76
+ [watch-lognormal-sde] 2026-05-23_05:50:52 done step_0078000
LTA_openwebtext_dualt/logs/lm1b_len128_lognormal_atoms_sde_watch/infer_lta_lm1b_classic_c1024_len128_lognormalatoms_gbs512_4gpu_20260522_step_0100000_logistic_normal_t1p45.log ADDED
@@ -0,0 +1,76 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [watch-lognormal-sde] 2026-05-23_07:51:55 infer runs/lta_lm1b_classic_c1024_len128_lognormalatoms_gbs512_4gpu_20260522/step_0100000.pt -> docs/lta_samples/metrics_20260522/lm1b_len128_lognormal_atoms_every1k_logistic_normal_sde_t1p45_steps128_n256/lta_lm1b_classic_c1024_len128_lognormalatoms_gbs512_4gpu_20260522/step_0100000
2
+ [load] runs/lta_lm1b_classic_c1024_len128_lognormalatoms_gbs512_4gpu_20260522/step_0100000.pt
3
+ [ckpt] step=100000
4
+ [sde] generated 16/256
5
+ [sde] generated 32/256
6
+ [sde] generated 48/256
7
+ [sde] generated 64/256
8
+ [sde] generated 80/256
9
+ [sde] generated 96/256
10
+ [sde] generated 112/256
11
+ [sde] generated 128/256
12
+ [sde] generated 144/256
13
+ [sde] generated 160/256
14
+ [sde] generated 176/256
15
+ [sde] generated 192/256
16
+ [sde] generated 208/256
17
+ [sde] generated 224/256
18
+ [sde] generated 240/256
19
+ [sde] generated 256/256
20
+ [score] loading scorer: /e2e-data/evad-tech-vla/wanghan58/models/flowtext_scorers/gpt2-large-standard
21
+ [summary] {
22
+ "type": "summary",
23
+ "checkpoint": "runs/lta_lm1b_classic_c1024_len128_lognormalatoms_gbs512_4gpu_20260522/step_0100000.pt",
24
+ "step": 100000,
25
+ "decode": {
26
+ "decode_rule": "logistic_normal_resample_sde",
27
+ "steps": 128,
28
+ "model_t_mode": "const0.5",
29
+ "mean_mode": "anchor_semantic",
30
+ "endpoint_floor": 0.0,
31
+ "concentration_min": 1.0,
32
+ "concentration_max": 1024.0,
33
+ "endpoint_temp": 1.45,
34
+ "support_power": 1.0,
35
+ "semantic_power": 1.0,
36
+ "noise_init": "logistic_normal",
37
+ "noise_sigma": 3.0,
38
+ "noise_dirichlet_concentration": 1.0,
39
+ "sde_resample": "logistic_normal",
40
+ "logistic_normal_sigma_min": 0.18,
41
+ "logistic_normal_sigma_max": 3.0,
42
+ "logistic_normal_tau_min": 0.65,
43
+ "logistic_normal_tau_max": 1.0,
44
+ "final_from": "blend_0.5",
45
+ "n_samples": 256,
46
+ "seed": 20260522
47
+ },
48
+ "raw_genppl": {
49
+ "ppl": 35.66292183380407,
50
+ "nll_per_token": 3.574111544967498,
51
+ "tokens": 32921,
52
+ "kept_samples": 256,
53
+ "total_samples": 256,
54
+ "empty_rate": 0.0,
55
+ "skipped_samples": 0
56
+ },
57
+ "stripped_genppl": {
58
+ "ppl": 38.61847231433198,
59
+ "nll_per_token": 3.653730719364842,
60
+ "tokens": 29225,
61
+ "kept_samples": 256,
62
+ "total_samples": 256,
63
+ "empty_rate": 0.0,
64
+ "skipped_samples": 0
65
+ },
66
+ "diversity": {
67
+ "sample_entropy": 3.25356395377077,
68
+ "unique_tokens": 1911,
69
+ "token_count": 32768,
70
+ "distinct_1": 0.058319091796875,
71
+ "distinct_2": 0.3033033956692913,
72
+ "top_token_mass": 0.169097900390625
73
+ }
74
+ }
75
+ [done] docs/lta_samples/metrics_20260522/lm1b_len128_lognormal_atoms_every1k_logistic_normal_sde_t1p45_steps128_n256/lta_lm1b_classic_c1024_len128_lognormalatoms_gbs512_4gpu_20260522/step_0100000/sde_steps128_samples256_scored.jsonl
76
+ [watch-lognormal-sde] 2026-05-23_07:53:23 done step_0100000
LTA_openwebtext_dualt/logs/lm1b_len128_lognormal_atoms_sde_watch/infer_lta_lm1b_classic_c1024_len128_lognormalatoms_gbs512_4gpu_20260522_step_0111000_logistic_normal_t1p45.log ADDED
@@ -0,0 +1,76 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [watch-lognormal-sde] 2026-05-23_08:53:16 infer runs/lta_lm1b_classic_c1024_len128_lognormalatoms_gbs512_4gpu_20260522/step_0111000.pt -> docs/lta_samples/metrics_20260522/lm1b_len128_lognormal_atoms_every1k_logistic_normal_sde_t1p45_steps128_n256/lta_lm1b_classic_c1024_len128_lognormalatoms_gbs512_4gpu_20260522/step_0111000
2
+ [load] runs/lta_lm1b_classic_c1024_len128_lognormalatoms_gbs512_4gpu_20260522/step_0111000.pt
3
+ [ckpt] step=111000
4
+ [sde] generated 16/256
5
+ [sde] generated 32/256
6
+ [sde] generated 48/256
7
+ [sde] generated 64/256
8
+ [sde] generated 80/256
9
+ [sde] generated 96/256
10
+ [sde] generated 112/256
11
+ [sde] generated 128/256
12
+ [sde] generated 144/256
13
+ [sde] generated 160/256
14
+ [sde] generated 176/256
15
+ [sde] generated 192/256
16
+ [sde] generated 208/256
17
+ [sde] generated 224/256
18
+ [sde] generated 240/256
19
+ [sde] generated 256/256
20
+ [score] loading scorer: /e2e-data/evad-tech-vla/wanghan58/models/flowtext_scorers/gpt2-large-standard
21
+ [summary] {
22
+ "type": "summary",
23
+ "checkpoint": "runs/lta_lm1b_classic_c1024_len128_lognormalatoms_gbs512_4gpu_20260522/step_0111000.pt",
24
+ "step": 111000,
25
+ "decode": {
26
+ "decode_rule": "logistic_normal_resample_sde",
27
+ "steps": 128,
28
+ "model_t_mode": "const0.5",
29
+ "mean_mode": "anchor_semantic",
30
+ "endpoint_floor": 0.0,
31
+ "concentration_min": 1.0,
32
+ "concentration_max": 1024.0,
33
+ "endpoint_temp": 1.45,
34
+ "support_power": 1.0,
35
+ "semantic_power": 1.0,
36
+ "noise_init": "logistic_normal",
37
+ "noise_sigma": 3.0,
38
+ "noise_dirichlet_concentration": 1.0,
39
+ "sde_resample": "logistic_normal",
40
+ "logistic_normal_sigma_min": 0.18,
41
+ "logistic_normal_sigma_max": 3.0,
42
+ "logistic_normal_tau_min": 0.65,
43
+ "logistic_normal_tau_max": 1.0,
44
+ "final_from": "blend_0.5",
45
+ "n_samples": 256,
46
+ "seed": 20260522
47
+ },
48
+ "raw_genppl": {
49
+ "ppl": 34.896738285302064,
50
+ "nll_per_token": 3.5523933659669624,
51
+ "tokens": 32414,
52
+ "kept_samples": 256,
53
+ "total_samples": 256,
54
+ "empty_rate": 0.0,
55
+ "skipped_samples": 0
56
+ },
57
+ "stripped_genppl": {
58
+ "ppl": 46.54344449646717,
59
+ "nll_per_token": 3.8403861666624404,
60
+ "tokens": 27113,
61
+ "kept_samples": 256,
62
+ "total_samples": 256,
63
+ "empty_rate": 0.0,
64
+ "skipped_samples": 0
65
+ },
66
+ "diversity": {
67
+ "sample_entropy": 3.2532209789942637,
68
+ "unique_tokens": 2152,
69
+ "token_count": 32768,
70
+ "distinct_1": 0.065673828125,
71
+ "distinct_2": 0.32852485236220474,
72
+ "top_token_mass": 0.203338623046875
73
+ }
74
+ }
75
+ [done] docs/lta_samples/metrics_20260522/lm1b_len128_lognormal_atoms_every1k_logistic_normal_sde_t1p45_steps128_n256/lta_lm1b_classic_c1024_len128_lognormalatoms_gbs512_4gpu_20260522/step_0111000/sde_steps128_samples256_scored.jsonl
76
+ [watch-lognormal-sde] 2026-05-23_08:54:44 done step_0111000
LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/transformers/models/grounding_dino/__init__.py ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_grounding_dino import *
22
+ from .image_processing_grounding_dino import *
23
+ from .image_processing_pil_grounding_dino import *
24
+ from .modeling_grounding_dino import *
25
+ from .processing_grounding_dino import *
26
+ else:
27
+ import sys
28
+
29
+ _file = globals()["__file__"]
30
+ 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/grounding_dino/configuration_grounding_dino.py ADDED
@@ -0,0 +1,154 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2024 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
+ """Grounding DINO model configuration"""
15
+
16
+ from huggingface_hub.dataclasses import strict
17
+
18
+ from ...backbone_utils import consolidate_backbone_kwargs_to_config
19
+ from ...configuration_utils import PreTrainedConfig
20
+ from ...utils import auto_docstring, logging
21
+ from ..auto import CONFIG_MAPPING, AutoConfig
22
+
23
+
24
+ logger = logging.get_logger(__name__)
25
+
26
+
27
+ @auto_docstring(checkpoint="IDEA-Research/grounding-dino-tiny")
28
+ @strict
29
+ class GroundingDinoConfig(PreTrainedConfig):
30
+ r"""
31
+ num_queries (`int`, *optional*, defaults to 900):
32
+ Number of object queries, i.e. detection slots. This is the maximal number of objects
33
+ [`GroundingDinoModel`] can detect in a single image.
34
+ position_embedding_type (`str`, *optional*, defaults to `"sine"`):
35
+ Type of position embeddings to be used on top of the image features. One of `"sine"` or `"learned"`.
36
+ num_feature_levels (`int`, *optional*, defaults to 4):
37
+ The number of input feature levels.
38
+ encoder_n_points (`int`, *optional*, defaults to 4):
39
+ The number of sampled keys in each feature level for each attention head in the encoder.
40
+ decoder_n_points (`int`, *optional*, defaults to 4):
41
+ The number of sampled keys in each feature level for each attention head in the decoder.
42
+ two_stage (`bool`, *optional*, defaults to `True`):
43
+ Whether to apply a two-stage deformable DETR, where the region proposals are also generated by a variant of
44
+ Grounding DINO, which are further fed into the decoder for iterative bounding box refinement.
45
+ disable_custom_kernels (`bool`, *optional*, defaults to `False`):
46
+ Disable the use of custom CUDA and CPU kernels. This option is necessary for the ONNX export, as custom
47
+ kernels are not supported by PyTorch ONNX export.
48
+ max_text_len (`int`, *optional*, defaults to 256):
49
+ The maximum length of the text input.
50
+ text_enhancer_dropout (`float`, *optional*, defaults to 0.0):
51
+ The dropout ratio for the text enhancer.
52
+ fusion_droppath (`float`, *optional*, defaults to 0.1):
53
+ The droppath ratio for the fusion module.
54
+ fusion_dropout (`float`, *optional*, defaults to 0.0):
55
+ The dropout ratio for the fusion module.
56
+ embedding_init_target (`bool`, *optional*, defaults to `True`):
57
+ Whether to initialize the target with Embedding weights.
58
+ query_dim (`int`, *optional*, defaults to 4):
59
+ The dimension of the query vector.
60
+ decoder_bbox_embed_share (`bool`, *optional*, defaults to `True`):
61
+ Whether to share the bbox regression head for all decoder layers.
62
+ two_stage_bbox_embed_share (`bool`, *optional*, defaults to `False`):
63
+ Whether to share the bbox embedding between the two-stage bbox generator and the region proposal
64
+ generation.
65
+ positional_embedding_temperature (`float`, *optional*, defaults to 20):
66
+ The temperature for Sine Positional Embedding that is used together with vision backbone.
67
+
68
+ Examples:
69
+
70
+ ```python
71
+ >>> from transformers import GroundingDinoConfig, GroundingDinoModel
72
+
73
+ >>> # Initializing a Grounding DINO IDEA-Research/grounding-dino-tiny style configuration
74
+ >>> configuration = GroundingDinoConfig()
75
+
76
+ >>> # Initializing a model (with random weights) from the IDEA-Research/grounding-dino-tiny style configuration
77
+ >>> model = GroundingDinoModel(configuration)
78
+
79
+ >>> # Accessing the model configuration
80
+ >>> configuration = model.config
81
+ ```"""
82
+
83
+ model_type = "grounding-dino"
84
+ sub_configs = {"backbone_config": AutoConfig, "text_config": AutoConfig}
85
+ attribute_map = {
86
+ "hidden_size": "d_model",
87
+ "num_attention_heads": "encoder_attention_heads",
88
+ }
89
+
90
+ backbone_config: dict | PreTrainedConfig | None = None
91
+ text_config: dict | PreTrainedConfig | None = None
92
+ num_queries: int = 900
93
+ encoder_layers: int = 6
94
+ encoder_ffn_dim: int = 2048
95
+ encoder_attention_heads: int = 8
96
+ decoder_layers: int = 6
97
+ decoder_ffn_dim: int = 2048
98
+ decoder_attention_heads: int = 8
99
+ is_encoder_decoder: bool = True
100
+ activation_function: str = "relu"
101
+ d_model: int = 256
102
+ dropout: float | int = 0.1
103
+ attention_dropout: float | int = 0.0
104
+ activation_dropout: float | int = 0.0
105
+ auxiliary_loss: bool = False
106
+ position_embedding_type: str = "sine"
107
+ num_feature_levels: int = 4
108
+ encoder_n_points: int = 4
109
+ decoder_n_points: int = 4
110
+ two_stage: bool = True
111
+ class_cost: float = 1.0
112
+ bbox_cost: float = 5.0
113
+ giou_cost: float = 2.0
114
+ bbox_loss_coefficient: float = 5.0
115
+ giou_loss_coefficient: float = 2.0
116
+ focal_alpha: float = 0.25
117
+ disable_custom_kernels: bool = False
118
+ max_text_len: int = 256
119
+ text_enhancer_dropout: float | int = 0.0
120
+ fusion_droppath: float | int = 0.1
121
+ fusion_dropout: float | int = 0.0
122
+ embedding_init_target: bool = True
123
+ query_dim: int = 4
124
+ decoder_bbox_embed_share: bool = True
125
+ two_stage_bbox_embed_share: bool = False
126
+ positional_embedding_temperature: int = 20
127
+ init_std: float = 0.02
128
+ layer_norm_eps: float = 1e-5
129
+ tie_word_embeddings: bool = True
130
+
131
+ def __post_init__(self, **kwargs):
132
+ self.backbone_config, kwargs = consolidate_backbone_kwargs_to_config(
133
+ backbone_config=self.backbone_config,
134
+ default_config_type="swin",
135
+ default_config_kwargs={"out_indices": [2, 3, 4]},
136
+ **kwargs,
137
+ )
138
+
139
+ if isinstance(self.text_config, dict):
140
+ self.text_config["model_type"] = self.text_config.get("model_type", "bert")
141
+ self.text_config = CONFIG_MAPPING[self.text_config["model_type"]](**self.text_config)
142
+ elif self.text_config is None:
143
+ self.text_config = CONFIG_MAPPING["bert"]()
144
+ logger.info("text_config is None. Initializing the text config with default values (`BertConfig`).")
145
+
146
+ super().__post_init__(**kwargs)
147
+
148
+ def validate_architecture(self):
149
+ """Part of `@strict`-powered validation. Validates the architecture of the config."""
150
+ if self.two_stage_bbox_embed_share and not self.decoder_bbox_embed_share:
151
+ raise ValueError("If two_stage_bbox_embed_share is True, decoder_bbox_embed_share must be True.")
152
+
153
+
154
+ __all__ = ["GroundingDinoConfig"]
LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/transformers/models/grounding_dino/image_processing_grounding_dino.py ADDED
@@ -0,0 +1,740 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨
2
+ # This file was automatically generated from src/transformers/models/grounding_dino/modular_grounding_dino.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_grounding_dino.py file directly. One of our CI enforces this.
6
+ # 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨
7
+ # Copyright 2025 the HuggingFace Inc. team. All rights reserved.
8
+ #
9
+ # This code is based on EleutherAI's GPT-NeoX library and the GPT-NeoX
10
+ # and OPT implementations in this library. It has been modified from its
11
+ # original forms to accommodate minor architectural differences compared
12
+ # to GPT-NeoX and OPT used by the Meta AI team that trained the model.
13
+ #
14
+ # Licensed under the Apache License, Version 2.0 (the "License");
15
+ # you may not use this file except in compliance with the License.
16
+ # You may obtain a copy of the License at
17
+ #
18
+ # http://www.apache.org/licenses/LICENSE-2.0
19
+ #
20
+ # Unless required by applicable law or agreed to in writing, software
21
+ # distributed under the License is distributed on an "AS IS" BASIS,
22
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
23
+ # See the License for the specific language governing permissions and
24
+ # limitations under the License.
25
+
26
+ import pathlib
27
+ from typing import TYPE_CHECKING, Any, Optional
28
+
29
+ import torch
30
+ from torchvision.io import read_image
31
+ from torchvision.transforms.v2 import functional as tvF
32
+
33
+ from ...image_processing_backends import TorchvisionBackend
34
+ from ...image_processing_utils import BatchFeature, get_size_dict
35
+ from ...image_transforms import (
36
+ center_to_corners_format,
37
+ corners_to_center_format,
38
+ get_size_with_aspect_ratio,
39
+ safe_squeeze,
40
+ )
41
+ from ...image_utils import (
42
+ IMAGENET_DEFAULT_MEAN,
43
+ IMAGENET_DEFAULT_STD,
44
+ AnnotationFormat,
45
+ AnnotationType,
46
+ ChannelDimension,
47
+ ImageInput,
48
+ PILImageResampling,
49
+ SizeDict,
50
+ get_image_size,
51
+ get_image_size_for_max_height_width,
52
+ get_max_height_width,
53
+ validate_annotations,
54
+ )
55
+ from ...processing_utils import ImagesKwargs, Unpack
56
+ from ...utils import TensorType, auto_docstring
57
+
58
+
59
+ if TYPE_CHECKING:
60
+ from .modeling_grounding_dino import GroundingDinoObjectDetectionOutput
61
+
62
+
63
+ class GroundingDinoImageProcessorKwargs(ImagesKwargs, total=False):
64
+ r"""
65
+ format (`str`, *optional*, defaults to `AnnotationFormat.COCO_DETECTION`):
66
+ Data format of the annotations. One of "coco_detection" or "coco_panoptic".
67
+ do_convert_annotations (`bool`, *optional*, defaults to `True`):
68
+ Controls whether to convert the annotations to the format expected by the GROUNDING_DINO model. Converts the
69
+ bounding boxes to the format `(center_x, center_y, width, height)` and in the range `[0, 1]`.
70
+ Can be overridden by the `do_convert_annotations` parameter in the `preprocess` method.
71
+ """
72
+
73
+ format: str | AnnotationFormat
74
+ do_convert_annotations: bool
75
+
76
+
77
+ SUPPORTED_ANNOTATION_FORMATS = (AnnotationFormat.COCO_DETECTION, AnnotationFormat.COCO_PANOPTIC)
78
+
79
+
80
+ # inspired by https://github.com/facebookresearch/grounding_dino/blob/master/datasets/coco.py#L33
81
+ def convert_coco_poly_to_mask(segmentations, height: int, width: int, device: torch.device) -> torch.Tensor:
82
+ """
83
+ Convert a COCO polygon annotation to a mask.
84
+
85
+ Args:
86
+ segmentations (`list[list[float]]`):
87
+ List of polygons, each polygon represented by a list of x-y coordinates.
88
+ height (`int`):
89
+ Height of the mask.
90
+ width (`int`):
91
+ Width of the mask.
92
+ """
93
+ try:
94
+ from pycocotools import mask as coco_mask
95
+ except ImportError:
96
+ raise ImportError("Pycocotools is not installed in your environment.")
97
+
98
+ masks = []
99
+ for polygons in segmentations:
100
+ rles = coco_mask.frPyObjects(polygons, height, width)
101
+ mask = coco_mask.decode(rles)
102
+ if len(mask.shape) < 3:
103
+ mask = mask[..., None]
104
+ mask = torch.as_tensor(mask, dtype=torch.uint8, device=device)
105
+ mask = torch.any(mask, axis=2)
106
+ masks.append(mask)
107
+ if masks:
108
+ masks = torch.stack(masks, axis=0)
109
+ else:
110
+ masks = torch.zeros((0, height, width), dtype=torch.uint8, device=device)
111
+
112
+ return masks
113
+
114
+
115
+ # inspired by https://github.com/facebookresearch/grounding_dino/blob/master/datasets/coco.py#L50
116
+ def prepare_coco_detection_annotation(
117
+ image,
118
+ target,
119
+ return_segmentation_masks: bool = False,
120
+ input_data_format: ChannelDimension | str | None = None,
121
+ ):
122
+ """
123
+ Convert the target in COCO format into the format expected by GROUNDING_DINO.
124
+ """
125
+ image_height, image_width = image.size()[-2:]
126
+
127
+ image_id = target["image_id"]
128
+ image_id = torch.as_tensor([image_id], dtype=torch.int64, device=image.device)
129
+
130
+ # Get all COCO annotations for the given image.
131
+ annotations = target["annotations"]
132
+ classes = []
133
+ area = []
134
+ boxes = []
135
+ keypoints = []
136
+ for obj in annotations:
137
+ if "iscrowd" not in obj or obj["iscrowd"] == 0:
138
+ classes.append(obj["category_id"])
139
+ area.append(obj["area"])
140
+ boxes.append(obj["bbox"])
141
+ if "keypoints" in obj:
142
+ keypoints.append(obj["keypoints"])
143
+
144
+ classes = torch.as_tensor(classes, dtype=torch.int64, device=image.device)
145
+ area = torch.as_tensor(area, dtype=torch.float32, device=image.device)
146
+ iscrowd = torch.zeros_like(classes, dtype=torch.int64, device=image.device)
147
+ # guard against no boxes via resizing
148
+ boxes = torch.as_tensor(boxes, dtype=torch.float32, device=image.device).reshape(-1, 4)
149
+ boxes[:, 2:] += boxes[:, :2]
150
+ boxes[:, 0::2] = boxes[:, 0::2].clip(min=0, max=image_width)
151
+ boxes[:, 1::2] = boxes[:, 1::2].clip(min=0, max=image_height)
152
+
153
+ keep = (boxes[:, 3] > boxes[:, 1]) & (boxes[:, 2] > boxes[:, 0])
154
+
155
+ new_target = {
156
+ "image_id": image_id,
157
+ "class_labels": classes[keep],
158
+ "boxes": boxes[keep],
159
+ "area": area[keep],
160
+ "iscrowd": iscrowd[keep],
161
+ "orig_size": torch.as_tensor([int(image_height), int(image_width)], dtype=torch.int64, device=image.device),
162
+ }
163
+
164
+ if keypoints:
165
+ keypoints = torch.as_tensor(keypoints, dtype=torch.float32, device=image.device)
166
+ # Apply the keep mask here to filter the relevant annotations
167
+ keypoints = keypoints[keep]
168
+ num_keypoints = keypoints.shape[0]
169
+ keypoints = keypoints.reshape((-1, 3)) if num_keypoints else keypoints
170
+ new_target["keypoints"] = keypoints
171
+
172
+ if return_segmentation_masks:
173
+ segmentation_masks = [obj["segmentation"] for obj in annotations]
174
+ masks = convert_coco_poly_to_mask(segmentation_masks, image_height, image_width, device=image.device)
175
+ new_target["masks"] = masks[keep]
176
+
177
+ return new_target
178
+
179
+
180
+ def masks_to_boxes(masks: torch.Tensor) -> torch.Tensor:
181
+ """
182
+ Compute the bounding boxes around the provided panoptic segmentation masks.
183
+
184
+ Args:
185
+ masks: masks in format `[number_masks, height, width]` where N is the number of masks
186
+
187
+ Returns:
188
+ boxes: bounding boxes in format `[number_masks, 4]` in xyxy format
189
+ """
190
+ if masks.numel() == 0:
191
+ return torch.zeros((0, 4), device=masks.device)
192
+
193
+ h, w = masks.shape[-2:]
194
+ y = torch.arange(0, h, dtype=torch.float32, device=masks.device)
195
+ x = torch.arange(0, w, dtype=torch.float32, device=masks.device)
196
+ # see https://github.com/pytorch/pytorch/issues/50276
197
+ y, x = torch.meshgrid(y, x, indexing="ij")
198
+
199
+ x_mask = masks * torch.unsqueeze(x, 0)
200
+ x_max = x_mask.view(x_mask.shape[0], -1).max(-1)[0]
201
+ x_min = (
202
+ torch.where(masks, x.unsqueeze(0), torch.tensor(1e8, device=masks.device)).view(masks.shape[0], -1).min(-1)[0]
203
+ )
204
+
205
+ y_mask = masks * torch.unsqueeze(y, 0)
206
+ y_max = y_mask.view(y_mask.shape[0], -1).max(-1)[0]
207
+ y_min = (
208
+ torch.where(masks, y.unsqueeze(0), torch.tensor(1e8, device=masks.device)).view(masks.shape[0], -1).min(-1)[0]
209
+ )
210
+
211
+ return torch.stack([x_min, y_min, x_max, y_max], 1)
212
+
213
+
214
+ # 2 functions below adapted from https://github.com/cocodataset/panopticapi/blob/master/panopticapi/utils.py
215
+ # Copyright (c) 2018, Alexander Kirillov
216
+ # All rights reserved.
217
+ def rgb_to_id(color):
218
+ """
219
+ Converts RGB color to unique ID.
220
+ """
221
+ if isinstance(color, torch.Tensor) and len(color.shape) == 3:
222
+ if color.dtype == torch.uint8:
223
+ color = color.to(torch.int32)
224
+ return color[:, :, 0] + 256 * color[:, :, 1] + 256 * 256 * color[:, :, 2]
225
+ return int(color[0] + 256 * color[1] + 256 * 256 * color[2])
226
+
227
+
228
+ def prepare_coco_panoptic_annotation(
229
+ image: torch.Tensor,
230
+ target: dict,
231
+ masks_path: str | pathlib.Path,
232
+ return_masks: bool = True,
233
+ input_data_format: ChannelDimension | str = None,
234
+ ) -> dict:
235
+ """
236
+ Prepare a coco panoptic annotation for GROUNDING_DINO.
237
+ """
238
+ image_height, image_width = get_image_size(image, channel_dim=input_data_format)
239
+ annotation_path = pathlib.Path(masks_path) / target["file_name"]
240
+
241
+ new_target = {}
242
+ new_target["image_id"] = torch.as_tensor(
243
+ [target["image_id"] if "image_id" in target else target["id"]], dtype=torch.int64, device=image.device
244
+ )
245
+ new_target["size"] = torch.as_tensor([image_height, image_width], dtype=torch.int64, device=image.device)
246
+ new_target["orig_size"] = torch.as_tensor([image_height, image_width], dtype=torch.int64, device=image.device)
247
+
248
+ if "segments_info" in target:
249
+ masks = read_image(annotation_path).permute(1, 2, 0).to(dtype=torch.int32, device=image.device)
250
+ masks = rgb_to_id(masks)
251
+
252
+ ids = torch.as_tensor([segment_info["id"] for segment_info in target["segments_info"]], device=image.device)
253
+ masks = masks == ids[:, None, None]
254
+ masks = masks.to(torch.bool)
255
+ if return_masks:
256
+ new_target["masks"] = masks
257
+ new_target["boxes"] = masks_to_boxes(masks)
258
+ new_target["class_labels"] = torch.as_tensor(
259
+ [segment_info["category_id"] for segment_info in target["segments_info"]],
260
+ dtype=torch.int64,
261
+ device=image.device,
262
+ )
263
+ new_target["iscrowd"] = torch.as_tensor(
264
+ [segment_info["iscrowd"] for segment_info in target["segments_info"]],
265
+ dtype=torch.int64,
266
+ device=image.device,
267
+ )
268
+ new_target["area"] = torch.as_tensor(
269
+ [segment_info["area"] for segment_info in target["segments_info"]],
270
+ dtype=torch.float32,
271
+ device=image.device,
272
+ )
273
+
274
+ return new_target
275
+
276
+
277
+ def _scale_boxes(boxes, target_sizes):
278
+ """
279
+ Scale batch of bounding boxes to the target sizes.
280
+
281
+ Args:
282
+ boxes (`torch.Tensor` of shape `(batch_size, num_boxes, 4)`):
283
+ Bounding boxes to scale. Each box is expected to be in (x1, y1, x2, y2) format.
284
+ target_sizes (`list[tuple[int, int]]` or `torch.Tensor` of shape `(batch_size, 2)`):
285
+ Target sizes to scale the boxes to. Each target size is expected to be in (height, width) format.
286
+
287
+ Returns:
288
+ `torch.Tensor` of shape `(batch_size, num_boxes, 4)`: Scaled bounding boxes.
289
+ """
290
+
291
+ if isinstance(target_sizes, (list, tuple)):
292
+ image_height = torch.tensor([i[0] for i in target_sizes])
293
+ image_width = torch.tensor([i[1] for i in target_sizes])
294
+ elif isinstance(target_sizes, torch.Tensor):
295
+ image_height, image_width = target_sizes.unbind(1)
296
+ else:
297
+ raise TypeError("`target_sizes` must be a list, tuple or torch.Tensor")
298
+
299
+ scale_factor = torch.stack([image_width, image_height, image_width, image_height], dim=1)
300
+ scale_factor = scale_factor.unsqueeze(1).to(boxes.device)
301
+ boxes = boxes * scale_factor
302
+ return boxes
303
+
304
+
305
+ @auto_docstring
306
+ class GroundingDinoImageProcessor(TorchvisionBackend):
307
+ valid_kwargs = GroundingDinoImageProcessorKwargs
308
+ resample = PILImageResampling.BILINEAR
309
+ image_mean = IMAGENET_DEFAULT_MEAN
310
+ image_std = IMAGENET_DEFAULT_STD
311
+ format = AnnotationFormat.COCO_DETECTION
312
+ do_resize = True
313
+ do_rescale = True
314
+ do_normalize = True
315
+ do_pad = True
316
+ size = {"shortest_edge": 800, "longest_edge": 1333}
317
+ default_to_square = False
318
+ model_input_names = ["pixel_values", "pixel_mask"]
319
+
320
+ def __init__(self, **kwargs: Unpack[GroundingDinoImageProcessorKwargs]) -> None:
321
+ kwargs.setdefault("do_pad", kwargs.pop("pad_and_return_pixel_mask", self.do_pad))
322
+
323
+ size = kwargs.pop("size", None)
324
+ max_size = None if size is None else kwargs.pop("max_size", 1333)
325
+ size = size if size is not None else {"shortest_edge": 800, "longest_edge": 1333}
326
+ # Convert size dict for backwards compat with max_size parameter
327
+ kwargs["size"] = get_size_dict(size, max_size=max_size, default_to_square=False)
328
+
329
+ # Backwards compatibility
330
+ do_convert_annotations = kwargs.get("do_convert_annotations")
331
+ do_normalize = kwargs.get("do_normalize")
332
+ if do_convert_annotations is None and getattr(self, "do_convert_annotations", None) is None:
333
+ self.do_convert_annotations = do_normalize if do_normalize is not None else self.do_normalize
334
+
335
+ super().__init__(**kwargs)
336
+
337
+ def prepare_annotation(
338
+ self,
339
+ image: torch.Tensor,
340
+ target: dict,
341
+ format: AnnotationFormat | None = None,
342
+ return_segmentation_masks: bool | None = None,
343
+ masks_path: str | pathlib.Path | None = None,
344
+ input_data_format: str | ChannelDimension | None = None,
345
+ ) -> dict:
346
+ """
347
+ Prepare an annotation for feeding into GROUNDING_DINO model.
348
+ """
349
+ format = format if format is not None else self.format
350
+
351
+ if format == AnnotationFormat.COCO_DETECTION:
352
+ return_segmentation_masks = False if return_segmentation_masks is None else return_segmentation_masks
353
+ target = prepare_coco_detection_annotation(
354
+ image, target, return_segmentation_masks, input_data_format=input_data_format
355
+ )
356
+ elif format == AnnotationFormat.COCO_PANOPTIC:
357
+ return_segmentation_masks = True if return_segmentation_masks is None else return_segmentation_masks
358
+ target = prepare_coco_panoptic_annotation(
359
+ image,
360
+ target,
361
+ masks_path=masks_path,
362
+ return_masks=return_segmentation_masks,
363
+ input_data_format=input_data_format,
364
+ )
365
+ else:
366
+ raise ValueError(f"Format {format} is not supported.")
367
+ return target
368
+
369
+ def resize(
370
+ self,
371
+ image: torch.Tensor,
372
+ size: SizeDict,
373
+ resample: Optional["PILImageResampling | tvF.InterpolationMode | int"] = None,
374
+ **kwargs,
375
+ ) -> torch.Tensor:
376
+ """
377
+ Resize the image to the given size. Size can be `min_size` (scalar) or `(height, width)` tuple. If size is an
378
+ int, smaller edge of the image will be matched to this number.
379
+
380
+ Args:
381
+ image (`torch.Tensor`):
382
+ Image to resize.
383
+ size (`SizeDict`):
384
+ Size of the image's `(height, width)` dimensions after resizing. Available options are:
385
+ - `{"height": int, "width": int}`: The image will be resized to the exact size `(height, width)`.
386
+ Do NOT keep the aspect ratio.
387
+ - `{"shortest_edge": int, "longest_edge": int}`: The image will be resized to a maximum size respecting
388
+ the aspect ratio and keeping the shortest edge less or equal to `shortest_edge` and the longest edge
389
+ less or equal to `longest_edge`.
390
+ - `{"max_height": int, "max_width": int}`: The image will be resized to the maximum size respecting the
391
+ aspect ratio and keeping the height less or equal to `max_height` and the width less or equal to
392
+ `max_width`.
393
+ resample (`PILImageResampling | tvF.InterpolationMode | int`, *optional*, defaults to `PILImageResampling.BILINEAR`):
394
+ Resampling filter to use if resizing the image.
395
+ """
396
+ if size.shortest_edge and size.longest_edge:
397
+ # Resize the image so that the shortest edge or the longest edge is of the given size
398
+ # while maintaining the aspect ratio of the original image.
399
+ new_size = get_size_with_aspect_ratio(image.shape[-2:], size.shortest_edge, size.longest_edge)
400
+ elif size.max_height and size.max_width:
401
+ new_size = get_image_size_for_max_height_width(image.shape[-2:], size.max_height, size.max_width)
402
+ elif size.height and size.width:
403
+ new_size = (size.height, size.width)
404
+ else:
405
+ raise ValueError(
406
+ f"Size must contain 'height' and 'width' keys or 'shortest_edge' and 'longest_edge' keys. Got {size}."
407
+ )
408
+
409
+ image = super().resize(
410
+ image, size=SizeDict(height=new_size[0], width=new_size[1]), resample=resample, **kwargs
411
+ )
412
+ return image
413
+
414
+ def resize_annotation(
415
+ self,
416
+ annotation: dict[str, Any],
417
+ orig_size: tuple[int, int],
418
+ target_size: tuple[int, int],
419
+ threshold: float = 0.5,
420
+ resample: Optional["PILImageResampling | tvF.InterpolationMode | int"] = PILImageResampling.NEAREST,
421
+ ):
422
+ """
423
+ Resizes an annotation to a target size.
424
+
425
+ Args:
426
+ annotation (`dict[str, Any]`):
427
+ The annotation dictionary.
428
+ orig_size (`tuple[int, int]`):
429
+ The original size of the input image.
430
+ target_size (`tuple[int, int]`):
431
+ The target size of the image, as returned by the preprocessing `resize` step.
432
+ threshold (`float`, *optional*, defaults to 0.5):
433
+ The threshold used to binarize the segmentation masks.
434
+ resample (`PILImageResampling | tvF.InterpolationMode | int`, defaults to `tvF.InterpolationMode.NEAREST_EXACT`):
435
+ The resampling filter to use when resizing the masks.
436
+ """
437
+ ratio_height, ratio_width = [target / orig for target, orig in zip(target_size, orig_size)]
438
+
439
+ new_annotation = {}
440
+ new_annotation["size"] = target_size
441
+
442
+ for key, value in annotation.items():
443
+ if key == "boxes":
444
+ boxes = value
445
+ scaled_boxes = boxes * torch.as_tensor(
446
+ [ratio_width, ratio_height, ratio_width, ratio_height], dtype=torch.float32, device=boxes.device
447
+ )
448
+ new_annotation["boxes"] = scaled_boxes
449
+ elif key == "area":
450
+ area = value
451
+ scaled_area = area * (ratio_width * ratio_height)
452
+ new_annotation["area"] = scaled_area
453
+ elif key == "masks":
454
+ masks = value[:, None]
455
+ masks = [
456
+ super(GroundingDinoImageProcessor, self).resize(
457
+ mask, size=SizeDict(height=target_size[0], width=target_size[1]), resample=resample
458
+ )
459
+ for mask in masks
460
+ ]
461
+ masks = torch.stack(masks).to(torch.float32)
462
+ masks = masks[:, 0] > threshold
463
+ new_annotation["masks"] = masks
464
+ elif key == "size":
465
+ new_annotation["size"] = target_size
466
+ else:
467
+ new_annotation[key] = value
468
+
469
+ return new_annotation
470
+
471
+ def normalize_annotation(self, annotation: dict, image_size: tuple[int, int]) -> dict:
472
+ image_height, image_width = image_size
473
+ norm_annotation = {}
474
+ for key, value in annotation.items():
475
+ if key == "boxes":
476
+ boxes = value
477
+ boxes = corners_to_center_format(boxes)
478
+ boxes /= torch.as_tensor(
479
+ [image_width, image_height, image_width, image_height], dtype=torch.float32, device=boxes.device
480
+ )
481
+ norm_annotation[key] = boxes
482
+ else:
483
+ norm_annotation[key] = value
484
+ return norm_annotation
485
+
486
+ def _update_annotation_for_padded_image(
487
+ self,
488
+ annotation: dict,
489
+ input_image_size: tuple[int, int],
490
+ output_image_size: tuple[int, int],
491
+ padding,
492
+ update_bboxes,
493
+ ) -> dict:
494
+ """
495
+ Update the annotation for a padded image.
496
+ """
497
+ new_annotation = {}
498
+ new_annotation["size"] = output_image_size
499
+ ratio_height, ratio_width = (input / output for output, input in zip(output_image_size, input_image_size))
500
+
501
+ for key, value in annotation.items():
502
+ if key == "masks":
503
+ masks = value
504
+ masks = tvF.pad(
505
+ masks,
506
+ padding,
507
+ fill=0,
508
+ )
509
+ masks = safe_squeeze(masks, 1)
510
+ new_annotation["masks"] = masks
511
+ elif key == "boxes" and update_bboxes:
512
+ boxes = value
513
+ boxes *= torch.as_tensor([ratio_width, ratio_height, ratio_width, ratio_height], device=boxes.device)
514
+ new_annotation["boxes"] = boxes
515
+ elif key == "size":
516
+ new_annotation["size"] = output_image_size
517
+ else:
518
+ new_annotation[key] = value
519
+ return new_annotation
520
+
521
+ def pad(
522
+ self,
523
+ image: torch.Tensor,
524
+ padded_size: tuple[int, int],
525
+ annotation: dict[str, Any] | None = None,
526
+ update_bboxes: bool = True,
527
+ fill: int = 0,
528
+ ):
529
+ original_size = image.size()[-2:]
530
+ padding_bottom = padded_size[0] - original_size[0]
531
+ padding_right = padded_size[1] - original_size[1]
532
+ if padding_bottom < 0 or padding_right < 0:
533
+ raise ValueError(
534
+ f"Padding dimensions are negative. Please make sure that the padded size is larger than the "
535
+ f"original size. Got padded size: {padded_size}, original size: {original_size}."
536
+ )
537
+ if original_size != padded_size:
538
+ padding = [0, 0, padding_right, padding_bottom]
539
+ image = tvF.pad(image, padding, fill=fill)
540
+ if annotation is not None:
541
+ annotation = self._update_annotation_for_padded_image(
542
+ annotation, original_size, padded_size, padding, update_bboxes
543
+ )
544
+
545
+ # Make a pixel mask for the image, where 1 indicates a valid pixel and 0 indicates padding.
546
+ pixel_mask = torch.zeros(padded_size, dtype=torch.int64, device=image.device)
547
+ pixel_mask[: original_size[0], : original_size[1]] = 1
548
+
549
+ return image, pixel_mask, annotation
550
+
551
+ @auto_docstring
552
+ def preprocess(
553
+ self,
554
+ images: ImageInput,
555
+ annotations: AnnotationType | list[AnnotationType] | None = None,
556
+ return_segmentation_masks: bool | None = None,
557
+ masks_path: str | pathlib.Path | None = None,
558
+ **kwargs: Unpack[GroundingDinoImageProcessorKwargs],
559
+ ) -> BatchFeature:
560
+ r"""
561
+ annotations (`AnnotationType` or `list[AnnotationType]`, *optional*):
562
+ Annotations to transform according to the padding that is applied to the images.
563
+ return_segmentation_masks (`bool`, *optional*, defaults to `self.return_segmentation_masks`):
564
+ Whether to return segmentation masks.
565
+ masks_path (`str` or `pathlib.Path`, *optional*):
566
+ Path to the directory containing the segmentation masks.
567
+ """
568
+ return super().preprocess(images, annotations, return_segmentation_masks, masks_path, **kwargs)
569
+
570
+ def _preprocess(
571
+ self,
572
+ images: list["torch.Tensor"],
573
+ annotations: AnnotationType | list[AnnotationType] | None,
574
+ return_segmentation_masks: bool,
575
+ masks_path: str | pathlib.Path | None,
576
+ do_resize: bool,
577
+ size: SizeDict,
578
+ resample: "PILImageResampling | tvF.InterpolationMode | int | None",
579
+ do_rescale: bool,
580
+ rescale_factor: float,
581
+ do_normalize: bool,
582
+ do_convert_annotations: bool,
583
+ image_mean: float | list[float] | None,
584
+ image_std: float | list[float] | None,
585
+ do_pad: bool,
586
+ pad_size: SizeDict | None,
587
+ format: str | AnnotationFormat | None,
588
+ return_tensors: str | TensorType | None,
589
+ **kwargs,
590
+ ) -> BatchFeature:
591
+ """
592
+ Preprocess an image or a batch of images so that it can be used by the model.
593
+ """
594
+ if annotations is not None and isinstance(annotations, dict):
595
+ annotations = [annotations]
596
+
597
+ if annotations is not None and len(images) != len(annotations):
598
+ raise ValueError(
599
+ f"The number of images ({len(images)}) and annotations ({len(annotations)}) do not match."
600
+ )
601
+
602
+ format = AnnotationFormat(format)
603
+ if annotations is not None:
604
+ validate_annotations(format, SUPPORTED_ANNOTATION_FORMATS, annotations)
605
+
606
+ if (
607
+ masks_path is not None
608
+ and format == AnnotationFormat.COCO_PANOPTIC
609
+ and not isinstance(masks_path, (pathlib.Path, str))
610
+ ):
611
+ raise ValueError(
612
+ "The path to the directory containing the mask PNG files should be provided as a"
613
+ f" `pathlib.Path` or string object, but is {type(masks_path)} instead."
614
+ )
615
+
616
+ data = {}
617
+
618
+ processed_images = []
619
+ processed_annotations = []
620
+ pixel_masks = [] # Initialize pixel_masks here
621
+ for image, annotation in zip(images, annotations if annotations is not None else [None] * len(images)):
622
+ # prepare (COCO annotations as a list of Dict -> GROUNDING_DINO target as a single Dict per image)
623
+ if annotations is not None:
624
+ annotation = self.prepare_annotation(
625
+ image,
626
+ annotation,
627
+ format,
628
+ return_segmentation_masks=return_segmentation_masks,
629
+ masks_path=masks_path,
630
+ input_data_format=ChannelDimension.FIRST,
631
+ )
632
+
633
+ if do_resize:
634
+ resized_image = self.resize(image, size=size, resample=resample)
635
+ if annotations is not None:
636
+ annotation = self.resize_annotation(
637
+ annotation,
638
+ orig_size=image.size()[-2:],
639
+ target_size=resized_image.size()[-2:],
640
+ )
641
+ image = resized_image
642
+ # Fused rescale and normalize
643
+ image = self.rescale_and_normalize(image, do_rescale, rescale_factor, do_normalize, image_mean, image_std)
644
+ if do_convert_annotations and annotations is not None:
645
+ annotation = self.normalize_annotation(annotation, get_image_size(image, ChannelDimension.FIRST))
646
+
647
+ processed_images.append(image)
648
+ processed_annotations.append(annotation)
649
+ images = processed_images
650
+ annotations = processed_annotations if annotations is not None else None
651
+
652
+ if do_pad:
653
+ # depends on all resized image shapes so we need another loop
654
+ if pad_size is not None:
655
+ padded_size = (pad_size.height, pad_size.width)
656
+ else:
657
+ padded_size = get_max_height_width(images)
658
+
659
+ padded_images = []
660
+ padded_annotations = []
661
+ for image, annotation in zip(images, annotations if annotations is not None else [None] * len(images)):
662
+ # Pads images and returns their mask: {'pixel_values': ..., 'pixel_mask': ...}
663
+ if padded_size == image.size()[-2:]:
664
+ padded_images.append(image)
665
+ pixel_masks.append(torch.ones(padded_size, dtype=torch.int64, device=image.device))
666
+ padded_annotations.append(annotation)
667
+ continue
668
+ image, pixel_mask, annotation = self.pad(
669
+ image, padded_size, annotation=annotation, update_bboxes=do_convert_annotations
670
+ )
671
+ padded_images.append(image)
672
+ padded_annotations.append(annotation)
673
+ pixel_masks.append(pixel_mask)
674
+ images = padded_images
675
+ annotations = padded_annotations if annotations is not None else None
676
+ data.update({"pixel_mask": torch.stack(pixel_masks, dim=0)})
677
+
678
+ data.update({"pixel_values": torch.stack(images, dim=0)})
679
+ encoded_inputs = BatchFeature(data, tensor_type=return_tensors)
680
+ if annotations is not None:
681
+ encoded_inputs["labels"] = [
682
+ BatchFeature(annotation, tensor_type=return_tensors) for annotation in annotations
683
+ ]
684
+ return encoded_inputs
685
+
686
+ def post_process_object_detection(
687
+ self,
688
+ outputs: "GroundingDinoObjectDetectionOutput",
689
+ threshold: float = 0.1,
690
+ target_sizes: TensorType | list[tuple] | None = None,
691
+ ):
692
+ """
693
+ Converts the raw output of [`GroundingDinoForObjectDetection`] into final bounding boxes in (top_left_x, top_left_y,
694
+ bottom_right_x, bottom_right_y) format.
695
+
696
+ Args:
697
+ outputs ([`GroundingDinoObjectDetectionOutput`]):
698
+ Raw outputs of the model.
699
+ threshold (`float`, *optional*, defaults to 0.1):
700
+ Score threshold to keep object detection predictions.
701
+ target_sizes (`torch.Tensor` or `list[tuple[int, int]]`, *optional*):
702
+ Tensor of shape `(batch_size, 2)` or list of tuples (`tuple[int, int]`) containing the target size
703
+ `(height, width)` of each image in the batch. If unset, predictions will not be resized.
704
+
705
+ Returns:
706
+ `list[Dict]`: A list of dictionaries, each dictionary containing the following keys:
707
+ - "scores": The confidence scores for each predicted box on the image.
708
+ - "labels": Indexes of the classes predicted by the model on the image.
709
+ - "boxes": Image bounding boxes in (top_left_x, top_left_y, bottom_right_x, bottom_right_y) format.
710
+ """
711
+ batch_logits, batch_boxes = outputs.logits, outputs.pred_boxes
712
+ batch_size = len(batch_logits)
713
+
714
+ if target_sizes is not None and len(target_sizes) != batch_size:
715
+ raise ValueError("Make sure that you pass in as many target sizes as images")
716
+
717
+ # batch_logits of shape (batch_size, num_queries, num_classes)
718
+ batch_class_logits = torch.max(batch_logits, dim=-1)
719
+ batch_scores = torch.sigmoid(batch_class_logits.values)
720
+ batch_labels = batch_class_logits.indices
721
+
722
+ # Convert to [x0, y0, x1, y1] format
723
+ batch_boxes = center_to_corners_format(batch_boxes)
724
+
725
+ # Convert from relative [0, 1] to absolute [0, height] coordinates
726
+ if target_sizes is not None:
727
+ batch_boxes = _scale_boxes(batch_boxes, target_sizes)
728
+
729
+ results = []
730
+ for scores, labels, boxes in zip(batch_scores, batch_labels, batch_boxes):
731
+ keep = scores > threshold
732
+ scores = scores[keep]
733
+ labels = labels[keep]
734
+ boxes = boxes[keep]
735
+ results.append({"scores": scores, "labels": labels, "boxes": boxes})
736
+
737
+ return results
738
+
739
+
740
+ __all__ = ["GroundingDinoImageProcessor"]
LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/transformers/models/grounding_dino/image_processing_pil_grounding_dino.py ADDED
@@ -0,0 +1,770 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨
2
+ # This file was automatically generated from src/transformers/models/grounding_dino/modular_grounding_dino.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_grounding_dino.py file directly. One of our CI enforces this.
6
+ # 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨
7
+ # Copyright 2025 the HuggingFace Inc. team. All rights reserved.
8
+ #
9
+ # This code is based on EleutherAI's GPT-NeoX library and the GPT-NeoX
10
+ # and OPT implementations in this library. It has been modified from its
11
+ # original forms to accommodate minor architectural differences compared
12
+ # to GPT-NeoX and OPT used by the Meta AI team that trained the model.
13
+ #
14
+ # Licensed under the Apache License, Version 2.0 (the "License");
15
+ # you may not use this file except in compliance with the License.
16
+ # You may obtain a copy of the License at
17
+ #
18
+ # http://www.apache.org/licenses/LICENSE-2.0
19
+ #
20
+ # Unless required by applicable law or agreed to in writing, software
21
+ # distributed under the License is distributed on an "AS IS" BASIS,
22
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
23
+ # See the License for the specific language governing permissions and
24
+ # limitations under the License.
25
+
26
+ import pathlib
27
+ from typing import TYPE_CHECKING, Any, Optional
28
+
29
+ import numpy as np
30
+
31
+ from ...image_processing_backends import PilBackend
32
+ from ...image_processing_utils import BatchFeature
33
+ from ...image_transforms import (
34
+ PaddingMode,
35
+ center_to_corners_format,
36
+ corners_to_center_format,
37
+ get_size_with_aspect_ratio,
38
+ pad,
39
+ resize,
40
+ safe_squeeze,
41
+ )
42
+ from ...image_utils import (
43
+ IMAGENET_DEFAULT_MEAN,
44
+ IMAGENET_DEFAULT_STD,
45
+ AnnotationFormat,
46
+ AnnotationType,
47
+ ChannelDimension,
48
+ ImageInput,
49
+ PILImageResampling,
50
+ SizeDict,
51
+ get_image_size,
52
+ get_image_size_for_max_height_width,
53
+ get_max_height_width,
54
+ validate_annotations,
55
+ )
56
+ from ...processing_utils import ImagesKwargs, Unpack
57
+ from ...utils import TensorType, auto_docstring, is_torch_available, is_vision_available, requires_backends
58
+ from ...utils.import_utils import requires
59
+
60
+
61
+ if TYPE_CHECKING:
62
+ from .modeling_grounding_dino import GroundingDinoObjectDetectionOutput
63
+
64
+
65
+ if is_vision_available():
66
+ import PIL.Image
67
+ if is_torch_available():
68
+ import torch
69
+
70
+ SUPPORTED_ANNOTATION_FORMATS = (AnnotationFormat.COCO_DETECTION, AnnotationFormat.COCO_PANOPTIC)
71
+
72
+
73
+ class GroundingDinoImageProcessorKwargs(ImagesKwargs, total=False):
74
+ r"""
75
+ format (`str`, *optional*, defaults to `AnnotationFormat.COCO_DETECTION`):
76
+ Data format of the annotations. One of "coco_detection" or "coco_panoptic".
77
+ do_convert_annotations (`bool`, *optional*, defaults to `True`):
78
+ Controls whether to convert the annotations to the format expected by the GROUNDING_DINO model. Converts the
79
+ bounding boxes to the format `(center_x, center_y, width, height)` and in the range `[0, 1]`.
80
+ Can be overridden by the `do_convert_annotations` parameter in the `preprocess` method.
81
+ """
82
+
83
+ format: str | AnnotationFormat
84
+ do_convert_annotations: bool
85
+
86
+
87
+ # inspired by https://github.com/facebookresearch/grounding_dino/blob/master/datasets/coco.py#L33
88
+ def convert_coco_poly_to_mask(segmentations, height: int, width: int) -> np.ndarray:
89
+ """
90
+ Convert a COCO polygon annotation to a mask.
91
+
92
+ Args:
93
+ segmentations (`list[list[float]]`):
94
+ List of polygons, each polygon represented by a list of x-y coordinates.
95
+ height (`int`):
96
+ Height of the mask.
97
+ width (`int`):
98
+ Width of the mask.
99
+ """
100
+ try:
101
+ from pycocotools import mask as coco_mask
102
+ except ImportError:
103
+ raise ImportError("Pycocotools is not installed in your environment.")
104
+
105
+ masks = []
106
+ for polygons in segmentations:
107
+ rles = coco_mask.frPyObjects(polygons, height, width)
108
+ mask = coco_mask.decode(rles)
109
+ if len(mask.shape) < 3:
110
+ mask = mask[..., None]
111
+ mask = np.asarray(mask, dtype=np.uint8)
112
+ mask = np.any(mask, axis=2)
113
+ masks.append(mask)
114
+ if masks:
115
+ masks = np.stack(masks, axis=0)
116
+ else:
117
+ masks = np.zeros((0, height, width), dtype=np.uint8)
118
+
119
+ return masks
120
+
121
+
122
+ # inspired by https://github.com/facebookresearch/grounding_dino/blob/master/datasets/coco.py#L50
123
+ def prepare_coco_detection_annotation(
124
+ image,
125
+ target,
126
+ return_segmentation_masks: bool = False,
127
+ input_data_format: ChannelDimension | str | None = None,
128
+ ):
129
+ """
130
+ Convert the target in COCO format into the format expected by GROUNDING_DINO.
131
+ """
132
+ image_height, image_width = get_image_size(image, channel_dim=input_data_format)
133
+
134
+ image_id = target["image_id"]
135
+ image_id = np.asarray([image_id], dtype=np.int64)
136
+
137
+ # Get all COCO annotations for the given image.
138
+ annotations = target["annotations"]
139
+ annotations = [obj for obj in annotations if "iscrowd" not in obj or obj["iscrowd"] == 0]
140
+
141
+ classes = [obj["category_id"] for obj in annotations]
142
+ classes = np.asarray(classes, dtype=np.int64)
143
+
144
+ # for conversion to coco api
145
+ area = np.asarray([obj["area"] for obj in annotations], dtype=np.float32)
146
+ iscrowd = np.asarray([obj.get("iscrowd", 0) for obj in annotations], dtype=np.int64)
147
+
148
+ boxes = [obj["bbox"] for obj in annotations]
149
+ # guard against no boxes via resizing
150
+ boxes = np.asarray(boxes, dtype=np.float32).reshape(-1, 4)
151
+ boxes[:, 2:] += boxes[:, :2]
152
+ boxes[:, 0::2] = boxes[:, 0::2].clip(min=0, max=image_width)
153
+ boxes[:, 1::2] = boxes[:, 1::2].clip(min=0, max=image_height)
154
+
155
+ keep = (boxes[:, 3] > boxes[:, 1]) & (boxes[:, 2] > boxes[:, 0])
156
+
157
+ new_target = {}
158
+ new_target["image_id"] = image_id
159
+ new_target["class_labels"] = classes[keep]
160
+ new_target["boxes"] = boxes[keep]
161
+ new_target["area"] = area[keep]
162
+ new_target["iscrowd"] = iscrowd[keep]
163
+ new_target["orig_size"] = np.asarray([int(image_height), int(image_width)], dtype=np.int64)
164
+
165
+ if annotations and "keypoints" in annotations[0]:
166
+ keypoints = [obj["keypoints"] for obj in annotations]
167
+ # Converting the filtered keypoints list to a numpy array
168
+ keypoints = np.asarray(keypoints, dtype=np.float32)
169
+ # Apply the keep mask here to filter the relevant annotations
170
+ keypoints = keypoints[keep]
171
+ num_keypoints = keypoints.shape[0]
172
+ keypoints = keypoints.reshape((-1, 3)) if num_keypoints else keypoints
173
+ new_target["keypoints"] = keypoints
174
+
175
+ if return_segmentation_masks:
176
+ segmentation_masks = [obj["segmentation"] for obj in annotations]
177
+ masks = convert_coco_poly_to_mask(segmentation_masks, image_height, image_width)
178
+ new_target["masks"] = masks[keep]
179
+
180
+ return new_target
181
+
182
+
183
+ def masks_to_boxes(masks: np.ndarray) -> np.ndarray:
184
+ """
185
+ Compute the bounding boxes around the provided panoptic segmentation masks.
186
+
187
+ Args:
188
+ masks: masks in format `[number_masks, height, width]` where N is the number of masks
189
+
190
+ Returns:
191
+ boxes: bounding boxes in format `[number_masks, 4]` in xyxy format
192
+ """
193
+ if masks.size == 0:
194
+ return np.zeros((0, 4))
195
+
196
+ h, w = masks.shape[-2:]
197
+ y = np.arange(0, h, dtype=np.float32)
198
+ x = np.arange(0, w, dtype=np.float32)
199
+ # see https://github.com/pytorch/pytorch/issues/50276
200
+ y, x = np.meshgrid(y, x, indexing="ij")
201
+
202
+ x_mask = masks * np.expand_dims(x, axis=0)
203
+ x_max = x_mask.reshape(x_mask.shape[0], -1).max(-1)
204
+ x = np.ma.array(x_mask, mask=~(np.array(masks, dtype=bool)))
205
+ x_min = x.filled(fill_value=1e8)
206
+ x_min = x_min.reshape(x_min.shape[0], -1).min(-1)
207
+
208
+ y_mask = masks * np.expand_dims(y, axis=0)
209
+ y_max = y_mask.reshape(x_mask.shape[0], -1).max(-1)
210
+ y = np.ma.array(y_mask, mask=~(np.array(masks, dtype=bool)))
211
+ y_min = y.filled(fill_value=1e8)
212
+ y_min = y_min.reshape(y_min.shape[0], -1).min(-1)
213
+
214
+ return np.stack([x_min, y_min, x_max, y_max], 1)
215
+
216
+
217
+ # 2 functions below adapted from https://github.com/cocodataset/panopticapi/blob/master/panopticapi/utils.py
218
+ # Copyright (c) 2018, Alexander Kirillov
219
+ # All rights reserved.
220
+ def rgb_to_id(color):
221
+ """
222
+ Converts RGB color to unique ID.
223
+ """
224
+ if isinstance(color, np.ndarray) and len(color.shape) == 3:
225
+ if color.dtype == np.uint8:
226
+ color = color.astype(np.int32)
227
+ return color[:, :, 0] + 256 * color[:, :, 1] + 256 * 256 * color[:, :, 2]
228
+ return int(color[0] + 256 * color[1] + 256 * 256 * color[2])
229
+
230
+
231
+ def prepare_coco_panoptic_annotation(
232
+ image: np.ndarray,
233
+ target: dict,
234
+ masks_path: str | pathlib.Path,
235
+ return_masks: bool = True,
236
+ input_data_format: ChannelDimension | str = None,
237
+ ) -> dict:
238
+ """
239
+ Prepare a coco panoptic annotation for GROUNDING_DINO.
240
+ """
241
+ image_height, image_width = get_image_size(image, channel_dim=input_data_format)
242
+ annotation_path = pathlib.Path(masks_path) / target["file_name"]
243
+
244
+ new_target = {}
245
+ new_target["image_id"] = np.asarray([target["image_id"] if "image_id" in target else target["id"]], dtype=np.int64)
246
+ new_target["size"] = np.asarray([image_height, image_width], dtype=np.int64)
247
+ new_target["orig_size"] = np.asarray([image_height, image_width], dtype=np.int64)
248
+
249
+ if "segments_info" in target:
250
+ masks = np.asarray(PIL.Image.open(annotation_path), dtype=np.uint32)
251
+ masks = rgb_to_id(masks)
252
+
253
+ ids = np.array([segment_info["id"] for segment_info in target["segments_info"]])
254
+ masks = masks == ids[:, None, None]
255
+ masks = masks.astype(np.uint8)
256
+ if return_masks:
257
+ new_target["masks"] = masks
258
+ new_target["boxes"] = masks_to_boxes(masks)
259
+ new_target["class_labels"] = np.array(
260
+ [segment_info["category_id"] for segment_info in target["segments_info"]], dtype=np.int64
261
+ )
262
+ new_target["iscrowd"] = np.asarray(
263
+ [segment_info["iscrowd"] for segment_info in target["segments_info"]], dtype=np.int64
264
+ )
265
+ new_target["area"] = np.asarray(
266
+ [segment_info["area"] for segment_info in target["segments_info"]], dtype=np.float32
267
+ )
268
+
269
+ return new_target
270
+
271
+
272
+ def _scale_boxes(boxes, target_sizes):
273
+ """
274
+ Scale batch of bounding boxes to the target sizes.
275
+
276
+ Args:
277
+ boxes (`torch.Tensor` of shape `(batch_size, num_boxes, 4)`):
278
+ Bounding boxes to scale. Each box is expected to be in (x1, y1, x2, y2) format.
279
+ target_sizes (`list[tuple[int, int]]` or `torch.Tensor` of shape `(batch_size, 2)`):
280
+ Target sizes to scale the boxes to. Each target size is expected to be in (height, width) format.
281
+
282
+ Returns:
283
+ `torch.Tensor` of shape `(batch_size, num_boxes, 4)`: Scaled bounding boxes.
284
+ """
285
+
286
+ if isinstance(target_sizes, (list, tuple)):
287
+ image_height = torch.tensor([i[0] for i in target_sizes])
288
+ image_width = torch.tensor([i[1] for i in target_sizes])
289
+ elif isinstance(target_sizes, torch.Tensor):
290
+ image_height, image_width = target_sizes.unbind(1)
291
+ else:
292
+ raise TypeError("`target_sizes` must be a list, tuple or torch.Tensor")
293
+
294
+ scale_factor = torch.stack([image_width, image_height, image_width, image_height], dim=1)
295
+ scale_factor = scale_factor.unsqueeze(1).to(boxes.device)
296
+ boxes = boxes * scale_factor
297
+ return boxes
298
+
299
+
300
+ @auto_docstring
301
+ class GroundingDinoImageProcessorPil(PilBackend):
302
+ resample = PILImageResampling.BILINEAR
303
+ image_mean = IMAGENET_DEFAULT_MEAN
304
+ image_std = IMAGENET_DEFAULT_STD
305
+ format = AnnotationFormat.COCO_DETECTION
306
+ do_resize = True
307
+ do_rescale = True
308
+ do_normalize = True
309
+ do_pad = True
310
+ size = {"shortest_edge": 800, "longest_edge": 1333}
311
+ default_to_square = False
312
+ model_input_names = ["pixel_values", "pixel_mask"]
313
+ valid_kwargs = GroundingDinoImageProcessorKwargs
314
+
315
+ def __init__(self, **kwargs: Unpack[GroundingDinoImageProcessorKwargs]) -> None:
316
+ kwargs.setdefault("do_pad", kwargs.pop("pad_and_return_pixel_mask", self.do_pad))
317
+
318
+ size = kwargs.pop("size", None)
319
+ max_size = None if size is None else kwargs.pop("max_size", 1333)
320
+ size = size if size is not None else {"shortest_edge": 800, "longest_edge": 1333}
321
+ # Convert size dict for backwards compat with max_size parameter
322
+ if size is not None:
323
+ from ...image_processing_utils import get_size_dict
324
+
325
+ kwargs["size"] = get_size_dict(size, max_size=max_size, default_to_square=False)
326
+
327
+ # Backwards compatibility
328
+ do_convert_annotations = kwargs.get("do_convert_annotations")
329
+ do_normalize = kwargs.get("do_normalize")
330
+ if do_convert_annotations is None and getattr(self, "do_convert_annotations", None) is None:
331
+ self.do_convert_annotations = do_normalize if do_normalize is not None else self.do_normalize
332
+
333
+ super().__init__(**kwargs)
334
+
335
+ def prepare_annotation(
336
+ self,
337
+ image: np.ndarray,
338
+ target: dict,
339
+ format: AnnotationFormat | None = None,
340
+ return_segmentation_masks: bool | None = None,
341
+ masks_path: str | pathlib.Path | None = None,
342
+ input_data_format: str | ChannelDimension | None = None,
343
+ ) -> dict:
344
+ """
345
+ Prepare an annotation for feeding into GROUNDING_DINO model.
346
+ """
347
+ format = format if format is not None else self.format
348
+
349
+ if format == AnnotationFormat.COCO_DETECTION:
350
+ return_segmentation_masks = False if return_segmentation_masks is None else return_segmentation_masks
351
+ target = prepare_coco_detection_annotation(
352
+ image, target, return_segmentation_masks, input_data_format=input_data_format
353
+ )
354
+ elif format == AnnotationFormat.COCO_PANOPTIC:
355
+ return_segmentation_masks = True if return_segmentation_masks is None else return_segmentation_masks
356
+ target = prepare_coco_panoptic_annotation(
357
+ image,
358
+ target,
359
+ masks_path=masks_path,
360
+ return_masks=return_segmentation_masks,
361
+ input_data_format=input_data_format,
362
+ )
363
+ else:
364
+ raise ValueError(f"Format {format} is not supported.")
365
+ return target
366
+
367
+ def resize(
368
+ self,
369
+ image: np.ndarray,
370
+ size: SizeDict,
371
+ resample: Optional["PILImageResampling"] = None,
372
+ **kwargs,
373
+ ) -> np.ndarray:
374
+ """
375
+ Resize the image to the given size. Size can be `min_size` (scalar) or `(height, width)` tuple. If size is an
376
+ int, smaller edge of the image will be matched to this number.
377
+
378
+ Args:
379
+ image (`np.ndarray`):
380
+ Image to resize.
381
+ size (`SizeDict`):
382
+ Size of the image's `(height, width)` dimensions after resizing. Available options are:
383
+ - `{"height": int, "width": int}`: The image will be resized to the exact size `(height, width)`.
384
+ Do NOT keep the aspect ratio.
385
+ - `{"shortest_edge": int, "longest_edge": int}`: The image will be resized to a maximum size respecting
386
+ the aspect ratio and keeping the shortest edge less or equal to `shortest_edge` and the longest edge
387
+ less or equal to `longest_edge`.
388
+ - `{"max_height": int, "max_width": int}`: The image will be resized to the maximum size respecting the
389
+ aspect ratio and keeping the height less or equal to `max_height` and the width less or equal to
390
+ `max_width`.
391
+ resample (`PILImageResampling`, *optional*, defaults to `PILImageResampling.BILINEAR`):
392
+ Resampling filter to use if resizing the image.
393
+ """
394
+ resample = resample if resample is not None else self.resample
395
+
396
+ if size.shortest_edge and size.longest_edge:
397
+ # Resize the image so that the shortest edge or the longest edge is of the given size
398
+ # while maintaining the aspect ratio of the original image.
399
+ new_size = get_size_with_aspect_ratio(
400
+ image.shape[-2:],
401
+ size.shortest_edge,
402
+ size.longest_edge or size.shortest_edge,
403
+ )
404
+ elif size.max_height and size.max_width:
405
+ new_size = get_image_size_for_max_height_width(image.shape[-2:], size.max_height, size.max_width)
406
+ elif size.height and size.width:
407
+ new_size = (size.height, size.width)
408
+ else:
409
+ raise ValueError(
410
+ f"Size must contain 'height' and 'width' keys or 'shortest_edge' and 'longest_edge' keys. Got {size}."
411
+ )
412
+
413
+ image = super().resize(
414
+ image,
415
+ size=SizeDict(height=new_size[0], width=new_size[1]),
416
+ resample=resample,
417
+ **kwargs,
418
+ )
419
+ return image
420
+
421
+ def resize_annotation(
422
+ self,
423
+ annotation: dict[str, Any],
424
+ orig_size: tuple[int, int],
425
+ target_size: tuple[int, int],
426
+ threshold: float = 0.5,
427
+ resample: Optional["PILImageResampling"] = PILImageResampling.NEAREST,
428
+ ):
429
+ """
430
+ Resizes an annotation to a target size.
431
+
432
+ Args:
433
+ annotation (`dict[str, Any]`):
434
+ The annotation dictionary.
435
+ orig_size (`tuple[int, int]`):
436
+ The original size of the input image.
437
+ target_size (`tuple[int, int]`):
438
+ The target size of the image, as returned by the preprocessing `resize` step.
439
+ threshold (`float`, *optional*, defaults to 0.5):
440
+ The threshold used to binarize the segmentation masks.
441
+ resample (`PILImageResampling`, defaults to `PILImageResampling.NEAREST`):
442
+ The resampling filter to use when resizing the masks.
443
+ """
444
+ ratios = tuple(float(s) / float(s_orig) for s, s_orig in zip(target_size, orig_size))
445
+ ratio_height, ratio_width = ratios
446
+
447
+ new_annotation = {}
448
+ new_annotation["size"] = target_size
449
+
450
+ for key, value in annotation.items():
451
+ if key == "boxes":
452
+ boxes = value
453
+ scaled_boxes = boxes * np.asarray(
454
+ [ratio_width, ratio_height, ratio_width, ratio_height], dtype=np.float32
455
+ )
456
+ new_annotation["boxes"] = scaled_boxes
457
+ elif key == "area":
458
+ area = value
459
+ scaled_area = area * (ratio_width * ratio_height)
460
+ new_annotation["area"] = scaled_area
461
+ elif key == "masks":
462
+ masks = value[:, None]
463
+ masks = np.array([resize(mask, target_size, resample=resample) for mask in masks])
464
+ masks = masks.astype(np.float32)
465
+ masks = masks[:, 0] > threshold
466
+ new_annotation["masks"] = masks
467
+ elif key == "size":
468
+ new_annotation["size"] = target_size
469
+ else:
470
+ new_annotation[key] = value
471
+
472
+ return new_annotation
473
+
474
+ def normalize_annotation(self, annotation: dict, image_size: tuple[int, int]) -> dict:
475
+ image_height, image_width = image_size
476
+ norm_annotation = {}
477
+ for key, value in annotation.items():
478
+ if key == "boxes":
479
+ boxes = value
480
+ boxes = corners_to_center_format(boxes)
481
+ boxes /= np.asarray([image_width, image_height, image_width, image_height], dtype=np.float32)
482
+ norm_annotation[key] = boxes
483
+ else:
484
+ norm_annotation[key] = value
485
+ return norm_annotation
486
+
487
+ def _update_annotation_for_padded_image(
488
+ self,
489
+ annotation: dict,
490
+ input_image_size: tuple[int, int],
491
+ output_image_size: tuple[int, int],
492
+ padding,
493
+ update_bboxes,
494
+ ) -> dict:
495
+ """
496
+ Update the annotation for a padded image.
497
+ """
498
+ new_annotation = {}
499
+ new_annotation["size"] = output_image_size
500
+ ratio_height, ratio_width = (input / output for output, input in zip(output_image_size, input_image_size))
501
+
502
+ for key, value in annotation.items():
503
+ if key == "masks":
504
+ masks = value
505
+ masks = pad(
506
+ masks,
507
+ padding,
508
+ mode=PaddingMode.CONSTANT,
509
+ constant_values=0,
510
+ input_data_format=ChannelDimension.FIRST,
511
+ )
512
+ masks = safe_squeeze(masks, 1)
513
+ new_annotation["masks"] = masks
514
+ elif key == "boxes" and update_bboxes:
515
+ boxes = value
516
+ boxes *= np.asarray(
517
+ [
518
+ input_image_size[1] / output_image_size[1],
519
+ input_image_size[0] / output_image_size[0],
520
+ input_image_size[1] / output_image_size[1],
521
+ input_image_size[0] / output_image_size[0],
522
+ ]
523
+ )
524
+ new_annotation["boxes"] = boxes
525
+ elif key == "size":
526
+ new_annotation["size"] = output_image_size
527
+ else:
528
+ new_annotation[key] = value
529
+ return new_annotation
530
+
531
+ def pad(
532
+ self,
533
+ image: np.ndarray,
534
+ padded_size: tuple[int, int],
535
+ annotation: dict[str, Any] | None = None,
536
+ update_bboxes: bool = True,
537
+ fill: int = 0,
538
+ ):
539
+ input_height, input_width = get_image_size(image, channel_dim=ChannelDimension.FIRST)
540
+ output_height, output_width = padded_size
541
+ padding_bottom = output_height - input_height
542
+ padding_right = output_width - input_width
543
+ if padding_bottom < 0 or padding_right < 0:
544
+ raise ValueError(
545
+ f"Padding dimensions are negative. Please make sure that the padded size is larger than the "
546
+ f"original size. Got padded size: {padded_size}, original size: {(input_height, input_width)}."
547
+ )
548
+ if (input_height, input_width) != padded_size:
549
+ padding = ((0, padding_bottom), (0, padding_right))
550
+ image = pad(
551
+ image,
552
+ padding,
553
+ mode=PaddingMode.CONSTANT,
554
+ constant_values=fill,
555
+ data_format=ChannelDimension.FIRST,
556
+ input_data_format=ChannelDimension.FIRST,
557
+ )
558
+ if annotation is not None:
559
+ annotation = self._update_annotation_for_padded_image(
560
+ annotation, (input_height, input_width), (output_height, output_width), padding, update_bboxes
561
+ )
562
+
563
+ # Make a pixel mask for the image, where 1 indicates a valid pixel and 0 indicates padding.
564
+ pixel_mask = np.zeros(padded_size, dtype=np.int64)
565
+ pixel_mask[:input_height, :input_width] = 1
566
+
567
+ return image, pixel_mask, annotation
568
+
569
+ @auto_docstring
570
+ def preprocess(
571
+ self,
572
+ images: ImageInput,
573
+ annotations: AnnotationType | list[AnnotationType] | None = None,
574
+ return_segmentation_masks: bool | None = None,
575
+ masks_path: str | pathlib.Path | None = None,
576
+ **kwargs: Unpack[GroundingDinoImageProcessorKwargs],
577
+ ) -> BatchFeature:
578
+ r"""
579
+ annotations (`AnnotationType` or `list[AnnotationType]`, *optional*):
580
+ Annotations to transform according to the padding that is applied to the images.
581
+ return_segmentation_masks (`bool`, *optional*, defaults to `self.return_segmentation_masks`):
582
+ Whether to return segmentation masks.
583
+ masks_path (`str` or `pathlib.Path`, *optional*):
584
+ Path to the directory containing the segmentation masks.
585
+ """
586
+ return super().preprocess(images, annotations, return_segmentation_masks, masks_path, **kwargs)
587
+
588
+ def _preprocess(
589
+ self,
590
+ images: list[np.ndarray],
591
+ annotations: AnnotationType | list[AnnotationType] | None,
592
+ return_segmentation_masks: bool,
593
+ masks_path: str | pathlib.Path | None,
594
+ do_resize: bool,
595
+ size: SizeDict,
596
+ resample: "PILImageResampling | None",
597
+ do_rescale: bool,
598
+ rescale_factor: float,
599
+ do_normalize: bool,
600
+ do_convert_annotations: bool,
601
+ image_mean: float | list[float] | None,
602
+ image_std: float | list[float] | None,
603
+ do_pad: bool,
604
+ pad_size: SizeDict | None,
605
+ format: str | AnnotationFormat | None,
606
+ return_tensors: str | TensorType | None,
607
+ **kwargs,
608
+ ) -> BatchFeature:
609
+ """
610
+ Preprocess an image or a batch of images so that it can be used by the model.
611
+ """
612
+ if annotations is not None and isinstance(annotations, dict):
613
+ annotations = [annotations]
614
+
615
+ if annotations is not None and len(images) != len(annotations):
616
+ raise ValueError(
617
+ f"The number of images ({len(images)}) and annotations ({len(annotations)}) do not match."
618
+ )
619
+
620
+ format = AnnotationFormat(format)
621
+ if annotations is not None:
622
+ validate_annotations(format, SUPPORTED_ANNOTATION_FORMATS, annotations)
623
+
624
+ if (
625
+ masks_path is not None
626
+ and format == AnnotationFormat.COCO_PANOPTIC
627
+ and not isinstance(masks_path, (pathlib.Path, str))
628
+ ):
629
+ raise ValueError(
630
+ "The path to the directory containing the mask PNG files should be provided as a"
631
+ f" `pathlib.Path` or string object, but is {type(masks_path)} instead."
632
+ )
633
+
634
+ data = {}
635
+
636
+ # Import torch if needed for tensor conversion
637
+ if return_tensors == "pt":
638
+ if not is_torch_available():
639
+ raise ImportError("PyTorch is required for tensor conversion.")
640
+
641
+ processed_images = []
642
+ processed_annotations = []
643
+ pixel_masks = [] # Initialize pixel_masks here
644
+ for image, annotation in zip(images, annotations if annotations is not None else [None] * len(images)):
645
+ # prepare (COCO annotations as a list of Dict -> GROUNDING_DINO target as a single Dict per image)
646
+ if annotations is not None:
647
+ annotation = self.prepare_annotation(
648
+ image,
649
+ annotation,
650
+ format,
651
+ return_segmentation_masks=return_segmentation_masks,
652
+ masks_path=masks_path,
653
+ input_data_format=ChannelDimension.FIRST,
654
+ )
655
+
656
+ if do_resize:
657
+ resized_image = self.resize(image, size=size, resample=resample)
658
+ if annotations is not None:
659
+ annotation = self.resize_annotation(
660
+ annotation,
661
+ orig_size=get_image_size(image, channel_dim=ChannelDimension.FIRST),
662
+ target_size=get_image_size(resized_image, channel_dim=ChannelDimension.FIRST),
663
+ )
664
+ image = resized_image
665
+
666
+ if do_rescale:
667
+ image = self.rescale(image, rescale_factor)
668
+ if do_normalize:
669
+ image = self.normalize(image, image_mean, image_std)
670
+
671
+ if do_convert_annotations and annotations is not None:
672
+ annotation = self.normalize_annotation(annotation, get_image_size(image, ChannelDimension.FIRST))
673
+
674
+ processed_images.append(image)
675
+ processed_annotations.append(annotation)
676
+ images = processed_images
677
+ annotations = processed_annotations if annotations is not None else None
678
+
679
+ if do_pad:
680
+ # depends on all resized image shapes so we need another loop
681
+ if pad_size is not None:
682
+ padded_size = (pad_size.height, pad_size.width)
683
+ else:
684
+ padded_size = get_max_height_width(images, input_data_format=ChannelDimension.FIRST)
685
+
686
+ padded_images = []
687
+ padded_annotations = []
688
+ for image, annotation in zip(images, annotations if annotations is not None else [None] * len(images)):
689
+ # Pads images and returns their mask: {'pixel_values': ..., 'pixel_mask': ...}
690
+ image_height, image_width = get_image_size(image, channel_dim=ChannelDimension.FIRST)
691
+ if padded_size == (image_height, image_width):
692
+ padded_images.append(image)
693
+ pixel_masks.append(np.ones(padded_size, dtype=np.int64))
694
+ padded_annotations.append(annotation)
695
+ continue
696
+ image, pixel_mask, annotation = self.pad(
697
+ image, padded_size, annotation=annotation, update_bboxes=do_convert_annotations
698
+ )
699
+ padded_images.append(image)
700
+ padded_annotations.append(annotation)
701
+ pixel_masks.append(pixel_mask)
702
+ images = padded_images
703
+ annotations = padded_annotations if annotations is not None else None
704
+ data.update({"pixel_mask": pixel_masks})
705
+
706
+ data.update({"pixel_values": images})
707
+ encoded_inputs = BatchFeature(data, tensor_type=return_tensors)
708
+ if annotations is not None:
709
+ encoded_inputs["labels"] = [
710
+ BatchFeature(annotation, tensor_type=return_tensors) for annotation in annotations
711
+ ]
712
+ return encoded_inputs
713
+
714
+ @requires(backends=("torch",))
715
+ def post_process_object_detection(
716
+ self,
717
+ outputs: "GroundingDinoObjectDetectionOutput",
718
+ threshold: float = 0.1,
719
+ target_sizes: TensorType | list[tuple] | None = None,
720
+ ):
721
+ """
722
+ Converts the raw output of [`GroundingDinoForObjectDetection`] into final bounding boxes in (top_left_x, top_left_y,
723
+ bottom_right_x, bottom_right_y) format.
724
+
725
+ Args:
726
+ outputs ([`GroundingDinoObjectDetectionOutput`]):
727
+ Raw outputs of the model.
728
+ threshold (`float`, *optional*, defaults to 0.1):
729
+ Score threshold to keep object detection predictions.
730
+ target_sizes (`torch.Tensor` or `list[tuple[int, int]]`, *optional*):
731
+ Tensor of shape `(batch_size, 2)` or list of tuples (`tuple[int, int]`) containing the target size
732
+ `(height, width)` of each image in the batch. If unset, predictions will not be resized.
733
+
734
+ Returns:
735
+ `list[Dict]`: A list of dictionaries, each dictionary containing the following keys:
736
+ - "scores": The confidence scores for each predicted box on the image.
737
+ - "labels": Indexes of the classes predicted by the model on the image.
738
+ - "boxes": Image bounding boxes in (top_left_x, top_left_y, bottom_right_x, bottom_right_y) format.
739
+ """
740
+ requires_backends(self, ["torch"])
741
+ batch_logits, batch_boxes = outputs.logits, outputs.pred_boxes
742
+ batch_size = len(batch_logits)
743
+
744
+ if target_sizes is not None and len(target_sizes) != batch_size:
745
+ raise ValueError("Make sure that you pass in as many target sizes as images")
746
+
747
+ # batch_logits of shape (batch_size, num_queries, num_classes)
748
+ batch_class_logits = torch.max(batch_logits, dim=-1)
749
+ batch_scores = torch.sigmoid(batch_class_logits.values)
750
+ batch_labels = batch_class_logits.indices
751
+
752
+ # Convert to [x0, y0, x1, y1] format
753
+ batch_boxes = center_to_corners_format(batch_boxes)
754
+
755
+ # Convert from relative [0, 1] to absolute [0, height] coordinates
756
+ if target_sizes is not None:
757
+ batch_boxes = _scale_boxes(batch_boxes, target_sizes)
758
+
759
+ results = []
760
+ for scores, labels, boxes in zip(batch_scores, batch_labels, batch_boxes):
761
+ keep = scores > threshold
762
+ scores = scores[keep]
763
+ labels = labels[keep]
764
+ boxes = boxes[keep]
765
+ results.append({"scores": scores, "labels": labels, "boxes": boxes})
766
+
767
+ return results
768
+
769
+
770
+ __all__ = ["GroundingDinoImageProcessorPil"]
LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/transformers/models/grounding_dino/modeling_grounding_dino.py 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/transformers/models/grounding_dino/modular_grounding_dino.py ADDED
@@ -0,0 +1,201 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2025 the HuggingFace Inc. team. All rights reserved.
2
+ #
3
+ # This code is based on EleutherAI's GPT-NeoX library and the GPT-NeoX
4
+ # and OPT implementations in this library. It has been modified from its
5
+ # original forms to accommodate minor architectural differences compared
6
+ # to GPT-NeoX and OPT used by the Meta AI team that trained the model.
7
+ #
8
+ # Licensed under the Apache License, Version 2.0 (the "License");
9
+ # you may not use this file except in compliance with the License.
10
+ # You may obtain a copy of the License at
11
+ #
12
+ # http://www.apache.org/licenses/LICENSE-2.0
13
+ #
14
+ # Unless required by applicable law or agreed to in writing, software
15
+ # distributed under the License is distributed on an "AS IS" BASIS,
16
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
+ # See the License for the specific language governing permissions and
18
+ # limitations under the License.
19
+
20
+ from typing import TYPE_CHECKING
21
+
22
+ import torch
23
+
24
+ from transformers.models.detr.image_processing_detr import DetrImageProcessor
25
+ from transformers.models.detr.image_processing_pil_detr import DetrImageProcessorPil
26
+
27
+ from ...image_transforms import center_to_corners_format
28
+ from ...utils import (
29
+ TensorType,
30
+ logging,
31
+ requires_backends,
32
+ )
33
+ from ...utils.import_utils import requires
34
+
35
+
36
+ if TYPE_CHECKING:
37
+ from .modeling_grounding_dino import GroundingDinoObjectDetectionOutput
38
+
39
+
40
+ logger = logging.get_logger(__name__)
41
+
42
+
43
+ def _scale_boxes(boxes, target_sizes):
44
+ """
45
+ Scale batch of bounding boxes to the target sizes.
46
+
47
+ Args:
48
+ boxes (`torch.Tensor` of shape `(batch_size, num_boxes, 4)`):
49
+ Bounding boxes to scale. Each box is expected to be in (x1, y1, x2, y2) format.
50
+ target_sizes (`list[tuple[int, int]]` or `torch.Tensor` of shape `(batch_size, 2)`):
51
+ Target sizes to scale the boxes to. Each target size is expected to be in (height, width) format.
52
+
53
+ Returns:
54
+ `torch.Tensor` of shape `(batch_size, num_boxes, 4)`: Scaled bounding boxes.
55
+ """
56
+
57
+ if isinstance(target_sizes, (list, tuple)):
58
+ image_height = torch.tensor([i[0] for i in target_sizes])
59
+ image_width = torch.tensor([i[1] for i in target_sizes])
60
+ elif isinstance(target_sizes, torch.Tensor):
61
+ image_height, image_width = target_sizes.unbind(1)
62
+ else:
63
+ raise TypeError("`target_sizes` must be a list, tuple or torch.Tensor")
64
+
65
+ scale_factor = torch.stack([image_width, image_height, image_width, image_height], dim=1)
66
+ scale_factor = scale_factor.unsqueeze(1).to(boxes.device)
67
+ boxes = boxes * scale_factor
68
+ return boxes
69
+
70
+
71
+ class GroundingDinoImageProcessor(DetrImageProcessor):
72
+ def post_process_object_detection(
73
+ self,
74
+ outputs: "GroundingDinoObjectDetectionOutput",
75
+ threshold: float = 0.1,
76
+ target_sizes: TensorType | list[tuple] | None = None,
77
+ ):
78
+ """
79
+ Converts the raw output of [`GroundingDinoForObjectDetection`] into final bounding boxes in (top_left_x, top_left_y,
80
+ bottom_right_x, bottom_right_y) format.
81
+
82
+ Args:
83
+ outputs ([`GroundingDinoObjectDetectionOutput`]):
84
+ Raw outputs of the model.
85
+ threshold (`float`, *optional*, defaults to 0.1):
86
+ Score threshold to keep object detection predictions.
87
+ target_sizes (`torch.Tensor` or `list[tuple[int, int]]`, *optional*):
88
+ Tensor of shape `(batch_size, 2)` or list of tuples (`tuple[int, int]`) containing the target size
89
+ `(height, width)` of each image in the batch. If unset, predictions will not be resized.
90
+
91
+ Returns:
92
+ `list[Dict]`: A list of dictionaries, each dictionary containing the following keys:
93
+ - "scores": The confidence scores for each predicted box on the image.
94
+ - "labels": Indexes of the classes predicted by the model on the image.
95
+ - "boxes": Image bounding boxes in (top_left_x, top_left_y, bottom_right_x, bottom_right_y) format.
96
+ """
97
+ batch_logits, batch_boxes = outputs.logits, outputs.pred_boxes
98
+ batch_size = len(batch_logits)
99
+
100
+ if target_sizes is not None and len(target_sizes) != batch_size:
101
+ raise ValueError("Make sure that you pass in as many target sizes as images")
102
+
103
+ # batch_logits of shape (batch_size, num_queries, num_classes)
104
+ batch_class_logits = torch.max(batch_logits, dim=-1)
105
+ batch_scores = torch.sigmoid(batch_class_logits.values)
106
+ batch_labels = batch_class_logits.indices
107
+
108
+ # Convert to [x0, y0, x1, y1] format
109
+ batch_boxes = center_to_corners_format(batch_boxes)
110
+
111
+ # Convert from relative [0, 1] to absolute [0, height] coordinates
112
+ if target_sizes is not None:
113
+ batch_boxes = _scale_boxes(batch_boxes, target_sizes)
114
+
115
+ results = []
116
+ for scores, labels, boxes in zip(batch_scores, batch_labels, batch_boxes):
117
+ keep = scores > threshold
118
+ scores = scores[keep]
119
+ labels = labels[keep]
120
+ boxes = boxes[keep]
121
+ results.append({"scores": scores, "labels": labels, "boxes": boxes})
122
+
123
+ return results
124
+
125
+ def post_process_instance_segmentation(self):
126
+ raise NotImplementedError("Segmentation post-processing is not implemented for Grounding-Dino yet.")
127
+
128
+ def post_process_semantic_segmentation(self):
129
+ raise NotImplementedError("Semantic segmentation post-processing is not implemented for Grounding-Dino yet.")
130
+
131
+ def post_process_panoptic_segmentation(self):
132
+ raise NotImplementedError("Panoptic segmentation post-processing is not implemented for Grounding-Dino yet.")
133
+
134
+
135
+ class GroundingDinoImageProcessorPil(DetrImageProcessorPil):
136
+ @requires(backends=("torch",))
137
+ def post_process_object_detection(
138
+ self,
139
+ outputs: "GroundingDinoObjectDetectionOutput",
140
+ threshold: float = 0.1,
141
+ target_sizes: TensorType | list[tuple] | None = None,
142
+ ):
143
+ """
144
+ Converts the raw output of [`GroundingDinoForObjectDetection`] into final bounding boxes in (top_left_x, top_left_y,
145
+ bottom_right_x, bottom_right_y) format.
146
+
147
+ Args:
148
+ outputs ([`GroundingDinoObjectDetectionOutput`]):
149
+ Raw outputs of the model.
150
+ threshold (`float`, *optional*, defaults to 0.1):
151
+ Score threshold to keep object detection predictions.
152
+ target_sizes (`torch.Tensor` or `list[tuple[int, int]]`, *optional*):
153
+ Tensor of shape `(batch_size, 2)` or list of tuples (`tuple[int, int]`) containing the target size
154
+ `(height, width)` of each image in the batch. If unset, predictions will not be resized.
155
+
156
+ Returns:
157
+ `list[Dict]`: A list of dictionaries, each dictionary containing the following keys:
158
+ - "scores": The confidence scores for each predicted box on the image.
159
+ - "labels": Indexes of the classes predicted by the model on the image.
160
+ - "boxes": Image bounding boxes in (top_left_x, top_left_y, bottom_right_x, bottom_right_y) format.
161
+ """
162
+ requires_backends(self, ["torch"])
163
+ batch_logits, batch_boxes = outputs.logits, outputs.pred_boxes
164
+ batch_size = len(batch_logits)
165
+
166
+ if target_sizes is not None and len(target_sizes) != batch_size:
167
+ raise ValueError("Make sure that you pass in as many target sizes as images")
168
+
169
+ # batch_logits of shape (batch_size, num_queries, num_classes)
170
+ batch_class_logits = torch.max(batch_logits, dim=-1)
171
+ batch_scores = torch.sigmoid(batch_class_logits.values)
172
+ batch_labels = batch_class_logits.indices
173
+
174
+ # Convert to [x0, y0, x1, y1] format
175
+ batch_boxes = center_to_corners_format(batch_boxes)
176
+
177
+ # Convert from relative [0, 1] to absolute [0, height] coordinates
178
+ if target_sizes is not None:
179
+ batch_boxes = _scale_boxes(batch_boxes, target_sizes)
180
+
181
+ results = []
182
+ for scores, labels, boxes in zip(batch_scores, batch_labels, batch_boxes):
183
+ keep = scores > threshold
184
+ scores = scores[keep]
185
+ labels = labels[keep]
186
+ boxes = boxes[keep]
187
+ results.append({"scores": scores, "labels": labels, "boxes": boxes})
188
+
189
+ return results
190
+
191
+ def post_process_instance_segmentation(self):
192
+ raise NotImplementedError("Segmentation post-processing is not implemented for Grounding-Dino yet.")
193
+
194
+ def post_process_semantic_segmentation(self):
195
+ raise NotImplementedError("Semantic segmentation post-processing is not implemented for Grounding-Dino yet.")
196
+
197
+ def post_process_panoptic_segmentation(self):
198
+ raise NotImplementedError("Panoptic segmentation post-processing is not implemented for Grounding-Dino yet.")
199
+
200
+
201
+ __all__ = ["GroundingDinoImageProcessor", "GroundingDinoImageProcessorPil"]
LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/transformers/models/grounding_dino/processing_grounding_dino.py ADDED
@@ -0,0 +1,236 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2024 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
+ """
15
+ Processor class for Grounding DINO.
16
+ """
17
+
18
+ import warnings
19
+ from typing import TYPE_CHECKING
20
+
21
+ from ...image_transforms import center_to_corners_format
22
+ from ...image_utils import ImageInput
23
+ from ...processing_utils import ProcessingKwargs, ProcessorMixin, Unpack
24
+ from ...tokenization_utils_base import BatchEncoding, PreTokenizedInput, TextInput
25
+ from ...utils import TensorType, auto_docstring, is_torch_available
26
+
27
+
28
+ if is_torch_available():
29
+ import torch
30
+
31
+ if TYPE_CHECKING:
32
+ from .modeling_grounding_dino import GroundingDinoObjectDetectionOutput
33
+
34
+
35
+ AnnotationType = dict[str, int | str | list[dict]]
36
+
37
+
38
+ def get_phrases_from_posmap(posmaps, input_ids):
39
+ """Get token ids of phrases from posmaps and input_ids.
40
+
41
+ Args:
42
+ posmaps (`torch.BoolTensor` of shape `(num_boxes, hidden_size)`):
43
+ A boolean tensor of text-thresholded logits related to the detected bounding boxes.
44
+ input_ids (`torch.LongTensor`) of shape `(sequence_length, )`):
45
+ A tensor of token ids.
46
+ """
47
+ left_idx = 0
48
+ right_idx = posmaps.shape[-1] - 1
49
+
50
+ # Avoiding altering the input tensor
51
+ posmaps = posmaps.clone()
52
+
53
+ posmaps[:, 0 : left_idx + 1] = False
54
+ posmaps[:, right_idx:] = False
55
+
56
+ token_ids = []
57
+ for posmap in posmaps:
58
+ non_zero_idx = posmap.nonzero(as_tuple=True)[0].tolist()
59
+ token_ids.append([input_ids[i] for i in non_zero_idx])
60
+
61
+ return token_ids
62
+
63
+
64
+ def _is_list_of_candidate_labels(text) -> bool:
65
+ """Check that text is list/tuple of strings and each string is a candidate label and not merged candidate labels text.
66
+ Merged candidate labels text is a string with candidate labels separated by a dot.
67
+ """
68
+ if isinstance(text, (list, tuple)):
69
+ return all(isinstance(t, str) and "." not in t for t in text)
70
+ return False
71
+
72
+
73
+ def _merge_candidate_labels_text(text: list[str]) -> str:
74
+ """
75
+ Merge candidate labels text into a single string. Ensure all labels are lowercase.
76
+ For example, ["A cat", "a dog"] -> "a cat. a dog."
77
+ """
78
+ labels = [t.strip().lower() for t in text] # ensure lowercase
79
+ merged_labels_str = ". ".join(labels) + "." # join with dot and add a dot at the end
80
+ return merged_labels_str
81
+
82
+
83
+ class DictWithDeprecationWarning(dict):
84
+ message = (
85
+ "The key `labels` is will return integer ids in `GroundingDinoProcessor.post_process_grounded_object_detection` "
86
+ "output since v4.51.0. Use `text_labels` instead to retrieve string object names."
87
+ )
88
+
89
+ def __getitem__(self, key):
90
+ if key == "labels":
91
+ warnings.warn(self.message, FutureWarning)
92
+ return super().__getitem__(key)
93
+
94
+ def get(self, key, *args, **kwargs):
95
+ if key == "labels":
96
+ warnings.warn(self.message, FutureWarning)
97
+ return super().get(key, *args, **kwargs)
98
+
99
+
100
+ class GroundingDinoProcessorKwargs(ProcessingKwargs, total=False):
101
+ _defaults = {
102
+ "text_kwargs": {
103
+ "add_special_tokens": True,
104
+ "padding": False,
105
+ "stride": 0,
106
+ "return_overflowing_tokens": False,
107
+ "return_special_tokens_mask": False,
108
+ "return_offsets_mapping": False,
109
+ "return_token_type_ids": True,
110
+ "return_length": False,
111
+ "verbose": True,
112
+ }
113
+ }
114
+
115
+
116
+ @auto_docstring
117
+ class GroundingDinoProcessor(ProcessorMixin):
118
+ valid_processor_kwargs = GroundingDinoProcessorKwargs
119
+
120
+ def __init__(self, image_processor, tokenizer):
121
+ super().__init__(image_processor, tokenizer)
122
+
123
+ @auto_docstring
124
+ def __call__(
125
+ self,
126
+ images: ImageInput | None = None,
127
+ text: TextInput | PreTokenizedInput | list[TextInput] | list[PreTokenizedInput] = None,
128
+ **kwargs: Unpack[GroundingDinoProcessorKwargs],
129
+ ) -> BatchEncoding:
130
+ if text is not None:
131
+ text = self._preprocess_input_text(text)
132
+ return super().__call__(images=images, text=text, **kwargs)
133
+
134
+ def _preprocess_input_text(self, text):
135
+ """
136
+ Preprocess input text to ensure that labels are in the correct format for the model.
137
+ If the text is a list of candidate labels, merge the candidate labels into a single string,
138
+ for example, ["a cat", "a dog"] -> "a cat. a dog.". In case candidate labels are already in a form of
139
+ "a cat. a dog.", the text is returned as is.
140
+ """
141
+
142
+ if _is_list_of_candidate_labels(text):
143
+ text = _merge_candidate_labels_text(text)
144
+
145
+ # for batched input
146
+ elif isinstance(text, (list, tuple)) and all(_is_list_of_candidate_labels(t) for t in text):
147
+ text = [_merge_candidate_labels_text(sample) for sample in text]
148
+
149
+ return text
150
+
151
+ def post_process_grounded_object_detection(
152
+ self,
153
+ outputs: "GroundingDinoObjectDetectionOutput",
154
+ input_ids: TensorType | None = None,
155
+ threshold: float = 0.25,
156
+ text_threshold: float = 0.25,
157
+ target_sizes: TensorType | list[tuple] | None = None,
158
+ text_labels: list[list[str]] | None = None,
159
+ ):
160
+ """
161
+ Converts the raw output of [`GroundingDinoForObjectDetection`] into final bounding boxes in (top_left_x, top_left_y,
162
+ bottom_right_x, bottom_right_y) format and get the associated text label.
163
+
164
+ Args:
165
+ outputs ([`GroundingDinoObjectDetectionOutput`]):
166
+ Raw outputs of the model.
167
+ input_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):
168
+ The token ids of the input text. If not provided will be taken from the model output.
169
+ threshold (`float`, *optional*, defaults to 0.25):
170
+ Threshold to keep object detection predictions based on confidence score.
171
+ text_threshold (`float`, *optional*, defaults to 0.25):
172
+ Score threshold to keep text detection predictions.
173
+ target_sizes (`torch.Tensor` or `list[tuple[int, int]]`, *optional*):
174
+ Tensor of shape `(batch_size, 2)` or list of tuples (`tuple[int, int]`) containing the target size
175
+ `(height, width)` of each image in the batch. If unset, predictions will not be resized.
176
+ text_labels (`list[list[str]]`, *optional*):
177
+ List of candidate labels to be detected on each image. At the moment it's *NOT used*, but required
178
+ to be in signature for the zero-shot object detection pipeline. Text labels are instead extracted
179
+ from the `input_ids` tensor provided in `outputs`.
180
+
181
+ Returns:
182
+ `list[Dict]`: A list of dictionaries, each dictionary containing the
183
+ - **scores**: tensor of confidence scores for detected objects
184
+ - **boxes**: tensor of bounding boxes in [x0, y0, x1, y1] format
185
+ - **labels**: list of text labels for each detected object (will be replaced with integer ids in v4.51.0)
186
+ - **text_labels**: list of text labels for detected objects
187
+ """
188
+ batch_logits, batch_boxes = outputs.logits, outputs.pred_boxes
189
+ input_ids = input_ids if input_ids is not None else outputs.input_ids
190
+
191
+ if target_sizes is not None and len(target_sizes) != len(batch_logits):
192
+ raise ValueError("Make sure that you pass in as many target sizes as the batch dimension of the logits")
193
+
194
+ batch_probs = torch.sigmoid(batch_logits) # (batch_size, num_queries, 256)
195
+ batch_scores = torch.max(batch_probs, dim=-1)[0] # (batch_size, num_queries)
196
+
197
+ # Convert to [x0, y0, x1, y1] format
198
+ batch_boxes = center_to_corners_format(batch_boxes)
199
+
200
+ # Convert from relative [0, 1] to absolute [0, height] coordinates
201
+ if target_sizes is not None:
202
+ if isinstance(target_sizes, list):
203
+ img_h = torch.Tensor([i[0] for i in target_sizes])
204
+ img_w = torch.Tensor([i[1] for i in target_sizes])
205
+ else:
206
+ img_h, img_w = target_sizes.unbind(1)
207
+
208
+ scale_fct = torch.stack([img_w, img_h, img_w, img_h], dim=1).to(batch_boxes.device)
209
+ batch_boxes = batch_boxes * scale_fct[:, None, :]
210
+
211
+ results = []
212
+ for idx, (scores, boxes, probs) in enumerate(zip(batch_scores, batch_boxes, batch_probs)):
213
+ keep = scores > threshold
214
+ scores = scores[keep]
215
+ boxes = boxes[keep]
216
+
217
+ # extract text labels
218
+ prob = probs[keep]
219
+ label_ids = get_phrases_from_posmap(prob > text_threshold, input_ids[idx])
220
+ objects_text_labels = self.batch_decode(label_ids)
221
+
222
+ result = DictWithDeprecationWarning(
223
+ {
224
+ "scores": scores,
225
+ "boxes": boxes,
226
+ "text_labels": objects_text_labels,
227
+ # TODO: @pavel, set labels to None since v4.51.0 or find a way to extract ids
228
+ "labels": objects_text_labels,
229
+ }
230
+ )
231
+ results.append(result)
232
+
233
+ return results
234
+
235
+
236
+ __all__ = ["GroundingDinoProcessor"]
LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/transformers/models/paddleocr_vl/image_processing_pil_paddleocr_vl.py ADDED
@@ -0,0 +1,251 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨
2
+ # This file was automatically generated from src/transformers/models/paddleocr_vl/modular_paddleocr_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_paddleocr_vl.py file directly. One of our CI enforces this.
6
+ # 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨
7
+ # Copyright 2025 The PaddlePaddle Team and The HuggingFace Inc. team. All rights reserved.
8
+ #
9
+ # This code is based on EleutherAI's GPT-NeoX library and the GPT-NeoX
10
+ # and OPT implementations in this library. It has been modified from its
11
+ # original forms to accommodate minor architectural differences compared
12
+ # to GPT-NeoX and OPT used by the Meta AI team that trained the model.
13
+ #
14
+ # Licensed under the Apache License, Version 2.0 (the "License");
15
+ # you may not use this file except in compliance with the License.
16
+ # You may obtain a copy of the License at
17
+ #
18
+ # http://www.apache.org/licenses/LICENSE-2.0
19
+ #
20
+ # Unless required by applicable law or agreed to in writing, software
21
+ # distributed under the License is distributed on an "AS IS" BASIS,
22
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
23
+ # See the License for the specific language governing permissions and
24
+ # limitations under the License.
25
+
26
+ import math
27
+ from collections.abc import Iterable
28
+
29
+ import numpy as np
30
+
31
+ from ...image_processing_backends import PilBackend
32
+ from ...image_processing_utils import BatchFeature
33
+ from ...image_utils import OPENAI_CLIP_MEAN, OPENAI_CLIP_STD, ImageInput, PILImageResampling, SizeDict
34
+ from ...processing_utils import ImagesKwargs, Unpack
35
+ from ...utils import TensorType, auto_docstring
36
+
37
+
38
+ class PaddleOCRVLImageProcessorKwargs(ImagesKwargs, total=False):
39
+ r"""
40
+ patch_size (`int`, *optional*, defaults to 14):
41
+ The spatial patch size of the vision encoder.
42
+ temporal_patch_size (`int`, *optional*, defaults to 1):
43
+ The temporal patch size of the vision encoder.
44
+ merge_size (`int`, *optional*, defaults to 2):
45
+ The merge size of the vision encoder to llm encoder.
46
+ """
47
+
48
+ min_pixels: int
49
+ max_pixels: int
50
+ patch_size: int
51
+ temporal_patch_size: int
52
+ merge_size: int
53
+
54
+
55
+ def smart_resize(
56
+ height: int,
57
+ width: int,
58
+ factor: int = 28,
59
+ min_pixels: int = 384 * 384,
60
+ max_pixels: int = 1536 * 1536,
61
+ ):
62
+ if height < factor:
63
+ width = round((width * factor) / height)
64
+ height = factor
65
+
66
+ if width < factor:
67
+ height = round((height * factor) / width)
68
+ width = factor
69
+
70
+ if max(height, width) / min(height, width) > 200:
71
+ raise ValueError(
72
+ f"absolute aspect ratio must be smaller than 200, got {max(height, width) / min(height, width)}"
73
+ )
74
+ h_bar = round(height / factor) * factor
75
+ w_bar = round(width / factor) * factor
76
+ if h_bar * w_bar > max_pixels:
77
+ beta = math.sqrt((height * width) / max_pixels)
78
+ h_bar = max(factor, math.floor(height / beta / factor) * factor)
79
+ w_bar = max(factor, math.floor(width / beta / factor) * factor)
80
+ elif h_bar * w_bar < min_pixels:
81
+ beta = math.sqrt(min_pixels / (height * width))
82
+ h_bar = math.ceil(height * beta / factor) * factor
83
+ w_bar = math.ceil(width * beta / factor) * factor
84
+ return h_bar, w_bar
85
+
86
+
87
+ @auto_docstring
88
+ class PaddleOCRVLImageProcessorPil(PilBackend):
89
+ do_resize = True
90
+ resample = PILImageResampling.BICUBIC
91
+ size = {"shortest_edge": 384 * 384, "longest_edge": 1536 * 1536}
92
+ default_to_square = False
93
+ do_rescale = True
94
+ do_normalize = True
95
+ image_mean = OPENAI_CLIP_MEAN
96
+ image_std = OPENAI_CLIP_STD
97
+ do_convert_rgb = True
98
+ patch_size = 14
99
+ temporal_patch_size = 1
100
+ merge_size = 2
101
+ valid_kwargs = PaddleOCRVLImageProcessorKwargs
102
+ model_input_names = ["pixel_values", "image_grid_thw"]
103
+
104
+ def __init__(self, **kwargs: Unpack[PaddleOCRVLImageProcessorKwargs]):
105
+ size = kwargs.pop("size", None)
106
+ min_pixels = kwargs.pop("min_pixels", None)
107
+ max_pixels = kwargs.pop("max_pixels", None)
108
+ # backward compatibility: override size with min_pixels and max_pixels if they are provided
109
+ size = self.size if size is None else size
110
+ if min_pixels is not None:
111
+ size["shortest_edge"] = min_pixels
112
+ size.pop("min_pixels", None)
113
+ if max_pixels is not None:
114
+ size["longest_edge"] = max_pixels
115
+ size.pop("max_pixels", None)
116
+ if "shortest_edge" not in size or "longest_edge" not in size:
117
+ raise ValueError("size must contain 'shortest_edge' and 'longest_edge' keys.")
118
+
119
+ super().__init__(size=size, **kwargs)
120
+
121
+ def _standardize_kwargs(
122
+ self,
123
+ size: int | Iterable[int] | dict[str, int] | SizeDict | None = None,
124
+ min_pixels: int | None = None,
125
+ max_pixels: int | None = None,
126
+ **kwargs,
127
+ ) -> dict:
128
+ if min_pixels is not None and max_pixels is not None:
129
+ size = SizeDict(shortest_edge=min_pixels, longest_edge=max_pixels)
130
+ kwargs = super()._standardize_kwargs(size=size, **kwargs)
131
+ size = kwargs.get("size", self.size)
132
+ if not size.shortest_edge or not size.longest_edge:
133
+ raise ValueError("size must contain 'shortest_edge' and 'longest_edge' keys.")
134
+ return kwargs
135
+
136
+ @auto_docstring
137
+ def preprocess(
138
+ self,
139
+ images: ImageInput,
140
+ **kwargs: Unpack[PaddleOCRVLImageProcessorKwargs],
141
+ ) -> BatchFeature:
142
+ return super().preprocess(images, **kwargs)
143
+
144
+ def _preprocess(
145
+ self,
146
+ images: list[np.ndarray],
147
+ do_resize: bool,
148
+ size: SizeDict,
149
+ resample: "PILImageResampling | None",
150
+ do_rescale: bool,
151
+ rescale_factor: float,
152
+ do_normalize: bool,
153
+ image_mean: float | list[float] | None,
154
+ image_std: float | list[float] | None,
155
+ patch_size: int,
156
+ temporal_patch_size: int,
157
+ merge_size: int,
158
+ return_tensors: str | TensorType | None,
159
+ **kwargs,
160
+ ) -> BatchFeature:
161
+ all_patches = []
162
+ all_grids = []
163
+
164
+ for image in images:
165
+ height, width = image.shape[-2:]
166
+ if do_resize:
167
+ resized_height, resized_width = smart_resize(
168
+ height,
169
+ width,
170
+ factor=patch_size * merge_size,
171
+ min_pixels=size.shortest_edge,
172
+ max_pixels=size.longest_edge,
173
+ )
174
+ image = self.resize(
175
+ image,
176
+ size=SizeDict(height=resized_height, width=resized_width),
177
+ resample=resample,
178
+ )
179
+ else:
180
+ resized_height, resized_width = height, width
181
+
182
+ if do_rescale:
183
+ image = self.rescale(image, rescale_factor)
184
+ if do_normalize:
185
+ image = self.normalize(image, image_mean, image_std)
186
+
187
+ patches = np.expand_dims(image, axis=0)
188
+ if patches.ndim == 4:
189
+ patches = np.expand_dims(patches, axis=1)
190
+ if patches.shape[1] % temporal_patch_size != 0:
191
+ repeats = np.repeat(
192
+ patches[:, -1:], temporal_patch_size - (patches.shape[1] % temporal_patch_size), axis=1
193
+ )
194
+ patches = np.concatenate([patches, repeats], axis=1)
195
+
196
+ batch_size = 1
197
+ grid_t = patches.shape[1] // temporal_patch_size
198
+ channel = patches.shape[2]
199
+ grid_h, grid_w = resized_height // patch_size, resized_width // patch_size
200
+
201
+ patches = patches.reshape(
202
+ batch_size,
203
+ grid_t,
204
+ temporal_patch_size,
205
+ channel,
206
+ grid_h,
207
+ patch_size,
208
+ grid_w,
209
+ patch_size,
210
+ )
211
+ patches = patches.transpose(0, 1, 4, 6, 3, 2, 5, 7)
212
+ flatten_patches = patches.reshape(batch_size, grid_t * grid_h * grid_w, channel, patch_size, patch_size)
213
+
214
+ all_patches.append(flatten_patches.squeeze(0))
215
+ all_grids.append([grid_t, grid_h, grid_w])
216
+
217
+ pixel_values = np.concatenate(all_patches, axis=0)
218
+ image_grid_thw = np.array(all_grids, dtype=np.int64)
219
+
220
+ return BatchFeature(
221
+ data={"pixel_values": pixel_values, "image_grid_thw": image_grid_thw}, tensor_type=return_tensors
222
+ )
223
+
224
+ def get_number_of_image_patches(self, height: int, width: int, images_kwargs=None):
225
+ """
226
+ A utility that returns number of image patches for a given image size.
227
+
228
+ Args:
229
+ height (`int`):
230
+ Height of the input image.
231
+ width (`int`):
232
+ Width of the input image.
233
+ images_kwargs (`dict`, *optional*)
234
+ Any kwargs to override defaults of the image processor.
235
+ Returns:
236
+ `int`: Number of image patches per image.
237
+ """
238
+ min_pixels = images_kwargs["min_pixels"] if "min_pixels" in images_kwargs else self.size["shortest_edge"]
239
+ max_pixels = images_kwargs["max_pixels"] if "max_pixels" in images_kwargs else self.size["longest_edge"]
240
+ patch_size = images_kwargs.get("patch_size", self.patch_size)
241
+ merge_size = images_kwargs.get("merge_size", self.merge_size)
242
+
243
+ factor = patch_size * merge_size
244
+ resized_height, resized_width = smart_resize(
245
+ height, width, factor, min_pixels=min_pixels, max_pixels=max_pixels
246
+ )
247
+ grid_h, grid_w = resized_height // patch_size, resized_width // patch_size
248
+ return grid_h * grid_w
249
+
250
+
251
+ __all__ = ["PaddleOCRVLImageProcessorPil"]
LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/transformers/models/paddleocr_vl/modular_paddleocr_vl.py ADDED
@@ -0,0 +1,1166 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2025 The PaddlePaddle Team and The HuggingFace Inc. team. All rights reserved.
2
+ #
3
+ # This code is based on EleutherAI's GPT-NeoX library and the GPT-NeoX
4
+ # and OPT implementations in this library. It has been modified from its
5
+ # original forms to accommodate minor architectural differences compared
6
+ # to GPT-NeoX and OPT used by the Meta AI team that trained the model.
7
+ #
8
+ # Licensed under the Apache License, Version 2.0 (the "License");
9
+ # you may not use this file except in compliance with the License.
10
+ # You may obtain a copy of the License at
11
+ #
12
+ # http://www.apache.org/licenses/LICENSE-2.0
13
+ #
14
+ # Unless required by applicable law or agreed to in writing, software
15
+ # distributed under the License is distributed on an "AS IS" BASIS,
16
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
+ # See the License for the specific language governing permissions and
18
+ # limitations under the License.
19
+
20
+ import math
21
+
22
+ import numpy as np
23
+ import torch
24
+ from huggingface_hub.dataclasses import strict
25
+ from torch import nn
26
+
27
+ from ... import initialization as init
28
+ from ...activations import GELUActivation
29
+ from ...cache_utils import Cache, DynamicCache
30
+ from ...image_processing_utils import BatchFeature
31
+ from ...image_transforms import group_images_by_shape, reorder_images
32
+ from ...image_utils import (
33
+ ImageInput,
34
+ PILImageResampling,
35
+ SizeDict,
36
+ )
37
+ from ...masking_utils import create_bidirectional_mask, create_causal_mask
38
+ from ...modeling_outputs import BaseModelOutput, BaseModelOutputWithPast, BaseModelOutputWithPooling
39
+ from ...modeling_utils import PreTrainedModel
40
+ from ...models.qwen2_vl.image_processing_pil_qwen2_vl import Qwen2VLImageProcessorPil
41
+ from ...models.qwen2_vl.image_processing_qwen2_vl import Qwen2VLImageProcessor, Qwen2VLImageProcessorKwargs
42
+ from ...processing_utils import (
43
+ ProcessingKwargs,
44
+ ProcessorMixin,
45
+ Unpack,
46
+ )
47
+ from ...tokenization_utils_base import PreTokenizedInput, TextInput
48
+ from ...utils import (
49
+ TensorType,
50
+ TransformersKwargs,
51
+ auto_docstring,
52
+ can_return_tuple,
53
+ logging,
54
+ torch_compilable_check,
55
+ torch_int,
56
+ )
57
+ from ...utils.deprecation import deprecate_kwarg
58
+ from ...utils.generic import accepts_precomputed_kwargs, merge_with_config_defaults
59
+ from ...utils.output_capturing import capture_outputs
60
+ from ...vision_utils import get_vision_cu_seqlens, get_vision_position_ids
61
+ from ..ernie4_5.configuration_ernie4_5 import Ernie4_5Config
62
+ from ..ernie4_5.modeling_ernie4_5 import (
63
+ Ernie4_5DecoderLayer,
64
+ Ernie4_5MLP,
65
+ Ernie4_5Model,
66
+ Ernie4_5RMSNorm,
67
+ )
68
+ from ..qwen2_5_omni.modeling_qwen2_5_omni import (
69
+ Qwen2_5OmniAttention,
70
+ )
71
+ from ..qwen2_vl.configuration_qwen2_vl import Qwen2VLConfig
72
+ from ..qwen2_vl.modeling_qwen2_vl import (
73
+ Qwen2VLCausalLMOutputWithPast,
74
+ Qwen2VLForConditionalGeneration,
75
+ Qwen2VLModel,
76
+ Qwen2VLModelOutputWithPast,
77
+ Qwen2VLRotaryEmbedding,
78
+ VisionRotaryEmbedding,
79
+ )
80
+ from ..siglip.configuration_siglip import SiglipVisionConfig
81
+ from ..siglip.modeling_siglip import (
82
+ SiglipMLP,
83
+ SiglipVisionEmbeddings,
84
+ )
85
+ from ..video_llama_3.modeling_video_llama_3 import (
86
+ VideoLlama3VisionAttention,
87
+ VideoLlama3VisionEncoder,
88
+ VideoLlama3VisionEncoderLayer,
89
+ )
90
+
91
+
92
+ logger = logging.get_logger(__name__)
93
+
94
+
95
+ def smart_resize(
96
+ height: int,
97
+ width: int,
98
+ factor: int = 28,
99
+ min_pixels: int = 384 * 384,
100
+ max_pixels: int = 1536 * 1536,
101
+ ):
102
+ if height < factor:
103
+ width = round((width * factor) / height)
104
+ height = factor
105
+
106
+ if width < factor:
107
+ height = round((height * factor) / width)
108
+ width = factor
109
+
110
+ if max(height, width) / min(height, width) > 200:
111
+ raise ValueError(
112
+ f"absolute aspect ratio must be smaller than 200, got {max(height, width) / min(height, width)}"
113
+ )
114
+ h_bar = round(height / factor) * factor
115
+ w_bar = round(width / factor) * factor
116
+ if h_bar * w_bar > max_pixels:
117
+ beta = math.sqrt((height * width) / max_pixels)
118
+ h_bar = max(factor, math.floor(height / beta / factor) * factor)
119
+ w_bar = max(factor, math.floor(width / beta / factor) * factor)
120
+ elif h_bar * w_bar < min_pixels:
121
+ beta = math.sqrt(min_pixels / (height * width))
122
+ h_bar = math.ceil(height * beta / factor) * factor
123
+ w_bar = math.ceil(width * beta / factor) * factor
124
+ return h_bar, w_bar
125
+
126
+
127
+ class PaddleOCRVLImageProcessorKwargs(Qwen2VLImageProcessorKwargs):
128
+ r"""
129
+ patch_size (`int`, *optional*, defaults to 14):
130
+ The spatial patch size of the vision encoder.
131
+ temporal_patch_size (`int`, *optional*, defaults to 1):
132
+ The temporal patch size of the vision encoder.
133
+ merge_size (`int`, *optional*, defaults to 2):
134
+ The merge size of the vision encoder to llm encoder.
135
+ """
136
+
137
+
138
+ class PaddleOCRVLImageProcessorPil(Qwen2VLImageProcessorPil):
139
+ size = {"shortest_edge": 384 * 384, "longest_edge": 1536 * 1536}
140
+ temporal_patch_size = 1
141
+
142
+ def _preprocess(
143
+ self,
144
+ images: list[np.ndarray],
145
+ do_resize: bool,
146
+ size: SizeDict,
147
+ resample: "PILImageResampling | None",
148
+ do_rescale: bool,
149
+ rescale_factor: float,
150
+ do_normalize: bool,
151
+ image_mean: float | list[float] | None,
152
+ image_std: float | list[float] | None,
153
+ patch_size: int,
154
+ temporal_patch_size: int,
155
+ merge_size: int,
156
+ return_tensors: str | TensorType | None,
157
+ **kwargs,
158
+ ) -> BatchFeature:
159
+ all_patches = []
160
+ all_grids = []
161
+
162
+ for image in images:
163
+ height, width = image.shape[-2:]
164
+ if do_resize:
165
+ resized_height, resized_width = smart_resize(
166
+ height,
167
+ width,
168
+ factor=patch_size * merge_size,
169
+ min_pixels=size.shortest_edge,
170
+ max_pixels=size.longest_edge,
171
+ )
172
+ image = self.resize(
173
+ image,
174
+ size=SizeDict(height=resized_height, width=resized_width),
175
+ resample=resample,
176
+ )
177
+ else:
178
+ resized_height, resized_width = height, width
179
+
180
+ if do_rescale:
181
+ image = self.rescale(image, rescale_factor)
182
+ if do_normalize:
183
+ image = self.normalize(image, image_mean, image_std)
184
+
185
+ patches = np.expand_dims(image, axis=0)
186
+ if patches.ndim == 4:
187
+ patches = np.expand_dims(patches, axis=1)
188
+ if patches.shape[1] % temporal_patch_size != 0:
189
+ repeats = np.repeat(
190
+ patches[:, -1:], temporal_patch_size - (patches.shape[1] % temporal_patch_size), axis=1
191
+ )
192
+ patches = np.concatenate([patches, repeats], axis=1)
193
+
194
+ batch_size = 1
195
+ grid_t = patches.shape[1] // temporal_patch_size
196
+ channel = patches.shape[2]
197
+ grid_h, grid_w = resized_height // patch_size, resized_width // patch_size
198
+
199
+ patches = patches.reshape(
200
+ batch_size,
201
+ grid_t,
202
+ temporal_patch_size,
203
+ channel,
204
+ grid_h,
205
+ patch_size,
206
+ grid_w,
207
+ patch_size,
208
+ )
209
+ patches = patches.transpose(0, 1, 4, 6, 3, 2, 5, 7)
210
+ flatten_patches = patches.reshape(batch_size, grid_t * grid_h * grid_w, channel, patch_size, patch_size)
211
+
212
+ all_patches.append(flatten_patches.squeeze(0))
213
+ all_grids.append([grid_t, grid_h, grid_w])
214
+
215
+ pixel_values = np.concatenate(all_patches, axis=0)
216
+ image_grid_thw = np.array(all_grids, dtype=np.int64)
217
+
218
+ return BatchFeature(
219
+ data={"pixel_values": pixel_values, "image_grid_thw": image_grid_thw}, tensor_type=return_tensors
220
+ )
221
+
222
+ def get_number_of_image_patches(self, height: int, width: int, images_kwargs=None):
223
+ """
224
+ A utility that returns number of image patches for a given image size.
225
+
226
+ Args:
227
+ height (`int`):
228
+ Height of the input image.
229
+ width (`int`):
230
+ Width of the input image.
231
+ images_kwargs (`dict`, *optional*)
232
+ Any kwargs to override defaults of the image processor.
233
+ Returns:
234
+ `int`: Number of image patches per image.
235
+ """
236
+ min_pixels = images_kwargs["min_pixels"] if "min_pixels" in images_kwargs else self.size["shortest_edge"]
237
+ max_pixels = images_kwargs["max_pixels"] if "max_pixels" in images_kwargs else self.size["longest_edge"]
238
+ patch_size = images_kwargs.get("patch_size", self.patch_size)
239
+ merge_size = images_kwargs.get("merge_size", self.merge_size)
240
+
241
+ factor = patch_size * merge_size
242
+ resized_height, resized_width = smart_resize(
243
+ height, width, factor, min_pixels=min_pixels, max_pixels=max_pixels
244
+ )
245
+ grid_h, grid_w = resized_height // patch_size, resized_width // patch_size
246
+ return grid_h * grid_w
247
+
248
+
249
+ class PaddleOCRVLImageProcessor(Qwen2VLImageProcessor):
250
+ size = {"shortest_edge": 384 * 384, "longest_edge": 1536 * 1536}
251
+ temporal_patch_size = 1
252
+
253
+ def _preprocess(
254
+ self,
255
+ images: list["torch.Tensor"],
256
+ do_resize: bool,
257
+ size: SizeDict,
258
+ resample: "PILImageResampling | int | None",
259
+ do_rescale: bool,
260
+ rescale_factor: float,
261
+ do_normalize: bool,
262
+ image_mean: float | list[float] | None,
263
+ image_std: float | list[float] | None,
264
+ patch_size: int,
265
+ temporal_patch_size: int,
266
+ merge_size: int,
267
+ disable_grouping: bool | None,
268
+ return_tensors: str | TensorType | None,
269
+ **kwargs,
270
+ ) -> BatchFeature:
271
+ grouped_images, grouped_images_index = group_images_by_shape(images, disable_grouping=disable_grouping)
272
+ resized_images_grouped = {}
273
+ for shape, stacked_images in grouped_images.items():
274
+ height, width = stacked_images.shape[-2:]
275
+ if do_resize:
276
+ resized_height, resized_width = smart_resize(
277
+ height,
278
+ width,
279
+ factor=patch_size * merge_size,
280
+ min_pixels=size.shortest_edge,
281
+ max_pixels=size.longest_edge,
282
+ )
283
+ stacked_images = self.resize(
284
+ image=stacked_images,
285
+ size=SizeDict(height=resized_height, width=resized_width),
286
+ resample=resample,
287
+ )
288
+ resized_images_grouped[shape] = stacked_images
289
+ resized_images = reorder_images(resized_images_grouped, grouped_images_index)
290
+
291
+ grouped_images, grouped_images_index = group_images_by_shape(resized_images, disable_grouping=disable_grouping)
292
+ processed_images_grouped = {}
293
+ processed_grids = {}
294
+ for shape, stacked_images in grouped_images.items():
295
+ resized_height, resized_width = stacked_images.shape[-2:]
296
+ patches = self.rescale_and_normalize(
297
+ stacked_images, do_rescale, rescale_factor, do_normalize, image_mean, image_std
298
+ )
299
+ if patches.ndim == 4:
300
+ patches = patches.unsqueeze(1)
301
+ if patches.shape[1] % temporal_patch_size != 0:
302
+ repeats = patches[:, -1:].repeat(1, temporal_patch_size - 1, 1, 1, 1)
303
+ patches = torch.cat([patches, repeats], dim=1)
304
+
305
+ batch_size, grid_t, channel = patches.shape[:3]
306
+ grid_t = grid_t // temporal_patch_size
307
+ grid_h, grid_w = resized_height // patch_size, resized_width // patch_size
308
+
309
+ patches = patches.view(
310
+ batch_size,
311
+ grid_t,
312
+ temporal_patch_size,
313
+ channel,
314
+ grid_h,
315
+ patch_size,
316
+ grid_w,
317
+ patch_size,
318
+ )
319
+ patches = patches.permute(0, 1, 4, 6, 3, 2, 5, 7)
320
+ flatten_patches = patches.reshape(batch_size, grid_t * grid_h * grid_w, channel, patch_size, patch_size)
321
+
322
+ processed_images_grouped[shape] = flatten_patches
323
+ processed_grids[shape] = [[grid_t, grid_h, grid_w]] * batch_size
324
+
325
+ processed_images = reorder_images(processed_images_grouped, grouped_images_index)
326
+ processed_grids = reorder_images(processed_grids, grouped_images_index)
327
+ pixel_values = torch.cat(processed_images, dim=0)
328
+ image_grid_thw = torch.tensor(processed_grids)
329
+
330
+ return BatchFeature(
331
+ data={"pixel_values": pixel_values, "image_grid_thw": image_grid_thw}, tensor_type=return_tensors
332
+ )
333
+
334
+ def get_number_of_image_patches(self, height: int, width: int, images_kwargs=None):
335
+ """
336
+ A utility that returns number of image patches for a given image size.
337
+
338
+ Args:
339
+ height (`int`):
340
+ Height of the input image.
341
+ width (`int`):
342
+ Width of the input image.
343
+ images_kwargs (`dict`, *optional*)
344
+ Any kwargs to override defaults of the image processor.
345
+ Returns:
346
+ `int`: Number of image patches per image.
347
+ """
348
+ min_pixels = images_kwargs["min_pixels"] if "min_pixels" in images_kwargs else self.size["shortest_edge"]
349
+ max_pixels = images_kwargs["max_pixels"] if "max_pixels" in images_kwargs else self.size["longest_edge"]
350
+ patch_size = images_kwargs.get("patch_size", self.patch_size)
351
+ merge_size = images_kwargs.get("merge_size", self.merge_size)
352
+
353
+ factor = patch_size * merge_size
354
+ resized_height, resized_width = smart_resize(
355
+ height, width, factor, min_pixels=min_pixels, max_pixels=max_pixels
356
+ )
357
+ grid_h, grid_w = resized_height // patch_size, resized_width // patch_size
358
+ return grid_h * grid_w
359
+
360
+
361
+ class PaddleOCRVLProcessorKwargs(ProcessingKwargs, total=False):
362
+ _defaults = {
363
+ "text_kwargs": {
364
+ "padding": False,
365
+ "return_mm_token_type_ids": True,
366
+ },
367
+ }
368
+
369
+
370
+ class PaddleOCRVLProcessor(ProcessorMixin):
371
+ r"""
372
+ [`PaddleOCRVLProcessor`] offers all the functionalities of [`PaddleOCRVLImageProcessor`] and [`LLamaTokenizerFast`]. See the
373
+ [`~PaddleOCRVLProcessor.__call__`] and [`~PaddleOCRVLProcessor.decode`] for more information.
374
+ Args:
375
+ image_processor ([`PaddleOCRVLImageProcessor`], *optional*):
376
+ The image processor is a required input.
377
+ tokenizer ([`LLamaTokenizerFast`], *optional*):
378
+ The tokenizer is a required input.
379
+ chat_template (`str`, *optional*): A Jinja template which will be used to convert lists of messages
380
+ in a chat into a tokenizable string.
381
+ """
382
+
383
+ image_processor_class = "AutoImageProcessor"
384
+ tokenizer_class = "AutoTokenizer"
385
+
386
+ def __init__(self, image_processor=None, tokenizer=None, chat_template=None, **kwargs):
387
+ self.image_token = tokenizer.image_token
388
+ self.image_token_id = tokenizer.image_token_id
389
+ super().__init__(image_processor, tokenizer, chat_template=chat_template)
390
+
391
+ def __call__(
392
+ self,
393
+ images: ImageInput = None,
394
+ text: TextInput | PreTokenizedInput | list[TextInput] | list[PreTokenizedInput] = None,
395
+ **kwargs: Unpack[PaddleOCRVLProcessorKwargs],
396
+ ) -> BatchFeature:
397
+ """
398
+ Args:
399
+ images (`PIL.Image.Image`, `np.ndarray`, `torch.Tensor`, `List[PIL.Image.Image]`, `List[np.ndarray]`, `List[torch.Tensor]`):
400
+ The image or batch of images to be prepared. Each image can be a PIL image, NumPy array or PyTorch
401
+ tensor. Both channels-first and channels-last formats are supported.
402
+ text (`str`, `List[str]`, `List[List[str]]`):
403
+ The sequence or batch of sequences to be encoded. Each sequence can be a string or a list of strings
404
+ (pretokenized string). If the sequences are provided as list of strings (pretokenized), you must set
405
+ `is_split_into_words=True` (to lift the ambiguity with a batch of sequences).
406
+ return_tensors (`str` or [`~utils.TensorType`], *optional*):
407
+ If set, will return tensors of a particular framework. Acceptable values are:
408
+ - `'tf'`: Return TensorFlow `tf.constant` objects.
409
+ - `'pt'`: Return PyTorch `torch.Tensor` objects.
410
+ - `'np'`: Return NumPy `np.ndarray` objects.
411
+ - `'jax'`: Return JAX `jnp.ndarray` objects.
412
+
413
+ Returns:
414
+ [`BatchFeature`]: A [`BatchFeature`] with the following fields:
415
+
416
+ - **input_ids** -- List of token ids to be fed to a model. Returned when `text` is not `None`.
417
+ - **attention_mask** -- List of indices specifying which tokens should be attended to by the model (when
418
+ `return_attention_mask=True` or if *"attention_mask"* is in `self.model_input_names` and if `text` is not
419
+ `None`).
420
+ - **pixel_values** -- Pixel values to be fed to a model. Returned when `images` is not `None`.
421
+ - **image_grid_thw** -- List of image 3D grid in LLM. Returned when `images` is not `None`.
422
+ """
423
+ output_kwargs = self._merge_kwargs(
424
+ PaddleOCRVLProcessorKwargs,
425
+ tokenizer_init_kwargs=self.tokenizer.init_kwargs,
426
+ **kwargs,
427
+ )
428
+
429
+ if images is not None:
430
+ image_inputs = self.image_processor(images=images, **output_kwargs["images_kwargs"])
431
+ image_grid_thw = image_inputs["image_grid_thw"]
432
+
433
+ else:
434
+ image_inputs = {}
435
+ image_grid_thw = None
436
+
437
+ if not isinstance(text, list):
438
+ text = [text]
439
+
440
+ text = text.copy()
441
+
442
+ if image_grid_thw is not None:
443
+ index = 0
444
+ for i in range(len(text)):
445
+ while self.image_token in text[i]:
446
+ text[i] = text[i].replace(
447
+ self.image_token,
448
+ "<|placeholder|>"
449
+ * (
450
+ image_grid_thw[index].prod()
451
+ // self.image_processor.merge_size
452
+ // self.image_processor.merge_size
453
+ ),
454
+ 1,
455
+ )
456
+ index += 1
457
+ text[i] = text[i].replace("<|placeholder|>", self.image_token)
458
+
459
+ return_tensors = output_kwargs["text_kwargs"].pop("return_tensors", None)
460
+ return_mm_token_type_ids = output_kwargs["text_kwargs"].pop("return_mm_token_type_ids", False)
461
+ text_inputs = self.tokenizer(text, **output_kwargs["text_kwargs"], return_tensors=None)
462
+
463
+ if return_mm_token_type_ids:
464
+ text_inputs["mm_token_type_ids"] = self.create_mm_token_type_ids(text_inputs["input_ids"])
465
+ return BatchFeature(data={**text_inputs, **image_inputs}, tensor_type=return_tensors)
466
+
467
+
468
+ @auto_docstring(checkpoint="PaddlePaddle/PaddleOCR-VL")
469
+ @strict
470
+ class PaddleOCRVisionConfig(SiglipVisionConfig):
471
+ r"""
472
+ Example:
473
+
474
+ ```python
475
+ >>> from transformers import PaddleOCRVisionConfig, PaddleOCRVisionModel
476
+
477
+ >>> # Initializing a PaddleOCRVisionConfig with PaddlePaddle/PaddleOCR-VL style configuration
478
+ >>> configuration = PaddleOCRVisionConfig()
479
+
480
+ >>> # Initializing a PaddleOCRVisionModel (with random weights) from the PaddlePaddle/PaddleOCR-VL style configuration
481
+ >>> model = PaddleOCRVisionModel(configuration)
482
+
483
+ >>> # Accessing the model configuration
484
+ >>> configuration = model.config
485
+ ```
486
+ """
487
+
488
+ model_type = "paddleocr_vl_vision"
489
+ base_config_key = "vision_config"
490
+
491
+ hidden_size: int = 1152
492
+ intermediate_size: int = 4304
493
+ num_hidden_layers: int = 27
494
+ num_attention_heads: int = 16
495
+ image_size: int = 384
496
+ patch_size: int = 14
497
+ spatial_merge_size: int = 2
498
+
499
+
500
+ @auto_docstring(checkpoint="PaddlePaddle/PaddleOCR-VL")
501
+ @strict
502
+ class PaddleOCRTextConfig(Ernie4_5Config):
503
+ model_type = "paddleocr_vl_text"
504
+
505
+
506
+ @auto_docstring(checkpoint="PaddlePaddle/PaddleOCR-VL")
507
+ @strict
508
+ class PaddleOCRVLConfig(Qwen2VLConfig):
509
+ r"""
510
+ Example:
511
+
512
+ ```python
513
+ >>> from transformers import PaddleOCRVLForConditionalGeneration, PaddleOCRVLConfig
514
+
515
+ >>> # Initializing a PaddleOCRVL style configuration
516
+ >>> configuration = PaddleOCRVLConfig()
517
+
518
+ >>> # Initializing a model from the PaddleOCRVL style configuration
519
+ >>> model = PaddleOCRVLForConditionalGeneration(configuration)
520
+
521
+ >>> # Accessing the model configuration
522
+ >>> configuration = model.config
523
+ ```"""
524
+
525
+ sub_configs = {"vision_config": PaddleOCRVisionConfig, "text_config": PaddleOCRTextConfig}
526
+
527
+ image_token_id: int = 100295
528
+ video_token_id: int = 100296
529
+ vision_start_token_id: int = 101305
530
+ vision_end_token_id: int = 101306
531
+ tie_word_embeddings: bool = True
532
+
533
+
534
+ class PaddleOCRProjector(nn.Module):
535
+ def __init__(self, config: PaddleOCRVLConfig):
536
+ super().__init__()
537
+ self.merge_kernel_size = (config.vision_config.spatial_merge_size, config.vision_config.spatial_merge_size)
538
+
539
+ hidden_size = config.vision_config.hidden_size * self.merge_kernel_size[0] * self.merge_kernel_size[1]
540
+
541
+ self.pre_norm = torch.nn.LayerNorm(config.vision_config.hidden_size, eps=1e-05)
542
+ self.linear_1 = nn.Linear(hidden_size, hidden_size, bias=True)
543
+ self.act = GELUActivation()
544
+ self.linear_2 = nn.Linear(hidden_size, config.text_config.hidden_size, bias=True)
545
+
546
+ def forward(self, image_features: torch.Tensor, image_grid_thw: torch.Tensor) -> torch.Tensor:
547
+ image_features_chunks = image_features.split(image_grid_thw.prod(dim=1).tolist(), dim=0)
548
+ m1, m2 = self.merge_kernel_size
549
+
550
+ processed_features = []
551
+ for image_feature, image_grid in zip(image_features_chunks, image_grid_thw):
552
+ image_feature = self.pre_norm(image_feature)
553
+ t, h, w = image_grid
554
+ d = image_feature.shape[-1]
555
+ h_block = h // m1
556
+ w_block = w // m2
557
+
558
+ image_feature = image_feature.reshape(t, h_block, m1, w_block, m2, d)
559
+ image_feature = image_feature.transpose(2, 3)
560
+ image_feature = image_feature.reshape(t * h_block * w_block, m1 * m2 * d)
561
+
562
+ hidden_states = self.linear_1(image_feature)
563
+ hidden_states = self.act(hidden_states)
564
+ hidden_states = self.linear_2(hidden_states)
565
+ processed_features.append(hidden_states)
566
+
567
+ return torch.cat(processed_features, dim=0)
568
+
569
+
570
+ class PaddleOCRVisionRotaryEmbedding(VisionRotaryEmbedding):
571
+ pass
572
+
573
+
574
+ class PaddleOCRRotaryEmbedding(Qwen2VLRotaryEmbedding):
575
+ pass
576
+
577
+
578
+ class PaddleOCRMLP(Ernie4_5MLP):
579
+ def __init__(self, config: PaddleOCRTextConfig):
580
+ super().__init__()
581
+
582
+
583
+ class PaddleOCRAttention(Qwen2_5OmniAttention):
584
+ def __init__(self, config: PaddleOCRVLConfig, layer_idx: int | None = None):
585
+ super().__init__()
586
+
587
+ self.attention_dropout = 0.0
588
+ self.q_proj = nn.Linear(self.hidden_size, self.num_heads * self.head_dim, bias=config.use_bias)
589
+ self.k_proj = nn.Linear(self.hidden_size, self.num_key_value_heads * self.head_dim, bias=config.use_bias)
590
+ self.v_proj = nn.Linear(self.hidden_size, self.num_key_value_heads * self.head_dim, bias=config.use_bias)
591
+ self.o_proj = nn.Linear(self.num_heads * self.head_dim, self.hidden_size, bias=config.use_bias)
592
+
593
+
594
+ class PaddleOCRRMSNorm(Ernie4_5RMSNorm):
595
+ pass
596
+
597
+
598
+ class PaddleOCRDecoderLayer(Ernie4_5DecoderLayer):
599
+ def __init__(self, config: PaddleOCRTextConfig, layer_idx: int):
600
+ super().__init__()
601
+
602
+
603
+ @auto_docstring
604
+ class PaddleOCRVLPreTrainedModel(PreTrainedModel):
605
+ config: PaddleOCRVLConfig
606
+ base_model_prefix = "model"
607
+ supports_gradient_checkpointing = True
608
+ _no_split_modules = ["PaddleOCRDecoderLayer"]
609
+ _skip_keys_device_placement = ["past_key_values"]
610
+ _supports_flash_attn = True
611
+ _supports_sdpa = True
612
+ _supports_flex_attn = True
613
+
614
+ _can_compile_fullgraph = True
615
+ _supports_attention_backend = True
616
+
617
+ _can_record_outputs = {
618
+ "hidden_states": PaddleOCRDecoderLayer,
619
+ "attentions": PaddleOCRAttention,
620
+ }
621
+
622
+ def _init_weights(self, module):
623
+ super()._init_weights(module)
624
+ if isinstance(module, PaddleOCRVisionEmbeddings):
625
+ init.copy_(module.position_ids, torch.arange(module.position_ids.shape[-1]).expand((1, -1)))
626
+ elif isinstance(module, PaddleOCRVisionRotaryEmbedding):
627
+ inv_freq = 1.0 / (module.theta ** (torch.arange(0, module.dim, 2, dtype=torch.float) / module.dim))
628
+ init.copy_(module.inv_freq, inv_freq)
629
+
630
+
631
+ class PaddleOCRTextModel(PaddleOCRVLPreTrainedModel, Ernie4_5Model):
632
+ def __init__(self, config: PaddleOCRTextConfig):
633
+ super().__init__(config)
634
+
635
+ @merge_with_config_defaults
636
+ @capture_outputs
637
+ @auto_docstring
638
+ def forward(
639
+ self,
640
+ input_ids: torch.LongTensor | None = None,
641
+ attention_mask: torch.Tensor | None = None,
642
+ position_ids: torch.LongTensor | None = None,
643
+ past_key_values: Cache | None = None,
644
+ inputs_embeds: torch.FloatTensor | None = None,
645
+ use_cache: bool | None = None,
646
+ **kwargs: Unpack[TransformersKwargs],
647
+ ) -> BaseModelOutputWithPast:
648
+ if (input_ids is None) ^ (inputs_embeds is not None):
649
+ raise ValueError("You must specify exactly one of input_ids or inputs_embeds")
650
+
651
+ if inputs_embeds is None:
652
+ inputs_embeds: torch.Tensor = self.embed_tokens(input_ids)
653
+
654
+ if use_cache and past_key_values is None:
655
+ past_key_values = DynamicCache(config=self.config)
656
+
657
+ if position_ids is None:
658
+ past_seen_tokens = past_key_values.get_seq_length() if past_key_values is not None else 0
659
+ position_ids = torch.arange(inputs_embeds.shape[1], device=inputs_embeds.device) + past_seen_tokens
660
+ position_ids = position_ids.view(1, 1, -1).expand(3, inputs_embeds.shape[0], -1)
661
+ elif position_ids.ndim == 2:
662
+ position_ids = position_ids[None, ...].expand(3, position_ids.shape[0], -1)
663
+
664
+ if position_ids.ndim == 3 and position_ids.shape[0] == 4:
665
+ text_position_ids = position_ids[0]
666
+ position_ids = position_ids[1:]
667
+ else:
668
+ text_position_ids = None
669
+
670
+ causal_mask = create_causal_mask(
671
+ config=self.config,
672
+ inputs_embeds=inputs_embeds,
673
+ attention_mask=attention_mask,
674
+ past_key_values=past_key_values,
675
+ position_ids=text_position_ids,
676
+ )
677
+
678
+ hidden_states = inputs_embeds
679
+ position_embeddings = self.rotary_emb(hidden_states, position_ids=position_ids)
680
+
681
+ for decoder_layer in self.layers[: self.config.num_hidden_layers]:
682
+ hidden_states = decoder_layer(
683
+ hidden_states,
684
+ attention_mask=causal_mask,
685
+ position_embeddings=position_embeddings,
686
+ position_ids=text_position_ids,
687
+ past_key_values=past_key_values,
688
+ use_cache=use_cache,
689
+ **kwargs,
690
+ )
691
+
692
+ hidden_states = self.norm(hidden_states)
693
+ return BaseModelOutputWithPast(
694
+ last_hidden_state=hidden_states,
695
+ past_key_values=past_key_values,
696
+ )
697
+
698
+
699
+ class PaddleOCRVisionEmbeddings(SiglipVisionEmbeddings):
700
+ def __init__(self, config: PaddleOCRVisionConfig):
701
+ super().__init__()
702
+
703
+ def interpolate_pos_encoding(self, embeddings: torch.Tensor, height: int, width: int) -> torch.Tensor:
704
+ num_positions = self.position_embedding.weight.shape[0]
705
+
706
+ patch_pos_embed = self.position_embedding.weight.unsqueeze(0)
707
+
708
+ dim = embeddings.shape[-1]
709
+
710
+ sqrt_num_positions = torch_int(num_positions**0.5)
711
+ patch_pos_embed = patch_pos_embed.reshape(1, sqrt_num_positions, sqrt_num_positions, dim)
712
+ patch_pos_embed = patch_pos_embed.permute(0, 3, 1, 2)
713
+
714
+ patch_pos_embed = nn.functional.interpolate(
715
+ patch_pos_embed,
716
+ size=(height, width),
717
+ mode="bilinear",
718
+ align_corners=False,
719
+ )
720
+
721
+ patch_pos_embed = patch_pos_embed.permute(0, 2, 3, 1).view(1, -1, dim)
722
+ return patch_pos_embed
723
+
724
+ @deprecate_kwarg("image_grid_thw", new_name="grid_thw", version="5.11.0")
725
+ def forward(
726
+ self,
727
+ pixel_values: torch.FloatTensor,
728
+ grid_thw: torch.LongTensor | None = None,
729
+ ) -> torch.Tensor:
730
+ """
731
+ Args:
732
+ pixel_values (`torch.FloatTensor` of shape `(batch_size, sequence_length, image_channels, patch_size, patch_size)`):
733
+ The tensors corresponding to the input images.
734
+ grid_thw (`torch.LongTensor` of shape `(num_images, 3)`, *optional*):
735
+ The temporal, height and width of feature shape of each image in LLM.
736
+ """
737
+ batch_size, squence_len, channel, height, width = pixel_values.shape
738
+ target_dtype = self.patch_embedding.weight.dtype
739
+ pixel_values = pixel_values.reshape(batch_size * squence_len, channel, height, width)
740
+ patch_embeds = self.patch_embedding(pixel_values.to(dtype=target_dtype)) # shape = [*, width, grid, grid]
741
+ embeddings = patch_embeds.flatten(-2).squeeze(-1)
742
+ embeddings = embeddings.reshape(batch_size, squence_len, -1)
743
+
744
+ start = 0
745
+ embeddings = embeddings.squeeze(0)
746
+ tmp_embeddings = []
747
+ for t, h, w in grid_thw:
748
+ end = start + t * h * w
749
+ image_embeddings = embeddings[start:end, :]
750
+ position_embedding = self.interpolate_pos_encoding(image_embeddings, h, w).squeeze(0).repeat(t, 1)
751
+ image_embeddings = image_embeddings + position_embedding
752
+ tmp_embeddings.append(image_embeddings)
753
+ start = end
754
+ embeddings = torch.concat(tmp_embeddings, dim=0)
755
+
756
+ return embeddings
757
+
758
+
759
+ class PaddleOCRVisionAttention(VideoLlama3VisionAttention):
760
+ def __init__(self, config: PaddleOCRVisionConfig):
761
+ super().__init__()
762
+
763
+
764
+ class PaddleOCRVisionMLP(SiglipMLP):
765
+ def __init__(self, config: PaddleOCRVisionConfig):
766
+ super().__init__()
767
+
768
+
769
+ class PaddleOCRVisionEncoderLayer(VideoLlama3VisionEncoderLayer):
770
+ def __init__(self, config: PaddleOCRVisionConfig):
771
+ super().__init__()
772
+
773
+
774
+ class PaddleOCRVisionEncoder(VideoLlama3VisionEncoder):
775
+ def __init__(self, config: PaddleOCRVisionConfig):
776
+ super().__init__()
777
+ embed_dim = config.hidden_size
778
+ num_heads = config.num_attention_heads
779
+ head_dim = embed_dim // num_heads
780
+ self.rotary_pos_emb = PaddleOCRVisionRotaryEmbedding(head_dim // 2)
781
+
782
+ @can_return_tuple
783
+ @auto_docstring
784
+ @deprecate_kwarg("image_grid_thw", new_name="grid_thw", version="5.11.0")
785
+ def forward(
786
+ self,
787
+ inputs_embeds: torch.FloatTensor,
788
+ attention_mask: torch.Tensor | None = None,
789
+ grid_thw: torch.LongTensor | None = None,
790
+ **kwargs: Unpack[TransformersKwargs],
791
+ ) -> BaseModelOutput:
792
+ r"""
793
+ inputs_embeds (`torch.FloatTensor` of shape `(sequence_length, hidden_size)`, *optional*):
794
+ Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation.
795
+ This is useful if you want more control over how to convert `input_ids` indices into associated vectors
796
+ than the model's internal embedding lookup matrix.
797
+ attention_mask (`torch.Tensor` of shape `(batch_size, sequence_length)`, *optional*):
798
+ The attention_mask used in forward function shape [batch_size X sequence_length] if not None.
799
+ grid_thw (`torch.LongTensor` of shape `(num_images, 3)`, *optional*):
800
+ The temporal, height and width of feature shape of each image in LLM.
801
+ """
802
+ # Use merge_size=1: PaddleOCR merges patches in the projector (after the encoder),
803
+ # unlike Qwen which merges inside the encoder, so rotary positions here are simple (row, col).
804
+ position_ids = get_vision_position_ids(grid_thw, 1, kwargs=kwargs)
805
+ cu_seqlens = get_vision_cu_seqlens(grid_thw, kwargs=kwargs)
806
+
807
+ hidden_states = inputs_embeds
808
+ attention_mask = create_bidirectional_mask(
809
+ config=self.config,
810
+ inputs_embeds=inputs_embeds,
811
+ attention_mask=attention_mask,
812
+ )
813
+ rotary_embeddings = self.rotary_pos_emb(position_ids)
814
+ rotary_embeddings = rotary_embeddings.repeat(1, 2)
815
+ position_embeddings = (rotary_embeddings.cos(), rotary_embeddings.sin())
816
+
817
+ for encoder_layer in self.layers:
818
+ hidden_states = encoder_layer(
819
+ hidden_states,
820
+ cu_seqlens=cu_seqlens,
821
+ position_embeddings=position_embeddings,
822
+ **kwargs,
823
+ )
824
+
825
+ return BaseModelOutput(
826
+ last_hidden_state=hidden_states,
827
+ )
828
+
829
+
830
+ class PaddleOCRVisionTransformer(PaddleOCRVLPreTrainedModel):
831
+ config: PaddleOCRVisionConfig
832
+ main_input_name = "pixel_values"
833
+ input_modalities = "image"
834
+ _can_record_outputs = {
835
+ "hidden_states": PaddleOCRVisionEncoderLayer,
836
+ "attentions": PaddleOCRVisionAttention,
837
+ }
838
+
839
+ def __init__(self, config: PaddleOCRVisionConfig):
840
+ super().__init__(config)
841
+ self.config = config
842
+ embed_dim = config.hidden_size
843
+
844
+ self.embeddings = PaddleOCRVisionEmbeddings(config)
845
+ self.encoder = PaddleOCRVisionEncoder(config)
846
+ self.post_layernorm = nn.LayerNorm(embed_dim, eps=config.layer_norm_eps)
847
+
848
+ self.post_init()
849
+
850
+ @merge_with_config_defaults
851
+ @capture_outputs(tie_last_hidden_states=False)
852
+ @deprecate_kwarg("image_grid_thw", new_name="grid_thw", version="5.11.0")
853
+ def forward(
854
+ self,
855
+ pixel_values: torch.FloatTensor,
856
+ attention_mask: torch.Tensor | None = None,
857
+ grid_thw: torch.LongTensor | None = None,
858
+ **kwargs: Unpack[TransformersKwargs],
859
+ ) -> BaseModelOutputWithPooling:
860
+ """
861
+ Args:
862
+ pixel_values (`torch.FloatTensor` of shape `(batch_size, sequence_length, patch_size * patch_size * image_channels)`):
863
+ The tensors corresponding to the input images.
864
+ attention_mask (`torch.Tensor`, *optional*):
865
+ The attention_mask used in forward function shape [batch_size X sequence_length] if not None.
866
+ grid_thw (`torch.LongTensor` of shape `(num_images, 3)`, *optional*):
867
+ The temporal, height and width of feature shape of each image in LLM.
868
+ """
869
+ hidden_states = self.embeddings(pixel_values, grid_thw=grid_thw)
870
+ encoder_outputs: BaseModelOutput = self.encoder(
871
+ inputs_embeds=hidden_states,
872
+ grid_thw=grid_thw,
873
+ attention_mask=attention_mask,
874
+ **kwargs,
875
+ )
876
+
877
+ last_hidden_state = encoder_outputs.last_hidden_state
878
+ last_hidden_state = self.post_layernorm(last_hidden_state)
879
+
880
+ return BaseModelOutputWithPooling(
881
+ last_hidden_state=last_hidden_state,
882
+ pooler_output=None,
883
+ )
884
+
885
+
886
+ class PaddleOCRVisionModel(PaddleOCRVLPreTrainedModel):
887
+ config: PaddleOCRVisionConfig
888
+ main_input_name = "pixel_values"
889
+ input_modalities = "image"
890
+
891
+ def __init__(self, config: PaddleOCRVisionConfig):
892
+ super().__init__(config)
893
+
894
+ self.vision_model = PaddleOCRVisionTransformer(config)
895
+
896
+ # Initialize weights and apply final processing
897
+ self.post_init()
898
+
899
+ @deprecate_kwarg("image_grid_thw", new_name="grid_thw", version="5.11.0")
900
+ def forward(
901
+ self,
902
+ pixel_values: torch.FloatTensor,
903
+ grid_thw: torch.LongTensor | None = None,
904
+ **kwargs: Unpack[TransformersKwargs],
905
+ ) -> tuple | BaseModelOutputWithPooling:
906
+ """
907
+ Args:
908
+ pixel_values (`torch.FloatTensor` of shape `(batch_size, sequence_length, image_channels, patch_size, patch_size)`):
909
+ The tensors corresponding to the input images.
910
+ grid_thw (`torch.LongTensor` of shape `(num_images, 3)`, *optional*):
911
+ The temporal, height and width of feature shape of each image in LLM.
912
+ """
913
+ return self.vision_model(pixel_values=pixel_values, grid_thw=grid_thw, **kwargs)
914
+
915
+
916
+ class PaddleOCRVLModelOutputWithPast(Qwen2VLModelOutputWithPast):
917
+ pass
918
+
919
+
920
+ class PaddleOCRVLCausalLMOutputWithPast(Qwen2VLCausalLMOutputWithPast):
921
+ pass
922
+
923
+
924
+ class PaddleOCRVLModel(Qwen2VLModel):
925
+ _keys_to_ignore_on_load_unexpected = ["packing_position_embedding", "vision_model.head"]
926
+
927
+ def __init__(self, config: PaddleOCRVLConfig):
928
+ super().__init__(config)
929
+ self.visual = PaddleOCRVisionModel._from_config(config.vision_config)
930
+ self.projector = PaddleOCRProjector(config)
931
+ self.language_model = PaddleOCRTextModel._from_config(config.text_config)
932
+ self.rope_deltas = None
933
+
934
+ self.post_init()
935
+
936
+ def get_video_features(self):
937
+ raise AttributeError("PaddleOCRVLModel does not support video.")
938
+
939
+ @accepts_precomputed_kwargs(modality="image")
940
+ @can_return_tuple
941
+ @auto_docstring
942
+ def get_image_features(
943
+ self,
944
+ pixel_values: torch.FloatTensor,
945
+ image_grid_thw: torch.LongTensor | None = None,
946
+ **kwargs: Unpack[TransformersKwargs],
947
+ ) -> tuple | BaseModelOutputWithPooling:
948
+ r"""
949
+ pixel_values (`torch.FloatTensor` of shape `(batch_size, num_channels, image_size, image_size)`):
950
+ The tensors corresponding to the input images.
951
+ image_grid_thw (`torch.LongTensor` of shape `(num_images, 3)`, *optional*):
952
+ The temporal, height and width of feature shape of each image in LLM.
953
+ """
954
+ pixel_values = pixel_values.type(self.visual.dtype).unsqueeze(0)
955
+ vision_outputs = self.visual(pixel_values=pixel_values, grid_thw=image_grid_thw, **kwargs)
956
+ image_embeds = vision_outputs.last_hidden_state
957
+ image_embeds = self.projector(image_embeds, image_grid_thw)
958
+ vision_outputs.pooler_output = image_embeds
959
+
960
+ return vision_outputs
961
+
962
+ def get_placeholder_mask(
963
+ self, input_ids: torch.LongTensor, inputs_embeds: torch.FloatTensor, image_features: torch.FloatTensor
964
+ ):
965
+ """
966
+ Obtains multimodal placeholder mask from `input_ids` or `inputs_embeds`, and checks that the placeholder token count is
967
+ equal to the length of multimodal features. If the lengths are different, an error is raised.
968
+ """
969
+ if input_ids is None:
970
+ special_image_mask = inputs_embeds == self.get_input_embeddings()(
971
+ torch.tensor(self.config.image_token_id, dtype=torch.long, device=inputs_embeds.device)
972
+ )
973
+ special_image_mask = special_image_mask.all(-1)
974
+ else:
975
+ special_image_mask = input_ids == self.config.image_token_id
976
+
977
+ n_image_tokens = special_image_mask.sum()
978
+ special_image_mask = special_image_mask.unsqueeze(-1).expand_as(inputs_embeds).to(inputs_embeds.device)
979
+ n_image_features = image_features.shape[0] * image_features.shape[1]
980
+ torch_compilable_check(
981
+ inputs_embeds[special_image_mask].numel() == image_features.numel(),
982
+ f"Image features and image tokens do not match: tokens: {n_image_tokens}, features {n_image_features}",
983
+ )
984
+ return special_image_mask
985
+
986
+ @can_return_tuple
987
+ def forward(
988
+ self,
989
+ input_ids: torch.LongTensor = None,
990
+ attention_mask: torch.Tensor | None = None,
991
+ position_ids: torch.LongTensor | None = None,
992
+ past_key_values: list[torch.FloatTensor] | None = None,
993
+ inputs_embeds: torch.FloatTensor | None = None,
994
+ use_cache: bool | None = None,
995
+ pixel_values: torch.Tensor | None = None,
996
+ image_grid_thw: torch.LongTensor | None = None,
997
+ mm_token_type_ids: torch.IntTensor | None = None,
998
+ rope_deltas: torch.LongTensor | None = None,
999
+ **kwargs,
1000
+ ) -> tuple | PaddleOCRVLModelOutputWithPast:
1001
+ r"""
1002
+ image_grid_thw (`torch.LongTensor` of shape `(num_images, 3)`, *optional*):
1003
+ The temporal, height and width of feature shape of each image in LLM.
1004
+ rope_deltas (`torch.LongTensor` of shape `(batch_size, )`, *optional*):
1005
+ The rope index difference between sequence length and multimodal rope.
1006
+ """
1007
+ if inputs_embeds is None:
1008
+ inputs_embeds = self.language_model.embed_tokens(input_ids)
1009
+
1010
+ if pixel_values is not None:
1011
+ image_embeds = self.get_image_features(
1012
+ pixel_values, image_grid_thw, return_dict=True, **kwargs
1013
+ ).pooler_output
1014
+ image_embeds = image_embeds.to(inputs_embeds.device, inputs_embeds.dtype)
1015
+ image_mask = self.get_placeholder_mask(input_ids, inputs_embeds=inputs_embeds, image_features=image_embeds)
1016
+ inputs_embeds = inputs_embeds.masked_scatter(image_mask, image_embeds)
1017
+
1018
+ if position_ids is None:
1019
+ position_ids = self.compute_3d_position_ids(
1020
+ input_ids=input_ids,
1021
+ image_grid_thw=image_grid_thw,
1022
+ inputs_embeds=inputs_embeds,
1023
+ attention_mask=attention_mask,
1024
+ past_key_values=past_key_values,
1025
+ mm_token_type_ids=mm_token_type_ids,
1026
+ )
1027
+
1028
+ outputs = self.language_model(
1029
+ input_ids=None,
1030
+ position_ids=position_ids,
1031
+ attention_mask=attention_mask,
1032
+ past_key_values=past_key_values,
1033
+ inputs_embeds=inputs_embeds,
1034
+ use_cache=use_cache,
1035
+ **kwargs,
1036
+ )
1037
+
1038
+ output = PaddleOCRVLModelOutputWithPast(
1039
+ last_hidden_state=outputs.last_hidden_state,
1040
+ past_key_values=outputs.past_key_values,
1041
+ hidden_states=outputs.hidden_states,
1042
+ attentions=outputs.attentions,
1043
+ rope_deltas=self.rope_deltas,
1044
+ )
1045
+
1046
+ return output
1047
+
1048
+
1049
+ class PaddleOCRVLForConditionalGeneration(Qwen2VLForConditionalGeneration):
1050
+ _keys_to_ignore_on_load_unexpected = ["packing_position_embedding", "vision_model.head"]
1051
+
1052
+ def get_video_features(self):
1053
+ raise AttributeError("PaddleOCRVLForConditionalGeneration does not support video.")
1054
+
1055
+ @can_return_tuple
1056
+ @auto_docstring
1057
+ def forward(
1058
+ self,
1059
+ input_ids: torch.LongTensor | None = None,
1060
+ attention_mask: torch.Tensor | None = None,
1061
+ position_ids: torch.LongTensor | None = None,
1062
+ past_key_values: Cache | None = None,
1063
+ inputs_embeds: torch.FloatTensor | None = None,
1064
+ labels: torch.LongTensor | None = None,
1065
+ use_cache: bool | None = None,
1066
+ pixel_values: torch.Tensor | None = None,
1067
+ image_grid_thw: torch.LongTensor | None = None,
1068
+ rope_deltas: torch.LongTensor | None = None,
1069
+ mm_token_type_ids: torch.IntTensor | None = None,
1070
+ logits_to_keep: int | torch.Tensor = 0,
1071
+ **kwargs: Unpack[TransformersKwargs],
1072
+ ) -> tuple | PaddleOCRVLCausalLMOutputWithPast:
1073
+ r"""
1074
+ labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):
1075
+ Labels for computing the masked language modeling loss. Indices should either be in `[0, ...,
1076
+ config.vocab_size]` or -100 (see `input_ids` docstring). Tokens with indices set to `-100` are ignored
1077
+ (masked), the loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]`.
1078
+ image_grid_thw (`torch.LongTensor` of shape `(num_images, 3)`, *optional*):
1079
+ The temporal, height and width of feature shape of each image in LLM.
1080
+ rope_deltas (`torch.LongTensor` of shape `(batch_size, )`, *optional*):
1081
+ The rope index difference between sequence length and multimodal rope.
1082
+
1083
+ Example:
1084
+
1085
+ ```python
1086
+ >>> from transformers import AutoProcessor, PaddleOCRVLForConditionalGeneration
1087
+
1088
+ >>> model = PaddleOCRVLForConditionalGeneration.from_pretrained("PaddlePaddle/PaddleOCR-VL", dtype="bfloat16")
1089
+ >>> processor = AutoProcessor.from_pretrained("PaddlePaddle/PaddleOCR-VL")
1090
+
1091
+ >>> messages = [
1092
+ {
1093
+ "role": "user",
1094
+ "content": [
1095
+ {
1096
+ "type": "image",
1097
+ "image": "https://paddle-model-ecology.bj.bcebos.com/paddlex/imgs/demo_image/ocr_demo.jpg",
1098
+ },
1099
+ {"type": "text", "text": "OCR:"},
1100
+ ],
1101
+ }
1102
+ ]
1103
+
1104
+ >>> inputs = processor.apply_chat_template(
1105
+ messages,
1106
+ tokenize=True,
1107
+ add_generation_prompt=True,
1108
+ return_dict=True,
1109
+ return_tensors="pt"
1110
+ ).to(model.device)
1111
+
1112
+ >>> # Generate
1113
+ >>> generated_ids = model.generate(**inputs, max_new_tokens=1024)
1114
+ >>> generated_ids_trimmed = [out_ids[len(in_ids) :] for in_ids, out_ids in zip(inputs.input_ids, generated_ids)]
1115
+ >>> output_text = processor.batch_decode(generated_ids_trimmed, skip_special_tokens=True, clean_up_tokenization_spaces=False)[0]
1116
+ >>> print(output_text)
1117
+ ```
1118
+ """
1119
+ outputs: PaddleOCRVLModelOutputWithPast = self.model(
1120
+ input_ids=input_ids,
1121
+ attention_mask=attention_mask,
1122
+ position_ids=position_ids,
1123
+ image_grid_thw=image_grid_thw,
1124
+ past_key_values=past_key_values,
1125
+ inputs_embeds=inputs_embeds,
1126
+ use_cache=use_cache,
1127
+ pixel_values=pixel_values,
1128
+ rope_deltas=rope_deltas,
1129
+ mm_token_type_ids=mm_token_type_ids,
1130
+ **kwargs,
1131
+ )
1132
+ hidden_states = outputs.last_hidden_state
1133
+
1134
+ slice_indices = slice(-logits_to_keep, None) if isinstance(logits_to_keep, int) else logits_to_keep
1135
+ logits = self.lm_head(hidden_states[:, slice_indices, :])
1136
+
1137
+ loss = None
1138
+ if labels is not None:
1139
+ loss = self.loss_function(
1140
+ logits=logits, labels=labels, vocab_size=self.config.text_config.vocab_size, **kwargs
1141
+ )
1142
+
1143
+ return PaddleOCRVLCausalLMOutputWithPast(
1144
+ loss=loss,
1145
+ logits=logits,
1146
+ past_key_values=outputs.past_key_values,
1147
+ hidden_states=outputs.hidden_states,
1148
+ attentions=outputs.attentions,
1149
+ rope_deltas=outputs.rope_deltas,
1150
+ )
1151
+
1152
+
1153
+ __all__ = [
1154
+ "PaddleOCRVLForConditionalGeneration",
1155
+ "PaddleOCRVLModel",
1156
+ "PaddleOCRVLPreTrainedModel",
1157
+ "PaddleOCRVisionTransformer",
1158
+ "PaddleOCRVLConfig",
1159
+ "PaddleOCRTextModel",
1160
+ "PaddleOCRVisionModel",
1161
+ "PaddleOCRVisionConfig",
1162
+ "PaddleOCRTextConfig",
1163
+ "PaddleOCRVLImageProcessor",
1164
+ "PaddleOCRVLImageProcessorPil",
1165
+ "PaddleOCRVLProcessor",
1166
+ ]
LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/transformers/models/phi/__init__.py ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2023 Microsoft 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_phi import *
22
+ from .modeling_phi import *
23
+ else:
24
+ import sys
25
+
26
+ _file = globals()["__file__"]
27
+ 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/phi/configuration_phi.py ADDED
@@ -0,0 +1,92 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2023 Microsoft 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
+
15
+ """Phi model configuration"""
16
+
17
+ from huggingface_hub.dataclasses import strict
18
+
19
+ from ...configuration_utils import PreTrainedConfig
20
+ from ...modeling_rope_utils import RopeParameters
21
+ from ...utils import auto_docstring
22
+
23
+
24
+ @auto_docstring(checkpoint="microsoft/phi-1")
25
+ @strict
26
+ class PhiConfig(PreTrainedConfig):
27
+ r"""
28
+ qk_layernorm (`bool`, *optional*, defaults to `False`):
29
+ Whether or not to normalize the Queries and Keys after projecting the hidden states.
30
+
31
+ Example:
32
+
33
+ ```python
34
+ >>> from transformers import PhiModel, PhiConfig
35
+
36
+ >>> # Initializing a Phi-1 style configuration
37
+ >>> configuration = PhiConfig.from_pretrained("microsoft/phi-1")
38
+
39
+ >>> # Initializing a model from the configuration
40
+ >>> model = PhiModel(configuration)
41
+
42
+ >>> # Accessing the model configuration
43
+ >>> configuration = model.config
44
+ ```"""
45
+
46
+ model_type = "phi"
47
+ keys_to_ignore_at_inference = ["past_key_values"]
48
+ base_model_tp_plan = {
49
+ "layers.*.self_attn.q_proj": "colwise",
50
+ "layers.*.self_attn.k_proj": "colwise",
51
+ "layers.*.self_attn.v_proj": "colwise",
52
+ "layers.*.self_attn.dense": "rowwise",
53
+ "layers.*.mlp.fc1": "colwise",
54
+ "layers.*.mlp.fc2": "rowwise",
55
+ }
56
+ base_model_pp_plan = {
57
+ "embed_tokens": (["input_ids"], ["inputs_embeds"]),
58
+ "embed_dropout": (["inputs_embeds"], ["inputs_embeds"]),
59
+ "layers": (["hidden_states", "attention_mask"], ["hidden_states"]),
60
+ "final_layernorm": (["hidden_states"], ["hidden_states"]),
61
+ }
62
+
63
+ vocab_size: int = 51200
64
+ hidden_size: int = 2048
65
+ intermediate_size: int = 8192
66
+ num_hidden_layers: int = 24
67
+ num_attention_heads: int = 32
68
+ num_key_value_heads: int | None = None
69
+ resid_pdrop: float | int = 0.0
70
+ embd_pdrop: float | int = 0.0
71
+ attention_dropout: float | int | None = 0.0
72
+ hidden_act: str = "gelu_new"
73
+ max_position_embeddings: int = 2048
74
+ initializer_range: float = 0.02
75
+ layer_norm_eps: float = 1e-5
76
+ use_cache: bool = True
77
+ tie_word_embeddings: bool = False
78
+ rope_parameters: RopeParameters | dict | None = None
79
+ qk_layernorm: bool = False
80
+ bos_token_id: int | None = 1
81
+ eos_token_id: int | list[int] | None = 2
82
+ pad_token_id: int | None = None
83
+
84
+ def __post_init__(self, **kwargs):
85
+ if self.num_key_value_heads is None:
86
+ self.num_key_value_heads = self.num_attention_heads
87
+
88
+ kwargs.setdefault("partial_rotary_factor", 0.5) # assign default for BC
89
+ super().__post_init__(**kwargs)
90
+
91
+
92
+ __all__ = ["PhiConfig"]
LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/transformers/models/phi/modeling_phi.py ADDED
@@ -0,0 +1,494 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨
2
+ # This file was automatically generated from src/transformers/models/phi/modular_phi.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_phi.py file directly. One of our CI enforces this.
6
+ # 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨
7
+ from collections.abc import Callable
8
+ from typing import Optional
9
+
10
+ import torch
11
+ import torch.nn as nn
12
+
13
+ from ...activations import ACT2FN
14
+ from ...cache_utils import Cache, DynamicCache
15
+ from ...generation import GenerationMixin
16
+ from ...integrations import use_kernel_func_from_hub, use_kernelized_func
17
+ from ...masking_utils import create_causal_mask
18
+ from ...modeling_layers import (
19
+ GenericForSequenceClassification,
20
+ GenericForTokenClassification,
21
+ GradientCheckpointingLayer,
22
+ )
23
+ from ...modeling_outputs import BaseModelOutputWithPast, CausalLMOutputWithPast
24
+ from ...modeling_rope_utils import ROPE_INIT_FUNCTIONS, dynamic_rope_update
25
+ from ...modeling_utils import ALL_ATTENTION_FUNCTIONS, PreTrainedModel
26
+ from ...processing_utils import Unpack
27
+ from ...utils import TransformersKwargs, auto_docstring
28
+ from ...utils.generic import can_return_tuple, maybe_autocast, merge_with_config_defaults
29
+ from ...utils.output_capturing import capture_outputs
30
+ from .configuration_phi import PhiConfig
31
+
32
+
33
+ class PhiRotaryEmbedding(nn.Module):
34
+ inv_freq: torch.Tensor # fix linting for `register_buffer`
35
+
36
+ def __init__(self, config: PhiConfig, device=None):
37
+ super().__init__()
38
+ self.max_seq_len_cached = config.max_position_embeddings
39
+ self.original_max_seq_len = config.max_position_embeddings
40
+
41
+ self.config = config
42
+
43
+ self.rope_type = self.config.rope_parameters["rope_type"]
44
+ rope_init_fn: Callable = self.compute_default_rope_parameters
45
+ if self.rope_type != "default":
46
+ rope_init_fn = ROPE_INIT_FUNCTIONS[self.rope_type]
47
+ inv_freq, self.attention_scaling = rope_init_fn(self.config, device)
48
+
49
+ self.register_buffer("inv_freq", inv_freq, persistent=False)
50
+ self.register_buffer("original_inv_freq", inv_freq.clone(), persistent=False)
51
+
52
+ @staticmethod
53
+ def compute_default_rope_parameters(
54
+ config: PhiConfig | None = None,
55
+ device: Optional["torch.device"] = None,
56
+ seq_len: int | None = None,
57
+ ) -> tuple["torch.Tensor", float]:
58
+ """
59
+ Computes the inverse frequencies according to the original RoPE implementation
60
+ Args:
61
+ config ([`~transformers.PreTrainedConfig`]):
62
+ The model configuration.
63
+ device (`torch.device`):
64
+ The device to use for initialization of the inverse frequencies.
65
+ seq_len (`int`, *optional*):
66
+ The current sequence length. Unused for this type of RoPE.
67
+ Returns:
68
+ Tuple of (`torch.Tensor`, `float`), containing the inverse frequencies for the RoPE embeddings and the
69
+ post-processing scaling factor applied to the computed cos/sin (unused in this type of RoPE).
70
+ """
71
+ base = config.rope_parameters["rope_theta"]
72
+ partial_rotary_factor = config.rope_parameters.get("partial_rotary_factor", 1.0)
73
+ head_dim = getattr(config, "head_dim", None) or config.hidden_size // config.num_attention_heads
74
+ dim = int(head_dim * partial_rotary_factor)
75
+
76
+ attention_factor = 1.0 # Unused in this type of RoPE
77
+
78
+ # Compute the inverse frequencies
79
+ inv_freq = 1.0 / (
80
+ base ** (torch.arange(0, dim, 2, dtype=torch.int64).to(device=device, dtype=torch.float) / dim)
81
+ )
82
+ return inv_freq, attention_factor
83
+
84
+ @torch.no_grad()
85
+ @dynamic_rope_update # power user: used with advanced RoPE types (e.g. dynamic rope)
86
+ def forward(self, x, position_ids):
87
+ inv_freq_expanded = self.inv_freq[None, :, None].float().expand(position_ids.shape[0], -1, 1).to(x.device)
88
+ position_ids_expanded = position_ids[:, None, :].float()
89
+
90
+ device_type = x.device.type if isinstance(x.device.type, str) and x.device.type != "mps" else "cpu"
91
+ with maybe_autocast(device_type=device_type, enabled=False): # Force float32
92
+ freqs = (inv_freq_expanded.float() @ position_ids_expanded.float()).transpose(1, 2)
93
+ emb = torch.cat((freqs, freqs), dim=-1)
94
+ cos = emb.cos() * self.attention_scaling
95
+ sin = emb.sin() * self.attention_scaling
96
+
97
+ return cos.to(dtype=x.dtype), sin.to(dtype=x.dtype)
98
+
99
+
100
+ def rotate_half(x):
101
+ """Rotates half the hidden dims of the input."""
102
+ x1 = x[..., : x.shape[-1] // 2]
103
+ x2 = x[..., x.shape[-1] // 2 :]
104
+ return torch.cat((-x2, x1), dim=-1)
105
+
106
+
107
+ @use_kernel_func_from_hub("rotary_pos_emb")
108
+ def apply_rotary_pos_emb(q, k, cos, sin, unsqueeze_dim=1):
109
+ """Applies Rotary Position Embedding to the query and key tensors.
110
+
111
+ Args:
112
+ q (`torch.Tensor`): The query tensor.
113
+ k (`torch.Tensor`): The key tensor.
114
+ cos (`torch.Tensor`): The cosine part of the rotary embedding.
115
+ sin (`torch.Tensor`): The sine part of the rotary embedding.
116
+ unsqueeze_dim (`int`, *optional*, defaults to 1):
117
+ The 'unsqueeze_dim' argument specifies the dimension along which to unsqueeze cos[position_ids] and
118
+ sin[position_ids] so that they can be properly broadcasted to the dimensions of q and k. For example, note
119
+ that cos[position_ids] and sin[position_ids] have the shape [batch_size, seq_len, head_dim]. Then, if q and
120
+ k have the shape [batch_size, heads, seq_len, head_dim], then setting unsqueeze_dim=1 makes
121
+ cos[position_ids] and sin[position_ids] broadcastable to the shapes of q and k. Similarly, if q and k have
122
+ the shape [batch_size, seq_len, heads, head_dim], then set unsqueeze_dim=2.
123
+ Returns:
124
+ `tuple(torch.Tensor)` comprising of the query and key tensors rotated using the Rotary Position Embedding.
125
+ """
126
+ cos = cos.unsqueeze(unsqueeze_dim)
127
+ sin = sin.unsqueeze(unsqueeze_dim)
128
+ q_embed = (q * cos) + (rotate_half(q) * sin)
129
+ k_embed = (k * cos) + (rotate_half(k) * sin)
130
+ return q_embed, k_embed
131
+
132
+
133
+ def repeat_kv(hidden_states: torch.Tensor, n_rep: int) -> torch.Tensor:
134
+ """
135
+ This is the equivalent of torch.repeat_interleave(x, dim=1, repeats=n_rep). The hidden states go from (batch,
136
+ num_key_value_heads, seqlen, head_dim) to (batch, num_attention_heads, seqlen, head_dim)
137
+ """
138
+ batch, num_key_value_heads, slen, head_dim = hidden_states.shape
139
+ if n_rep == 1:
140
+ return hidden_states
141
+ hidden_states = hidden_states[:, :, None, :, :].expand(batch, num_key_value_heads, n_rep, slen, head_dim)
142
+ return hidden_states.reshape(batch, num_key_value_heads * n_rep, slen, head_dim)
143
+
144
+
145
+ def eager_attention_forward(
146
+ module: nn.Module,
147
+ query: torch.Tensor,
148
+ key: torch.Tensor,
149
+ value: torch.Tensor,
150
+ attention_mask: torch.Tensor | None,
151
+ scaling: float,
152
+ dropout: float = 0.0,
153
+ **kwargs: Unpack[TransformersKwargs],
154
+ ):
155
+ key_states = repeat_kv(key, module.num_key_value_groups)
156
+ value_states = repeat_kv(value, module.num_key_value_groups)
157
+
158
+ attn_weights = torch.matmul(query, key_states.transpose(2, 3)) * scaling
159
+ if attention_mask is not None:
160
+ attn_weights = attn_weights + attention_mask
161
+
162
+ attn_weights = nn.functional.softmax(attn_weights, dim=-1, dtype=torch.float32).to(query.dtype)
163
+ attn_weights = nn.functional.dropout(attn_weights, p=dropout, training=module.training)
164
+ attn_output = torch.matmul(attn_weights, value_states)
165
+ attn_output = attn_output.transpose(1, 2).contiguous()
166
+
167
+ return attn_output, attn_weights
168
+
169
+
170
+ @use_kernelized_func(apply_rotary_pos_emb)
171
+ class PhiAttention(nn.Module):
172
+ """Multi-headed attention from 'Attention Is All You Need' paper"""
173
+
174
+ def __init__(self, config: PhiConfig, layer_idx: int):
175
+ super().__init__()
176
+ self.config = config
177
+ self.layer_idx = layer_idx
178
+ self.head_dim = getattr(config, "head_dim", config.hidden_size // config.num_attention_heads)
179
+ self.num_key_value_groups = config.num_attention_heads // config.num_key_value_heads
180
+ self.scaling = self.head_dim**-0.5
181
+ self.attention_dropout = config.attention_dropout
182
+ self.is_causal = True
183
+ self.q_proj = nn.Linear(config.hidden_size, config.num_attention_heads * self.head_dim, bias=True)
184
+ self.k_proj = nn.Linear(config.hidden_size, config.num_key_value_heads * self.head_dim, bias=True)
185
+ self.v_proj = nn.Linear(config.hidden_size, config.num_key_value_heads * self.head_dim, bias=True)
186
+ self.dense = nn.Linear(config.num_attention_heads * self.head_dim, config.hidden_size, bias=True)
187
+ self.rotary_ndims = int(self.head_dim * config.rope_parameters["partial_rotary_factor"])
188
+ self.qk_layernorm = config.qk_layernorm
189
+ if self.qk_layernorm:
190
+ self.q_layernorm = nn.LayerNorm(
191
+ config.hidden_size // config.num_attention_heads, eps=config.layer_norm_eps, elementwise_affine=True
192
+ )
193
+ self.k_layernorm = nn.LayerNorm(
194
+ config.hidden_size // config.num_attention_heads, eps=config.layer_norm_eps, elementwise_affine=True
195
+ )
196
+
197
+ def forward(
198
+ self,
199
+ hidden_states: torch.Tensor,
200
+ position_embeddings: tuple[torch.Tensor, torch.Tensor],
201
+ attention_mask: torch.Tensor | None,
202
+ past_key_values: Cache | None = None,
203
+ **kwargs,
204
+ ) -> tuple[torch.Tensor, torch.Tensor | None]:
205
+ input_shape = hidden_states.shape[:-1]
206
+ hidden_shape = (*input_shape, -1, self.head_dim)
207
+
208
+ query_states = self.q_proj(hidden_states).view(hidden_shape).transpose(1, 2)
209
+ key_states = self.k_proj(hidden_states).view(hidden_shape).transpose(1, 2)
210
+ value_states = self.v_proj(hidden_states).view(hidden_shape).transpose(1, 2)
211
+
212
+ if self.qk_layernorm:
213
+ query_states = self.q_layernorm(query_states)
214
+ key_states = self.k_layernorm(key_states)
215
+
216
+ cos, sin = position_embeddings
217
+ # Partial rotary embedding
218
+ query_rot, query_pass = (
219
+ query_states[..., : self.rotary_ndims],
220
+ query_states[..., self.rotary_ndims :],
221
+ )
222
+ key_rot, key_pass = (
223
+ key_states[..., : self.rotary_ndims],
224
+ key_states[..., self.rotary_ndims :],
225
+ )
226
+ # [batch_size, seq_length, num_heads, head_dim // config.partial_rotary_factor]
227
+ query_rot, key_rot = apply_rotary_pos_emb(query_rot, key_rot, cos, sin)
228
+
229
+ # [batch_size, seq_length, num_heads, head_dim]
230
+ query_states = torch.cat((query_rot, query_pass), dim=-1)
231
+ key_states = torch.cat((key_rot, key_pass), dim=-1)
232
+
233
+ if past_key_values is not None:
234
+ key_states, value_states = past_key_values.update(key_states, value_states, self.layer_idx)
235
+
236
+ attention_interface: Callable = ALL_ATTENTION_FUNCTIONS.get_interface(
237
+ self.config._attn_implementation, eager_attention_forward
238
+ )
239
+
240
+ attn_output, attn_weights = attention_interface(
241
+ self,
242
+ query_states,
243
+ key_states,
244
+ value_states,
245
+ attention_mask,
246
+ dropout=0.0 if not self.training else self.attention_dropout,
247
+ scaling=self.scaling,
248
+ **kwargs,
249
+ )
250
+
251
+ attn_output = attn_output.reshape(*input_shape, -1).contiguous()
252
+ attn_output = self.dense(attn_output)
253
+ return attn_output, attn_weights
254
+
255
+
256
+ class PhiMLP(nn.Module):
257
+ def __init__(self, config):
258
+ super().__init__()
259
+ self.config = config
260
+ self.activation_fn = ACT2FN[config.hidden_act]
261
+ self.fc1 = nn.Linear(config.hidden_size, config.intermediate_size)
262
+ self.fc2 = nn.Linear(config.intermediate_size, config.hidden_size)
263
+
264
+ def forward(self, hidden_states: torch.Tensor) -> torch.Tensor:
265
+ hidden_states = self.fc1(hidden_states)
266
+ hidden_states = self.activation_fn(hidden_states)
267
+ hidden_states = self.fc2(hidden_states)
268
+ return hidden_states
269
+
270
+
271
+ class PhiDecoderLayer(GradientCheckpointingLayer):
272
+ def __init__(self, config: PhiConfig, layer_idx: int):
273
+ super().__init__()
274
+ self.self_attn = PhiAttention(config, layer_idx=layer_idx)
275
+ self.mlp = PhiMLP(config)
276
+ self.input_layernorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps)
277
+ self.resid_dropout = nn.Dropout(config.resid_pdrop)
278
+
279
+ def forward(
280
+ self,
281
+ hidden_states: torch.Tensor,
282
+ attention_mask: torch.Tensor | None = None,
283
+ position_ids: torch.LongTensor | None = None,
284
+ past_key_values: Cache | None = None,
285
+ use_cache: bool | None = False,
286
+ position_embeddings: tuple[torch.Tensor, torch.Tensor] | None = None,
287
+ **kwargs: Unpack[TransformersKwargs],
288
+ ) -> torch.Tensor:
289
+ residual = hidden_states
290
+
291
+ hidden_states = self.input_layernorm(hidden_states)
292
+
293
+ attn_outputs, _ = self.self_attn(
294
+ hidden_states=hidden_states,
295
+ attention_mask=attention_mask,
296
+ position_ids=position_ids,
297
+ past_key_values=past_key_values,
298
+ use_cache=use_cache,
299
+ position_embeddings=position_embeddings,
300
+ **kwargs,
301
+ )
302
+ attn_outputs = self.resid_dropout(attn_outputs)
303
+
304
+ feed_forward_hidden_states = self.resid_dropout(self.mlp(hidden_states))
305
+ hidden_states = attn_outputs + feed_forward_hidden_states + residual
306
+
307
+ return hidden_states
308
+
309
+
310
+ @auto_docstring
311
+ class PhiPreTrainedModel(PreTrainedModel):
312
+ config: PhiConfig
313
+ base_model_prefix = "model"
314
+ supports_gradient_checkpointing = True
315
+ _no_split_modules = ["PhiDecoderLayer"]
316
+ _skip_keys_device_placement = ["past_key_values"]
317
+ _supports_flash_attn = True
318
+ _supports_sdpa = True
319
+ _supports_flex_attn = True
320
+
321
+ _can_compile_fullgraph = True
322
+ _supports_attention_backend = True
323
+ _can_record_outputs = {
324
+ "hidden_states": PhiDecoderLayer,
325
+ "attentions": PhiAttention,
326
+ }
327
+
328
+
329
+ @auto_docstring
330
+ class PhiModel(PhiPreTrainedModel):
331
+ def __init__(self, config: PhiConfig):
332
+ super().__init__(config)
333
+ self.padding_idx = config.pad_token_id
334
+ self.vocab_size = config.vocab_size
335
+
336
+ self.embed_tokens = nn.Embedding(config.vocab_size, config.hidden_size, self.padding_idx)
337
+ self.layers = nn.ModuleList(
338
+ [PhiDecoderLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)]
339
+ )
340
+ self.rotary_emb = PhiRotaryEmbedding(config=config)
341
+ self.gradient_checkpointing = False
342
+ self.embed_dropout = nn.Dropout(config.embd_pdrop)
343
+ self.final_layernorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps)
344
+
345
+ # Initialize weights and apply final processing
346
+ self.post_init()
347
+
348
+ @merge_with_config_defaults
349
+ @capture_outputs
350
+ @auto_docstring
351
+ def forward(
352
+ self,
353
+ input_ids: torch.LongTensor | None = None,
354
+ attention_mask: torch.Tensor | None = None,
355
+ position_ids: torch.LongTensor | None = None,
356
+ past_key_values: Cache | None = None,
357
+ inputs_embeds: torch.FloatTensor | None = None,
358
+ use_cache: bool | None = None,
359
+ **kwargs: Unpack[TransformersKwargs],
360
+ ) -> BaseModelOutputWithPast:
361
+ if (input_ids is None) ^ (inputs_embeds is not None):
362
+ raise ValueError("You must specify exactly one of input_ids or inputs_embeds")
363
+
364
+ if inputs_embeds is None:
365
+ inputs_embeds = self.embed_tokens(input_ids)
366
+
367
+ if use_cache and past_key_values is None:
368
+ past_key_values = DynamicCache(config=self.config)
369
+
370
+ if position_ids is None:
371
+ past_seen_tokens = past_key_values.get_seq_length() if past_key_values is not None else 0
372
+ position_ids = torch.arange(inputs_embeds.shape[1], device=inputs_embeds.device) + past_seen_tokens
373
+ position_ids = position_ids.unsqueeze(0)
374
+
375
+ causal_mask = create_causal_mask(
376
+ config=self.config,
377
+ inputs_embeds=inputs_embeds,
378
+ attention_mask=attention_mask,
379
+ past_key_values=past_key_values,
380
+ position_ids=position_ids,
381
+ )
382
+
383
+ inputs_embeds = self.embed_dropout(inputs_embeds)
384
+ hidden_states = inputs_embeds
385
+ position_embeddings = self.rotary_emb(hidden_states, position_ids=position_ids)
386
+
387
+ for decoder_layer in self.layers[: self.config.num_hidden_layers]:
388
+ hidden_states = decoder_layer(
389
+ hidden_states,
390
+ attention_mask=causal_mask,
391
+ position_ids=position_ids,
392
+ past_key_values=past_key_values,
393
+ use_cache=use_cache,
394
+ position_embeddings=position_embeddings,
395
+ **kwargs,
396
+ )
397
+
398
+ hidden_states = self.final_layernorm(hidden_states)
399
+
400
+ return BaseModelOutputWithPast(
401
+ last_hidden_state=hidden_states,
402
+ past_key_values=past_key_values,
403
+ )
404
+
405
+
406
+ @auto_docstring
407
+ class PhiForCausalLM(PhiPreTrainedModel, GenerationMixin):
408
+ _tied_weights_keys = {"lm_head.weight": "model.embed_tokens.weight"}
409
+ _tp_plan = {"lm_head": "colwise_gather_output"}
410
+ _pp_plan = {"lm_head": (["hidden_states"], ["logits"])}
411
+
412
+ def __init__(self, config):
413
+ super().__init__(config)
414
+ self.model = PhiModel(config)
415
+ self.vocab_size = config.vocab_size
416
+ self.lm_head = nn.Linear(config.hidden_size, config.vocab_size, bias=True)
417
+
418
+ # Initialize weights and apply final processing
419
+ self.post_init()
420
+
421
+ @can_return_tuple
422
+ @auto_docstring
423
+ def forward(
424
+ self,
425
+ input_ids: torch.LongTensor | None = None,
426
+ attention_mask: torch.Tensor | None = None,
427
+ position_ids: torch.LongTensor | None = None,
428
+ past_key_values: Cache | None = None,
429
+ inputs_embeds: torch.FloatTensor | None = None,
430
+ labels: torch.LongTensor | None = None,
431
+ use_cache: bool | None = None,
432
+ logits_to_keep: int | torch.Tensor = 0,
433
+ **kwargs: Unpack[TransformersKwargs],
434
+ ) -> CausalLMOutputWithPast:
435
+ r"""
436
+ Example:
437
+
438
+ ```python
439
+ >>> from transformers import AutoTokenizer, PhiForCausalLM
440
+
441
+ >>> model = PhiForCausalLM.from_pretrained("meta-phi/Phi-2-7b-hf")
442
+ >>> tokenizer = AutoTokenizer.from_pretrained("meta-phi/Phi-2-7b-hf")
443
+
444
+ >>> prompt = "Hey, are you conscious? Can you talk to me?"
445
+ >>> inputs = tokenizer(prompt, return_tensors="pt")
446
+
447
+ >>> # Generate
448
+ >>> generate_ids = model.generate(inputs.input_ids, max_length=30)
449
+ >>> tokenizer.batch_decode(generate_ids, skip_special_tokens=True, clean_up_tokenization_spaces=False)[0]
450
+ "Hey, are you conscious? Can you talk to me?\nI'm not conscious, but I can talk to you."
451
+ ```"""
452
+ outputs: BaseModelOutputWithPast = self.model(
453
+ input_ids=input_ids,
454
+ attention_mask=attention_mask,
455
+ position_ids=position_ids,
456
+ past_key_values=past_key_values,
457
+ inputs_embeds=inputs_embeds,
458
+ use_cache=use_cache,
459
+ **kwargs,
460
+ )
461
+
462
+ hidden_states = outputs.last_hidden_state
463
+ # Only compute necessary logits, and do not upcast them to float if we are not computing the loss
464
+ slice_indices = slice(-logits_to_keep, None) if isinstance(logits_to_keep, int) else logits_to_keep
465
+ logits = self.lm_head(hidden_states[:, slice_indices, :])
466
+
467
+ loss = None
468
+ if labels is not None:
469
+ loss = self.loss_function(logits=logits, labels=labels, vocab_size=self.config.vocab_size, **kwargs)
470
+
471
+ return CausalLMOutputWithPast(
472
+ loss=loss,
473
+ logits=logits,
474
+ past_key_values=outputs.past_key_values,
475
+ hidden_states=outputs.hidden_states,
476
+ attentions=outputs.attentions,
477
+ )
478
+
479
+
480
+ class PhiForSequenceClassification(GenericForSequenceClassification, PhiPreTrainedModel):
481
+ pass
482
+
483
+
484
+ class PhiForTokenClassification(GenericForTokenClassification, PhiPreTrainedModel):
485
+ pass
486
+
487
+
488
+ __all__ = [
489
+ "PhiPreTrainedModel",
490
+ "PhiModel",
491
+ "PhiForCausalLM",
492
+ "PhiForSequenceClassification",
493
+ "PhiForTokenClassification",
494
+ ]
LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/transformers/models/phi/modular_phi.py ADDED
@@ -0,0 +1,288 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from collections.abc import Callable
2
+ from typing import Optional
3
+
4
+ import torch
5
+ import torch.nn as nn
6
+
7
+ from ...cache_utils import Cache, DynamicCache
8
+ from ...masking_utils import create_causal_mask
9
+ from ...modeling_layers import GradientCheckpointingLayer
10
+ from ...modeling_outputs import (
11
+ BaseModelOutputWithPast,
12
+ )
13
+ from ...modeling_utils import ALL_ATTENTION_FUNCTIONS
14
+ from ...processing_utils import Unpack
15
+ from ...utils import TransformersKwargs, auto_docstring, logging
16
+ from ...utils.generic import merge_with_config_defaults
17
+ from ...utils.output_capturing import capture_outputs
18
+ from ..clip.modeling_clip import CLIPMLP
19
+ from ..llama.modeling_llama import (
20
+ LlamaAttention,
21
+ LlamaForCausalLM,
22
+ LlamaForSequenceClassification,
23
+ LlamaForTokenClassification,
24
+ LlamaModel,
25
+ LlamaPreTrainedModel,
26
+ LlamaRotaryEmbedding,
27
+ apply_rotary_pos_emb,
28
+ eager_attention_forward,
29
+ )
30
+ from .configuration_phi import PhiConfig
31
+
32
+
33
+ logger = logging.get_logger(__name__)
34
+
35
+ _CHECKPOINT_FOR_DOC = "microsoft/phi-1"
36
+ _CONFIG_FOR_DOC = "PhiConfig"
37
+
38
+
39
+ class PhiRotaryEmbedding(LlamaRotaryEmbedding):
40
+ @staticmethod
41
+ def compute_default_rope_parameters(
42
+ config: PhiConfig | None = None,
43
+ device: Optional["torch.device"] = None,
44
+ seq_len: int | None = None,
45
+ ) -> tuple["torch.Tensor", float]:
46
+ """
47
+ Computes the inverse frequencies according to the original RoPE implementation
48
+ Args:
49
+ config ([`~transformers.PreTrainedConfig`]):
50
+ The model configuration.
51
+ device (`torch.device`):
52
+ The device to use for initialization of the inverse frequencies.
53
+ seq_len (`int`, *optional*):
54
+ The current sequence length. Unused for this type of RoPE.
55
+ Returns:
56
+ Tuple of (`torch.Tensor`, `float`), containing the inverse frequencies for the RoPE embeddings and the
57
+ post-processing scaling factor applied to the computed cos/sin (unused in this type of RoPE).
58
+ """
59
+ base = config.rope_parameters["rope_theta"]
60
+ partial_rotary_factor = config.rope_parameters.get("partial_rotary_factor", 1.0)
61
+ head_dim = getattr(config, "head_dim", None) or config.hidden_size // config.num_attention_heads
62
+ dim = int(head_dim * partial_rotary_factor)
63
+
64
+ attention_factor = 1.0 # Unused in this type of RoPE
65
+
66
+ # Compute the inverse frequencies
67
+ inv_freq = 1.0 / (
68
+ base ** (torch.arange(0, dim, 2, dtype=torch.int64).to(device=device, dtype=torch.float) / dim)
69
+ )
70
+ return inv_freq, attention_factor
71
+
72
+
73
+ class PhiAttention(LlamaAttention):
74
+ def __init__(self, config: PhiConfig, layer_idx: int):
75
+ super().__init__(config, layer_idx)
76
+ self.q_proj = nn.Linear(config.hidden_size, config.num_attention_heads * self.head_dim, bias=True)
77
+ self.k_proj = nn.Linear(config.hidden_size, config.num_key_value_heads * self.head_dim, bias=True)
78
+ self.v_proj = nn.Linear(config.hidden_size, config.num_key_value_heads * self.head_dim, bias=True)
79
+ self.dense = nn.Linear(config.num_attention_heads * self.head_dim, config.hidden_size, bias=True)
80
+ del self.o_proj
81
+ self.rotary_ndims = int(self.head_dim * config.rope_parameters["partial_rotary_factor"])
82
+ self.qk_layernorm = config.qk_layernorm
83
+ if self.qk_layernorm:
84
+ self.q_layernorm = nn.LayerNorm(
85
+ config.hidden_size // config.num_attention_heads, eps=config.layer_norm_eps, elementwise_affine=True
86
+ )
87
+ self.k_layernorm = nn.LayerNorm(
88
+ config.hidden_size // config.num_attention_heads, eps=config.layer_norm_eps, elementwise_affine=True
89
+ )
90
+
91
+ def forward(
92
+ self,
93
+ hidden_states: torch.Tensor,
94
+ position_embeddings: tuple[torch.Tensor, torch.Tensor],
95
+ attention_mask: torch.Tensor | None,
96
+ past_key_values: Cache | None = None,
97
+ **kwargs,
98
+ ) -> tuple[torch.Tensor, torch.Tensor | None]:
99
+ input_shape = hidden_states.shape[:-1]
100
+ hidden_shape = (*input_shape, -1, self.head_dim)
101
+
102
+ query_states = self.q_proj(hidden_states).view(hidden_shape).transpose(1, 2)
103
+ key_states = self.k_proj(hidden_states).view(hidden_shape).transpose(1, 2)
104
+ value_states = self.v_proj(hidden_states).view(hidden_shape).transpose(1, 2)
105
+
106
+ if self.qk_layernorm:
107
+ query_states = self.q_layernorm(query_states)
108
+ key_states = self.k_layernorm(key_states)
109
+
110
+ cos, sin = position_embeddings
111
+ # Partial rotary embedding
112
+ query_rot, query_pass = (
113
+ query_states[..., : self.rotary_ndims],
114
+ query_states[..., self.rotary_ndims :],
115
+ )
116
+ key_rot, key_pass = (
117
+ key_states[..., : self.rotary_ndims],
118
+ key_states[..., self.rotary_ndims :],
119
+ )
120
+ # [batch_size, seq_length, num_heads, head_dim // config.partial_rotary_factor]
121
+ query_rot, key_rot = apply_rotary_pos_emb(query_rot, key_rot, cos, sin)
122
+
123
+ # [batch_size, seq_length, num_heads, head_dim]
124
+ query_states = torch.cat((query_rot, query_pass), dim=-1)
125
+ key_states = torch.cat((key_rot, key_pass), dim=-1)
126
+
127
+ if past_key_values is not None:
128
+ key_states, value_states = past_key_values.update(key_states, value_states, self.layer_idx)
129
+
130
+ attention_interface: Callable = ALL_ATTENTION_FUNCTIONS.get_interface(
131
+ self.config._attn_implementation, eager_attention_forward
132
+ )
133
+
134
+ attn_output, attn_weights = attention_interface(
135
+ self,
136
+ query_states,
137
+ key_states,
138
+ value_states,
139
+ attention_mask,
140
+ dropout=0.0 if not self.training else self.attention_dropout,
141
+ scaling=self.scaling,
142
+ **kwargs,
143
+ )
144
+
145
+ attn_output = attn_output.reshape(*input_shape, -1).contiguous()
146
+ attn_output = self.dense(attn_output)
147
+ return attn_output, attn_weights
148
+
149
+
150
+ class PhiMLP(CLIPMLP):
151
+ pass
152
+
153
+
154
+ class PhiDecoderLayer(GradientCheckpointingLayer):
155
+ def __init__(self, config: PhiConfig, layer_idx: int):
156
+ super().__init__()
157
+ self.self_attn = PhiAttention(config, layer_idx=layer_idx)
158
+ self.mlp = PhiMLP(config)
159
+ self.input_layernorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps)
160
+ self.resid_dropout = nn.Dropout(config.resid_pdrop)
161
+
162
+ def forward(
163
+ self,
164
+ hidden_states: torch.Tensor,
165
+ attention_mask: torch.Tensor | None = None,
166
+ position_ids: torch.LongTensor | None = None,
167
+ past_key_values: Cache | None = None,
168
+ use_cache: bool | None = False,
169
+ position_embeddings: tuple[torch.Tensor, torch.Tensor] | None = None,
170
+ **kwargs: Unpack[TransformersKwargs],
171
+ ) -> torch.Tensor:
172
+ residual = hidden_states
173
+
174
+ hidden_states = self.input_layernorm(hidden_states)
175
+
176
+ attn_outputs, _ = self.self_attn(
177
+ hidden_states=hidden_states,
178
+ attention_mask=attention_mask,
179
+ position_ids=position_ids,
180
+ past_key_values=past_key_values,
181
+ use_cache=use_cache,
182
+ position_embeddings=position_embeddings,
183
+ **kwargs,
184
+ )
185
+ attn_outputs = self.resid_dropout(attn_outputs)
186
+
187
+ feed_forward_hidden_states = self.resid_dropout(self.mlp(hidden_states))
188
+ hidden_states = attn_outputs + feed_forward_hidden_states + residual
189
+
190
+ return hidden_states
191
+
192
+
193
+ class PhiPreTrainedModel(LlamaPreTrainedModel):
194
+ _can_record_outputs = {
195
+ "hidden_states": PhiDecoderLayer,
196
+ "attentions": PhiAttention,
197
+ }
198
+
199
+
200
+ class PhiModel(LlamaModel):
201
+ def __init__(self, config: PhiConfig):
202
+ super().__init__(config)
203
+ self.layers = nn.ModuleList(
204
+ [PhiDecoderLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)]
205
+ )
206
+ self.embed_dropout = nn.Dropout(config.embd_pdrop)
207
+ self.final_layernorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps)
208
+ del self.norm
209
+
210
+ @merge_with_config_defaults
211
+ @capture_outputs
212
+ @auto_docstring
213
+ def forward(
214
+ self,
215
+ input_ids: torch.LongTensor | None = None,
216
+ attention_mask: torch.Tensor | None = None,
217
+ position_ids: torch.LongTensor | None = None,
218
+ past_key_values: Cache | None = None,
219
+ inputs_embeds: torch.FloatTensor | None = None,
220
+ use_cache: bool | None = None,
221
+ **kwargs: Unpack[TransformersKwargs],
222
+ ) -> BaseModelOutputWithPast:
223
+ if (input_ids is None) ^ (inputs_embeds is not None):
224
+ raise ValueError("You must specify exactly one of input_ids or inputs_embeds")
225
+
226
+ if inputs_embeds is None:
227
+ inputs_embeds = self.embed_tokens(input_ids)
228
+
229
+ if use_cache and past_key_values is None:
230
+ past_key_values = DynamicCache(config=self.config)
231
+
232
+ if position_ids is None:
233
+ past_seen_tokens = past_key_values.get_seq_length() if past_key_values is not None else 0
234
+ position_ids = torch.arange(inputs_embeds.shape[1], device=inputs_embeds.device) + past_seen_tokens
235
+ position_ids = position_ids.unsqueeze(0)
236
+
237
+ causal_mask = create_causal_mask(
238
+ config=self.config,
239
+ inputs_embeds=inputs_embeds,
240
+ attention_mask=attention_mask,
241
+ past_key_values=past_key_values,
242
+ position_ids=position_ids,
243
+ )
244
+
245
+ inputs_embeds = self.embed_dropout(inputs_embeds)
246
+ hidden_states = inputs_embeds
247
+ position_embeddings = self.rotary_emb(hidden_states, position_ids=position_ids)
248
+
249
+ for decoder_layer in self.layers[: self.config.num_hidden_layers]:
250
+ hidden_states = decoder_layer(
251
+ hidden_states,
252
+ attention_mask=causal_mask,
253
+ position_ids=position_ids,
254
+ past_key_values=past_key_values,
255
+ use_cache=use_cache,
256
+ position_embeddings=position_embeddings,
257
+ **kwargs,
258
+ )
259
+
260
+ hidden_states = self.final_layernorm(hidden_states)
261
+
262
+ return BaseModelOutputWithPast(
263
+ last_hidden_state=hidden_states,
264
+ past_key_values=past_key_values,
265
+ )
266
+
267
+
268
+ class PhiForCausalLM(LlamaForCausalLM):
269
+ def __init__(self, config):
270
+ super().__init__(config)
271
+ self.lm_head = nn.Linear(config.hidden_size, config.vocab_size, bias=True)
272
+
273
+
274
+ class PhiForSequenceClassification(LlamaForSequenceClassification):
275
+ pass
276
+
277
+
278
+ class PhiForTokenClassification(LlamaForTokenClassification):
279
+ pass
280
+
281
+
282
+ __all__ = [
283
+ "PhiPreTrainedModel",
284
+ "PhiModel",
285
+ "PhiForCausalLM",
286
+ "PhiForSequenceClassification",
287
+ "PhiForTokenClassification",
288
+ ]
LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/transformers/models/wav2vec2/tokenization_wav2vec2.py ADDED
@@ -0,0 +1,653 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2021 The Facebook Inc. 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
+ """Tokenization class for Wav2Vec2."""
15
+
16
+ import json
17
+ import os
18
+ from dataclasses import dataclass
19
+ from itertools import groupby
20
+ from typing import TYPE_CHECKING, Union
21
+
22
+ import numpy as np
23
+
24
+ from ...tokenization_python import PreTrainedTokenizer
25
+ from ...tokenization_utils_base import AddedToken
26
+ from ...utils import (
27
+ ModelOutput,
28
+ logging,
29
+ to_py_obj,
30
+ )
31
+
32
+
33
+ logger = logging.get_logger(__name__)
34
+
35
+
36
+ if TYPE_CHECKING:
37
+ import torch
38
+
39
+
40
+ VOCAB_FILES_NAMES = {
41
+ "vocab_file": "vocab.json",
42
+ "tokenizer_config_file": "tokenizer_config.json",
43
+ }
44
+
45
+
46
+ # Wav2Vec2 has no max input length
47
+
48
+ WAV2VEC2_KWARGS_DOCSTRING = r"""
49
+ padding (`bool`, `str` or [`~utils.PaddingStrategy`], *optional*, defaults to `False`):
50
+ Activates and controls padding. Accepts the following values:
51
+
52
+ - `True` or `'longest'`: Pad to the longest sequence in the batch (or no padding if only a single
53
+ sequence if provided).
54
+ - `'max_length'`: Pad to a maximum length specified with the argument `max_length` or to the maximum
55
+ acceptable input length for the model if that argument is not provided.
56
+ - `False` or `'do_not_pad'` (default): No padding (i.e., can output a batch with sequences of different
57
+ lengths).
58
+ max_length (`int`, *optional*):
59
+ Controls the maximum length to use by one of the truncation/padding parameters.
60
+
61
+ If left unset or set to `None`, this will use the predefined model maximum length if a maximum length
62
+ is required by one of the truncation/padding parameters. If the model has no specific maximum input
63
+ length (like XLNet) truncation/padding to a maximum length will be deactivated.
64
+ pad_to_multiple_of (`int`, *optional*):
65
+ If set will pad the sequence to a multiple of the provided value. This is especially useful to enable
66
+ the use of Tensor Cores on NVIDIA hardware with compute capability `>= 7.5` (Volta).
67
+ return_tensors (`str` or [`~utils.TensorType`], *optional*):
68
+ If set, will return tensors instead of list of python integers. Acceptable values are:
69
+
70
+ - `'pt'`: Return PyTorch `torch.Tensor` objects.
71
+ - `'np'`: Return Numpy `np.ndarray` objects.
72
+ verbose (`bool`, *optional*, defaults to `True`):
73
+ Whether or not to print more information and warnings.
74
+ """
75
+
76
+ ListOfDict = list[dict[str, int | str]]
77
+
78
+
79
+ @dataclass
80
+ class Wav2Vec2CTCTokenizerOutput(ModelOutput):
81
+ """
82
+ Output type of [` Wav2Vec2CTCTokenizer`], with transcription.
83
+
84
+ Args:
85
+ text (list of `str` or `str`):
86
+ Decoded logits in text from. Usually the speech transcription.
87
+ char_offsets (list of `list[dict[str, Union[int, str]]]` or `list[dict[str, Union[int, str]]]`):
88
+ Offsets of the decoded characters. In combination with sampling rate and model downsampling rate char
89
+ offsets can be used to compute time stamps for each character. Total logit score of the beam associated with
90
+ produced text.
91
+ word_offsets (list of `list[dict[str, Union[int, str]]]` or `list[dict[str, Union[int, str]]]`):
92
+ Offsets of the decoded words. In combination with sampling rate and model downsampling rate word offsets
93
+ can be used to compute time stamps for each word.
94
+ """
95
+
96
+ text: list[str] | str
97
+ char_offsets: list[ListOfDict] | ListOfDict = None
98
+ word_offsets: list[ListOfDict] | ListOfDict = None
99
+
100
+
101
+ class Wav2Vec2CTCTokenizer(PreTrainedTokenizer):
102
+ """
103
+ Constructs a Wav2Vec2CTC tokenizer.
104
+
105
+ This tokenizer inherits from [`PreTrainedTokenizer`] which contains some of the main methods. Users should refer to
106
+ the superclass for more information regarding such methods.
107
+
108
+ Args:
109
+ vocab_file (`str`):
110
+ File containing the vocabulary.
111
+ bos_token (`str`, *optional*, defaults to `"<s>"`):
112
+ The beginning of sentence token.
113
+ eos_token (`str`, *optional*, defaults to `"</s>"`):
114
+ The end of sentence token.
115
+ unk_token (`str`, *optional*, defaults to `"<unk>"`):
116
+ The unknown token. A token that is not in the vocabulary cannot be converted to an ID and is set to be this
117
+ token instead.
118
+ pad_token (`str`, *optional*, defaults to `"<pad>"`):
119
+ The token used for padding, for example when batching sequences of different lengths.
120
+ word_delimiter_token (`str`, *optional*, defaults to `"|"`):
121
+ The token used for defining the end of a word.
122
+ do_lower_case (`bool`, *optional*, defaults to `False`):
123
+ Whether or not to accept lowercase input and lowercase the output when decoding.
124
+ target_lang (`str`, *optional*):
125
+ A target language the tokenizer should set by default. `target_lang` has to be defined for multi-lingual,
126
+ nested vocabulary such as [facebook/mms-1b-all](https://huggingface.co/facebook/mms-1b-all).
127
+
128
+ **kwargs
129
+ Additional keyword arguments passed along to [`PreTrainedTokenizer`]
130
+ """
131
+
132
+ vocab_files_names = VOCAB_FILES_NAMES
133
+ model_input_names = ["input_ids", "attention_mask"]
134
+
135
+ def __init__(
136
+ self,
137
+ vocab_file,
138
+ bos_token="<s>",
139
+ eos_token="</s>",
140
+ unk_token="<unk>",
141
+ pad_token="<pad>",
142
+ word_delimiter_token="|",
143
+ replace_word_delimiter_char=" ",
144
+ do_lower_case=False,
145
+ target_lang=None,
146
+ **kwargs,
147
+ ):
148
+ self._word_delimiter_token = word_delimiter_token
149
+
150
+ self.do_lower_case = do_lower_case
151
+ self.replace_word_delimiter_char = replace_word_delimiter_char
152
+ self.target_lang = target_lang
153
+
154
+ with open(vocab_file, encoding="utf-8") as vocab_handle:
155
+ self.vocab = json.load(vocab_handle)
156
+
157
+ # if target lang is defined vocab must be a nested dict
158
+ # with each target lang being one vocabulary
159
+ if target_lang is not None:
160
+ self.encoder = self.vocab[target_lang]
161
+ else:
162
+ self.encoder = self.vocab
163
+
164
+ self.decoder = {v: k for k, v in self.encoder.items()}
165
+
166
+ super().__init__(
167
+ unk_token=unk_token,
168
+ bos_token=bos_token,
169
+ eos_token=eos_token,
170
+ pad_token=pad_token,
171
+ do_lower_case=do_lower_case,
172
+ word_delimiter_token=word_delimiter_token,
173
+ replace_word_delimiter_char=replace_word_delimiter_char,
174
+ target_lang=target_lang,
175
+ special_tokens_pattern="none",
176
+ **kwargs,
177
+ )
178
+ # make sure that tokens made of several
179
+ # characters are not split at tokenization
180
+ for token in self.encoder:
181
+ if len(token) > 1:
182
+ self.add_tokens(AddedToken(token, rstrip=True, lstrip=True, normalized=False))
183
+
184
+ def set_target_lang(self, target_lang: str):
185
+ """
186
+ Set the target language of a nested multi-lingual dictionary
187
+ """
188
+ if self.vocab == self.encoder:
189
+ raise ValueError(f"{self.vocab} is not a multi-lingual, nested tokenizer. Cannot set target language.")
190
+
191
+ if target_lang not in self.vocab:
192
+ raise ValueError(f"{target_lang} does not exist. Choose one of {', '.join(self.vocab.keys())}.")
193
+
194
+ self.target_lang = target_lang
195
+ self.init_kwargs["target_lang"] = target_lang
196
+ self.encoder = self.vocab[target_lang]
197
+ self.decoder = {v: k for k, v in self.encoder.items()}
198
+
199
+ # Remove conflicting entries from _added_tokens_decoder so vocabulary tokens take precedence
200
+ for token_id in list(self._added_tokens_decoder.keys()):
201
+ if token_id in self.decoder:
202
+ del self._added_tokens_decoder[token_id]
203
+
204
+ # make sure that tokens made of several
205
+ # characters are not split at tokenization
206
+ for token in self.encoder:
207
+ if len(token) > 1:
208
+ self.add_tokens(AddedToken(token, rstrip=True, lstrip=True, normalized=False))
209
+
210
+ @property
211
+ def word_delimiter_token(self) -> str:
212
+ """
213
+ `str`: Word delimiter token. Log an error if used while not having been set.
214
+ """
215
+ if self._word_delimiter_token is None and self.verbose:
216
+ logger.error("Using word_delimiter_token, but it is not set yet.")
217
+ return None
218
+ return str(self._word_delimiter_token)
219
+
220
+ @property
221
+ def word_delimiter_token_id(self) -> int | None:
222
+ """
223
+ `Optional[int]`: Id of the word_delimiter_token in the vocabulary. Returns `None` if the token has not been
224
+ set.
225
+ """
226
+ if self._word_delimiter_token is None:
227
+ return None
228
+ return self.convert_tokens_to_ids(self.word_delimiter_token)
229
+
230
+ @word_delimiter_token.setter
231
+ def word_delimiter_token(self, value):
232
+ self._word_delimiter_token = value
233
+
234
+ @word_delimiter_token_id.setter
235
+ def word_delimiter_token_id(self, value):
236
+ self._word_delimiter_token = self.convert_tokens_to_ids(value)
237
+
238
+ @property
239
+ def vocab_size(self) -> int:
240
+ return len(self.decoder)
241
+
242
+ def get_vocab(self) -> dict:
243
+ vocab = dict(self.encoder)
244
+ vocab.update(self.added_tokens_encoder)
245
+ return vocab
246
+
247
+ def _add_tokens(self, new_tokens: list[str] | list[AddedToken], special_tokens: bool = False) -> int:
248
+ # Overwritten to never strip!
249
+ to_add = []
250
+ for token in new_tokens:
251
+ if isinstance(token, str):
252
+ to_add.append(AddedToken(token, rstrip=False, lstrip=False, normalized=False))
253
+ else:
254
+ to_add.append(token)
255
+
256
+ return super()._add_tokens(to_add, special_tokens)
257
+
258
+ def _tokenize(self, text, **kwargs):
259
+ """
260
+ Converts a string into a sequence of tokens (string), using the tokenizer.
261
+ """
262
+ if self.do_lower_case:
263
+ text = text.upper()
264
+
265
+ return list(text.replace(" ", self.word_delimiter_token))
266
+
267
+ def _convert_token_to_id(self, token: str) -> int:
268
+ """Converts a token (str) in an index (integer) using the vocab."""
269
+ return self.encoder.get(token, self.encoder.get(self.unk_token))
270
+
271
+ def _convert_id_to_token(self, index: int) -> str:
272
+ """Converts an index (integer) in a token (str) using the vocab."""
273
+ result = self.decoder.get(index, self.unk_token)
274
+ return result
275
+
276
+ def convert_ids_to_tokens(self, ids: int | list[int], skip_special_tokens: bool = False) -> str | list[str]:
277
+ """Overridden to prioritize vocabulary tokens over added tokens for nested vocabularies."""
278
+ if isinstance(ids, int):
279
+ if ids in self.decoder:
280
+ return self.decoder[ids]
281
+ return self._added_tokens_decoder[ids].content if ids in self._added_tokens_decoder else self.unk_token
282
+
283
+ tokens = []
284
+ for index in ids:
285
+ index = int(index)
286
+ if skip_special_tokens and index in self.all_special_ids:
287
+ continue
288
+ if index in self.decoder:
289
+ tokens.append(self.decoder[index])
290
+ elif index in self._added_tokens_decoder:
291
+ tokens.append(self._added_tokens_decoder[index].content)
292
+ else:
293
+ tokens.append(self.unk_token)
294
+ return tokens
295
+
296
+ def convert_tokens_to_string(
297
+ self,
298
+ tokens: list[str],
299
+ group_tokens: bool = True,
300
+ spaces_between_special_tokens: bool = False,
301
+ output_char_offsets: bool = False,
302
+ output_word_offsets: bool = False,
303
+ ) -> dict[str, str | float]:
304
+ """
305
+ Converts a connectionist-temporal-classification (CTC) output tokens into a single string.
306
+ """
307
+ if len(tokens) == 0:
308
+ return {"text": "", "char_offsets": [], "word_offsets": []}
309
+ # group same tokens into non-repeating tokens in CTC style decoding
310
+ if group_tokens:
311
+ chars, char_repetitions = zip(*((token, len(list(group_iter))) for token, group_iter in groupby(tokens)))
312
+ else:
313
+ chars = tokens
314
+ char_repetitions = len(tokens) * [1]
315
+
316
+ # filter self.pad_token which is used as CTC-blank token
317
+ processed_chars = list(filter(lambda char: char != self.pad_token, chars))
318
+
319
+ # replace delimiter token
320
+ processed_chars = [
321
+ self.replace_word_delimiter_char if char == self.word_delimiter_token else char for char in processed_chars
322
+ ]
323
+
324
+ # retrieve offsets
325
+ char_offsets = word_offsets = None
326
+ if output_char_offsets or output_word_offsets:
327
+ char_offsets = self._compute_offsets(char_repetitions, chars, self.pad_token)
328
+
329
+ if len(char_offsets) != len(processed_chars):
330
+ raise ValueError(
331
+ f"`char_offsets`: {char_offsets} and `processed_tokens`: {processed_chars}"
332
+ " have to be of the same length, but are: "
333
+ f"`len(offsets)`: {len(char_offsets)} and `len(processed_tokens)`:"
334
+ f" {len(processed_chars)}"
335
+ )
336
+
337
+ # set tokens to correct processed token
338
+ for i, char in enumerate(processed_chars):
339
+ char_offsets[i]["char"] = char
340
+
341
+ # retrieve word offsets from character offsets
342
+ word_offsets = None
343
+ if output_word_offsets:
344
+ word_offsets = self._get_word_offsets(char_offsets, self.replace_word_delimiter_char)
345
+
346
+ # don't output chars if not set to True
347
+ if not output_char_offsets:
348
+ char_offsets = None
349
+
350
+ # join to string
351
+ join_char = " " if spaces_between_special_tokens else ""
352
+ string = join_char.join(processed_chars).strip()
353
+
354
+ if self.do_lower_case:
355
+ string = string.lower()
356
+
357
+ return {"text": string, "char_offsets": char_offsets, "word_offsets": word_offsets}
358
+
359
+ @staticmethod
360
+ def _compute_offsets(char_repetitions: list[int], chars: list[str], ctc_token: int) -> list[dict[str, str | int]]:
361
+ end_indices = np.asarray(char_repetitions).cumsum()
362
+ start_indices = np.concatenate(([0], end_indices[:-1]))
363
+
364
+ offsets = [
365
+ {"char": t, "start_offset": s, "end_offset": e} for t, s, e in zip(chars, start_indices, end_indices)
366
+ ]
367
+
368
+ # filter out CTC token
369
+ offsets = list(filter(lambda offsets: offsets["char"] != ctc_token, offsets))
370
+ return offsets
371
+
372
+ @staticmethod
373
+ def _get_word_offsets(offsets: dict[str, str | float], word_delimiter_char: str = " ") -> dict[str, str | float]:
374
+ word_offsets = []
375
+
376
+ last_state = "SPACE"
377
+ word = ""
378
+ start_offset = 0
379
+ end_offset = 0
380
+ for i, offset in enumerate(offsets):
381
+ char = offset["char"]
382
+ state = "SPACE" if char == word_delimiter_char else "WORD"
383
+
384
+ if state == last_state:
385
+ # If we are in the same state as before, we simply repeat what we've done before
386
+ end_offset = offset["end_offset"]
387
+ word += char
388
+ else:
389
+ # Switching state
390
+ if state == "SPACE":
391
+ # Finishing a word
392
+ word_offsets.append({"word": word, "start_offset": start_offset, "end_offset": end_offset})
393
+ else:
394
+ # Starting a new word
395
+ start_offset = offset["start_offset"]
396
+ end_offset = offset["end_offset"]
397
+ word = char
398
+
399
+ last_state = state
400
+ if last_state == "WORD":
401
+ word_offsets.append({"word": word, "start_offset": start_offset, "end_offset": end_offset})
402
+
403
+ return word_offsets
404
+
405
+ def prepare_for_tokenization(self, text, is_split_into_words=False, **kwargs):
406
+ if is_split_into_words:
407
+ text = " " + text
408
+ return (text, kwargs)
409
+
410
+ def _decode(
411
+ self,
412
+ token_ids: list[int],
413
+ skip_special_tokens: bool = False,
414
+ clean_up_tokenization_spaces: bool | None = None,
415
+ group_tokens: bool = True,
416
+ spaces_between_special_tokens: bool = False,
417
+ output_word_offsets: bool | None = False,
418
+ output_char_offsets: bool | None = False,
419
+ ) -> str:
420
+ """
421
+ special _decode function is needed because added tokens should be treated exactly the
422
+ same as tokens of the base vocabulary and therefore the function `convert_tokens_to_string` has to be called on
423
+ the whole token list and not individually on added tokens
424
+ """
425
+ # Don't skip special tokens in convert_ids_to_tokens so we can handle word_delimiter_token specially
426
+ filtered_tokens = self.convert_ids_to_tokens(token_ids, skip_special_tokens=False)
427
+
428
+ result = []
429
+ for token in filtered_tokens:
430
+ if skip_special_tokens and token in self.all_special_tokens and token != self.word_delimiter_token:
431
+ continue
432
+ result.append(token)
433
+
434
+ string_output = self.convert_tokens_to_string(
435
+ result,
436
+ group_tokens=group_tokens,
437
+ spaces_between_special_tokens=spaces_between_special_tokens,
438
+ output_word_offsets=output_word_offsets,
439
+ output_char_offsets=output_char_offsets,
440
+ )
441
+
442
+ text = string_output["text"]
443
+
444
+ clean_up_tokenization_spaces = (
445
+ clean_up_tokenization_spaces
446
+ if clean_up_tokenization_spaces is not None
447
+ else self.clean_up_tokenization_spaces
448
+ )
449
+ if clean_up_tokenization_spaces:
450
+ text = self.clean_up_tokenization(text)
451
+
452
+ if output_word_offsets or output_char_offsets:
453
+ return Wav2Vec2CTCTokenizerOutput(
454
+ text=text,
455
+ char_offsets=string_output["char_offsets"],
456
+ word_offsets=string_output["word_offsets"],
457
+ )
458
+ else:
459
+ return text
460
+
461
+ # overwritten from `tokenization_utils_base.py` because tokenizer can output
462
+ # `ModelOutput` which should not be a list for batched output and
463
+ # because we need docs for `output_char_offsets` here
464
+ def batch_decode(
465
+ self,
466
+ sequences: Union[list[int], list[list[int]], np.ndarray, "torch.Tensor"],
467
+ skip_special_tokens: bool = False,
468
+ clean_up_tokenization_spaces: bool | None = None,
469
+ output_char_offsets: bool = False,
470
+ output_word_offsets: bool = False,
471
+ **kwargs,
472
+ ) -> list[str]:
473
+ """
474
+ Convert a list of lists of token ids into a list of strings by calling decode.
475
+
476
+ Args:
477
+ sequences (`Union[list[int], list[list[int]], np.ndarray, torch.Tensor]`):
478
+ List of tokenized input ids. Can be obtained using the `__call__` method.
479
+ skip_special_tokens (`bool`, *optional*, defaults to `False`):
480
+ Whether or not to remove special tokens in the decoding.
481
+ clean_up_tokenization_spaces (`bool`, *optional*):
482
+ Whether or not to clean up the tokenization spaces.
483
+ output_char_offsets (`bool`, *optional*, defaults to `False`):
484
+ Whether or not to output character offsets. Character offsets can be used in combination with the
485
+ sampling rate and model downsampling rate to compute the time-stamps of transcribed characters.
486
+
487
+ <Tip>
488
+
489
+ Please take a look at the Example of [`~Wav2Vec2CTCTokenizer.decode`] to better understand how to make
490
+ use of `output_char_offsets`. [`~Wav2Vec2CTCTokenizer.batch_decode`] works the same way with batched
491
+ output.
492
+
493
+ </Tip>
494
+
495
+ output_word_offsets (`bool`, *optional*, defaults to `False`):
496
+ Whether or not to output word offsets. Word offsets can be used in combination with the sampling rate
497
+ and model downsampling rate to compute the time-stamps of transcribed words.
498
+
499
+ <Tip>
500
+
501
+ Please take a look at the Example of [`~Wav2Vec2CTCTokenizer.decode`] to better understand how to make
502
+ use of `output_word_offsets`. [`~Wav2Vec2CTCTokenizer.batch_decode`] works the same way with batched
503
+ output.
504
+
505
+ </Tip>
506
+
507
+ kwargs (additional keyword arguments, *optional*):
508
+ Will be passed to the underlying model specific decode method.
509
+
510
+ Returns:
511
+ `list[str]` or [`~models.wav2vec2.tokenization_wav2vec2.Wav2Vec2CTCTokenizerOutput`]: The list of decoded
512
+ sentences. Will be a [`~models.wav2vec2.tokenization_wav2vec2.Wav2Vec2CTCTokenizerOutput`] when
513
+ `output_char_offsets == True` or `output_word_offsets == True`.
514
+ """
515
+ batch_decoded = [
516
+ self.decode(
517
+ seq,
518
+ skip_special_tokens=skip_special_tokens,
519
+ clean_up_tokenization_spaces=clean_up_tokenization_spaces,
520
+ output_char_offsets=output_char_offsets,
521
+ output_word_offsets=output_word_offsets,
522
+ **kwargs,
523
+ )
524
+ for seq in sequences
525
+ ]
526
+ if output_char_offsets or output_word_offsets:
527
+ # transform list of dicts to dict of lists
528
+ return Wav2Vec2CTCTokenizerOutput({k: [d[k] for d in batch_decoded] for k in batch_decoded[0]})
529
+
530
+ return batch_decoded
531
+
532
+ # overwritten from `tokenization_utils_base.py` because we need docs for `output_char_offsets`
533
+ # and `output_word_offsets` here
534
+ def decode(
535
+ self,
536
+ token_ids: Union[int, list[int], np.ndarray, "torch.Tensor"],
537
+ skip_special_tokens: bool = False,
538
+ clean_up_tokenization_spaces: bool | None = None,
539
+ output_char_offsets: bool = False,
540
+ output_word_offsets: bool = False,
541
+ **kwargs,
542
+ ) -> str:
543
+ """
544
+ Converts a sequence of ids in a string, using the tokenizer and vocabulary with options to remove special
545
+ tokens and clean up tokenization spaces.
546
+
547
+ Similar to doing `self.convert_tokens_to_string(self.convert_ids_to_tokens(token_ids))`.
548
+
549
+ Args:
550
+ token_ids (`Union[int, list[int], np.ndarray, torch.Tensor]`):
551
+ List of tokenized input ids. Can be obtained using the `__call__` method.
552
+ skip_special_tokens (`bool`, *optional*, defaults to `False`):
553
+ Whether or not to remove special tokens in the decoding.
554
+ clean_up_tokenization_spaces (`bool`, *optional*):
555
+ Whether or not to clean up the tokenization spaces.
556
+ output_char_offsets (`bool`, *optional*, defaults to `False`):
557
+ Whether or not to output character offsets. Character offsets can be used in combination with the
558
+ sampling rate and model downsampling rate to compute the time-stamps of transcribed characters.
559
+
560
+ <Tip>
561
+
562
+ Please take a look at the example below to better understand how to make use of `output_char_offsets`.
563
+
564
+ </Tip>
565
+
566
+ output_word_offsets (`bool`, *optional*, defaults to `False`):
567
+ Whether or not to output word offsets. Word offsets can be used in combination with the sampling rate
568
+ and model downsampling rate to compute the time-stamps of transcribed words.
569
+
570
+ <Tip>
571
+
572
+ Please take a look at the example below to better understand how to make use of `output_word_offsets`.
573
+
574
+ </Tip>
575
+
576
+ kwargs (additional keyword arguments, *optional*):
577
+ Will be passed to the underlying model specific decode method.
578
+
579
+ Returns:
580
+ `str` or [`~models.wav2vec2.tokenization_wav2vec2.Wav2Vec2CTCTokenizerOutput`]: The list of decoded
581
+ sentences. Will be a [`~models.wav2vec2.tokenization_wav2vec2.Wav2Vec2CTCTokenizerOutput`] when
582
+ `output_char_offsets == True` or `output_word_offsets == True`.
583
+
584
+ Example:
585
+
586
+ ```python
587
+ >>> # Let's see how to retrieve time steps for a model
588
+ >>> from transformers import AutoTokenizer, AutoFeatureExtractor, AutoModelForCTC
589
+ >>> from datasets import load_dataset
590
+ >>> import datasets
591
+ >>> import torch
592
+
593
+ >>> # import model, feature extractor, tokenizer
594
+ >>> model = AutoModelForCTC.from_pretrained("facebook/wav2vec2-base-960h")
595
+ >>> tokenizer = AutoTokenizer.from_pretrained("facebook/wav2vec2-base-960h")
596
+ >>> feature_extractor = AutoFeatureExtractor.from_pretrained("facebook/wav2vec2-base-960h")
597
+
598
+ >>> # load first sample of English common_voice
599
+ >>> dataset = load_dataset("mozilla-foundation/common_voice_11_0", "en", split="train", streaming=True)
600
+ >>> dataset = dataset.cast_column("audio", datasets.Audio(sampling_rate=16_000))
601
+ >>> dataset_iter = iter(dataset)
602
+ >>> sample = next(dataset_iter)
603
+
604
+ >>> # forward sample through model to get greedily predicted transcription ids
605
+ >>> input_values = feature_extractor(sample["audio"]["array"], return_tensors="pt").input_values
606
+ >>> logits = model(input_values).logits[0]
607
+ >>> pred_ids = torch.argmax(logits, axis=-1)
608
+
609
+ >>> # retrieve word stamps (analogous commands for `output_char_offsets`)
610
+ >>> outputs = tokenizer.decode(pred_ids, output_word_offsets=True)
611
+ >>> # compute `time_offset` in seconds as product of downsampling ratio and sampling_rate
612
+ >>> time_offset = model.config.inputs_to_logits_ratio / feature_extractor.sampling_rate
613
+
614
+ >>> word_offsets = [
615
+ ... {
616
+ ... "word": d["word"],
617
+ ... "start_time": round(d["start_offset"] * time_offset, 2),
618
+ ... "end_time": round(d["end_offset"] * time_offset, 2),
619
+ ... }
620
+ ... for d in outputs.word_offsets
621
+ ... ]
622
+ >>> # compare word offsets with audio `en_train_0/common_voice_en_19121553.mp3` online on the dataset viewer:
623
+ >>> # https://huggingface.co/datasets/mozilla-foundation/common_voice_11_0/viewer/en
624
+ >>> word_offsets[:3]
625
+ [{'word': 'THE', 'start_time': 0.7, 'end_time': 0.78}, {'word': 'TRICK', 'start_time': 0.88, 'end_time': 1.08}, {'word': 'APPEARS', 'start_time': 1.2, 'end_time': 1.64}]
626
+ ```"""
627
+ # Convert inputs to python lists
628
+ token_ids = to_py_obj(token_ids)
629
+
630
+ return self._decode(
631
+ token_ids=token_ids,
632
+ skip_special_tokens=skip_special_tokens,
633
+ clean_up_tokenization_spaces=clean_up_tokenization_spaces,
634
+ output_char_offsets=output_char_offsets,
635
+ output_word_offsets=output_word_offsets,
636
+ **kwargs,
637
+ )
638
+
639
+ def save_vocabulary(self, save_directory: str, filename_prefix: str | None = None) -> tuple[str]:
640
+ if not os.path.isdir(save_directory):
641
+ logger.error(f"Vocabulary path ({save_directory}) should be a directory")
642
+ return
643
+ vocab_file = os.path.join(
644
+ save_directory, (filename_prefix + "-" if filename_prefix else "") + VOCAB_FILES_NAMES["vocab_file"]
645
+ )
646
+
647
+ with open(vocab_file, "w", encoding="utf-8") as f:
648
+ f.write(json.dumps(self.vocab, indent=2, sort_keys=True, ensure_ascii=False) + "\n")
649
+
650
+ return (vocab_file,)
651
+
652
+
653
+ __all__ = ["Wav2Vec2CTCTokenizer"]