caption-flow 0.5.7__tar.gz → 0.6.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. {caption_flow-0.5.7 → caption_flow-0.6.1}/PKG-INFO +90 -72
  2. {caption_flow-0.5.7 → caption_flow-0.6.1}/README.md +32 -15
  3. {caption_flow-0.5.7 → caption_flow-0.6.1}/pyproject.toml +1 -1
  4. {caption_flow-0.5.7 → caption_flow-0.6.1}/setup.py +48 -45
  5. {caption_flow-0.5.7 → caption_flow-0.6.1}/src/caption_flow/__init__.py +1 -1
  6. {caption_flow-0.5.7 → caption_flow-0.6.1}/src/caption_flow.egg-info/PKG-INFO +90 -72
  7. caption_flow-0.6.1/src/caption_flow.egg-info/requires.txt +92 -0
  8. {caption_flow-0.5.7 → caption_flow-0.6.1}/tests/test_dependency_config.py +12 -12
  9. {caption_flow-0.5.7 → caption_flow-0.6.1}/tests/test_webshart_dependency.py +3 -2
  10. {caption_flow-0.5.7 → caption_flow-0.6.1}/tests/test_worker_caption.py +10 -0
  11. caption_flow-0.5.7/src/caption_flow.egg-info/requires.txt +0 -89
  12. {caption_flow-0.5.7 → caption_flow-0.6.1}/LICENSE +0 -0
  13. {caption_flow-0.5.7 → caption_flow-0.6.1}/setup.cfg +0 -0
  14. {caption_flow-0.5.7 → caption_flow-0.6.1}/src/caption_flow/cli.py +0 -0
  15. {caption_flow-0.5.7 → caption_flow-0.6.1}/src/caption_flow/models.py +0 -0
  16. {caption_flow-0.5.7 → caption_flow-0.6.1}/src/caption_flow/monitor.py +0 -0
  17. {caption_flow-0.5.7 → caption_flow-0.6.1}/src/caption_flow/orchestrator.py +0 -0
  18. {caption_flow-0.5.7 → caption_flow-0.6.1}/src/caption_flow/processors/__init__.py +0 -0
  19. {caption_flow-0.5.7 → caption_flow-0.6.1}/src/caption_flow/processors/base.py +0 -0
  20. {caption_flow-0.5.7 → caption_flow-0.6.1}/src/caption_flow/processors/huggingface.py +0 -0
  21. {caption_flow-0.5.7 → caption_flow-0.6.1}/src/caption_flow/processors/local_filesystem.py +0 -0
  22. {caption_flow-0.5.7 → caption_flow-0.6.1}/src/caption_flow/processors/webdataset.py +0 -0
  23. {caption_flow-0.5.7 → caption_flow-0.6.1}/src/caption_flow/storage/__init__.py +0 -0
  24. {caption_flow-0.5.7 → caption_flow-0.6.1}/src/caption_flow/storage/exporter.py +0 -0
  25. {caption_flow-0.5.7 → caption_flow-0.6.1}/src/caption_flow/storage/manager.py +0 -0
  26. {caption_flow-0.5.7 → caption_flow-0.6.1}/src/caption_flow/utils/__init__.py +0 -0
  27. {caption_flow-0.5.7 → caption_flow-0.6.1}/src/caption_flow/utils/auth.py +0 -0
  28. {caption_flow-0.5.7 → caption_flow-0.6.1}/src/caption_flow/utils/caption_utils.py +0 -0
  29. {caption_flow-0.5.7 → caption_flow-0.6.1}/src/caption_flow/utils/certificates.py +0 -0
  30. {caption_flow-0.5.7 → caption_flow-0.6.1}/src/caption_flow/utils/checkpoint_tracker.py +0 -0
  31. {caption_flow-0.5.7 → caption_flow-0.6.1}/src/caption_flow/utils/chunk_tracker.py +0 -0
  32. {caption_flow-0.5.7 → caption_flow-0.6.1}/src/caption_flow/utils/image_processor.py +0 -0
  33. {caption_flow-0.5.7 → caption_flow-0.6.1}/src/caption_flow/utils/json_utils.py +0 -0
  34. {caption_flow-0.5.7 → caption_flow-0.6.1}/src/caption_flow/utils/output_policy.py +0 -0
  35. {caption_flow-0.5.7 → caption_flow-0.6.1}/src/caption_flow/utils/prompt_template.py +0 -0
  36. {caption_flow-0.5.7 → caption_flow-0.6.1}/src/caption_flow/utils/retry_queue.py +0 -0
  37. {caption_flow-0.5.7 → caption_flow-0.6.1}/src/caption_flow/utils/unicode_utils.py +0 -0
  38. {caption_flow-0.5.7 → caption_flow-0.6.1}/src/caption_flow/utils/vllm_config.py +0 -0
  39. {caption_flow-0.5.7 → caption_flow-0.6.1}/src/caption_flow/viewer.py +0 -0
  40. {caption_flow-0.5.7 → caption_flow-0.6.1}/src/caption_flow/workers/base.py +0 -0
  41. {caption_flow-0.5.7 → caption_flow-0.6.1}/src/caption_flow/workers/caption.py +0 -0
  42. {caption_flow-0.5.7 → caption_flow-0.6.1}/src/caption_flow/workers/data.py +0 -0
  43. {caption_flow-0.5.7 → caption_flow-0.6.1}/src/caption_flow/workers/openai_compatible.py +0 -0
  44. {caption_flow-0.5.7 → caption_flow-0.6.1}/src/caption_flow/workers/pipeline.py +0 -0
  45. {caption_flow-0.5.7 → caption_flow-0.6.1}/src/caption_flow.egg-info/SOURCES.txt +0 -0
  46. {caption_flow-0.5.7 → caption_flow-0.6.1}/src/caption_flow.egg-info/dependency_links.txt +0 -0
  47. {caption_flow-0.5.7 → caption_flow-0.6.1}/src/caption_flow.egg-info/entry_points.txt +0 -0
  48. {caption_flow-0.5.7 → caption_flow-0.6.1}/src/caption_flow.egg-info/top_level.txt +0 -0
  49. {caption_flow-0.5.7 → caption_flow-0.6.1}/tests/test_caption_pipeline.py +0 -0
  50. {caption_flow-0.5.7 → caption_flow-0.6.1}/tests/test_caption_utils.py +0 -0
  51. {caption_flow-0.5.7 → caption_flow-0.6.1}/tests/test_certificates.py +0 -0
  52. {caption_flow-0.5.7 → caption_flow-0.6.1}/tests/test_chunk_completion_index.py +0 -0
  53. {caption_flow-0.5.7 → caption_flow-0.6.1}/tests/test_cli.py +0 -0
  54. {caption_flow-0.5.7 → caption_flow-0.6.1}/tests/test_config_reload.py +0 -0
  55. {caption_flow-0.5.7 → caption_flow-0.6.1}/tests/test_duplicate_job_assignments.py +0 -0
  56. {caption_flow-0.5.7 → caption_flow-0.6.1}/tests/test_exporter.py +0 -0
  57. {caption_flow-0.5.7 → caption_flow-0.6.1}/tests/test_fix_verification.py +0 -0
  58. {caption_flow-0.5.7 → caption_flow-0.6.1}/tests/test_huggingface_ranges.py +0 -0
  59. {caption_flow-0.5.7 → caption_flow-0.6.1}/tests/test_image_processor.py +0 -0
  60. {caption_flow-0.5.7 → caption_flow-0.6.1}/tests/test_json_utils.py +0 -0
  61. {caption_flow-0.5.7 → caption_flow-0.6.1}/tests/test_main.py +0 -0
  62. {caption_flow-0.5.7 → caption_flow-0.6.1}/tests/test_monitor.py +0 -0
  63. {caption_flow-0.5.7 → caption_flow-0.6.1}/tests/test_openai_compatible_worker.py +0 -0
  64. {caption_flow-0.5.7 → caption_flow-0.6.1}/tests/test_orchestrator_storage_order.py +0 -0
  65. {caption_flow-0.5.7 → caption_flow-0.6.1}/tests/test_processors.py +0 -0
  66. {caption_flow-0.5.7 → caption_flow-0.6.1}/tests/test_range_level_distribution.py +0 -0
  67. {caption_flow-0.5.7 → caption_flow-0.6.1}/tests/test_result_acceptance.py +0 -0
  68. {caption_flow-0.5.7 → caption_flow-0.6.1}/tests/test_retry_queue.py +0 -0
  69. {caption_flow-0.5.7 → caption_flow-0.6.1}/tests/test_storage_components.py +0 -0
  70. {caption_flow-0.5.7 → caption_flow-0.6.1}/tests/test_unicode_utils.py +0 -0
  71. {caption_flow-0.5.7 → caption_flow-0.6.1}/tests/test_viewer.py +0 -0
  72. {caption_flow-0.5.7 → caption_flow-0.6.1}/tests/test_vllm_config.py +0 -0
  73. {caption_flow-0.5.7 → caption_flow-0.6.1}/tests/test_webdataset_cache_wait.py +0 -0
  74. {caption_flow-0.5.7 → caption_flow-0.6.1}/tests/test_webdataset_prefetch.py +0 -0
  75. {caption_flow-0.5.7 → caption_flow-0.6.1}/tests/test_webdataset_ranges.py +0 -0
  76. {caption_flow-0.5.7 → caption_flow-0.6.1}/tests/test_webshart_export_contract.py +0 -0
  77. {caption_flow-0.5.7 → caption_flow-0.6.1}/tests/test_worker_reconnection_complete.py +0 -0
  78. {caption_flow-0.5.7 → caption_flow-0.6.1}/tests/test_worker_reconnection_sequence.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: caption-flow
3
- Version: 0.5.7
3
+ Version: 0.6.1
4
4
  Summary: Self-contained distributed community captioning system
5
5
  Author: bghira
6
6
  Author-email: bghira <bghira@users.github.com>
@@ -16,82 +16,83 @@ Classifier: Programming Language :: Python :: 3.13
16
16
  Requires-Python: >=3.12,<3.14
17
17
  Description-Content-Type: text/markdown
18
18
  License-File: LICENSE
19
- Requires-Dist: websockets<17.0,>=16.0
20
- Requires-Dist: pyarrow<26.0.0,>=21.0.0
21
- Requires-Dist: click<9.0.0,>=8.2.0
22
- Requires-Dist: pydantic<3.0.0,>=2.12.0
23
- Requires-Dist: aiofiles<26.0.0,>=24.1.0
24
- Requires-Dist: rich<16.0.0,>=14.0.0
25
- Requires-Dist: cryptography<50.0.0,>=45.0.0
26
- Requires-Dist: PyYAML<7.0.0,>=6.0.2
27
- Requires-Dist: certbot<6.0.0,>=5.0.0
28
- Requires-Dist: numpy<3.0.0,>=2.2.0
29
- Requires-Dist: Pillow<13.0.0,>=11.3.0
30
- Requires-Dist: trainingsample<0.4.0,>=0.3.2
31
- Requires-Dist: pandas<4.0.0,>=3.0.0
32
- Requires-Dist: datasets<6.0.0,>=5.0.0
33
- Requires-Dist: boto3<2.0.0,>=1.43.0
34
- Requires-Dist: webshart<0.7.0,>=0.6.0
35
- Requires-Dist: pylance<9.0.0,>=8.0.0
36
- Requires-Dist: duckdb<2.0.0,>=1.5.0
37
- Requires-Dist: aiohttp<4.0.0,>=3.13.3
38
- Requires-Dist: fastapi<0.137.0,>=0.133.0
39
- Requires-Dist: uvicorn<1.0.0,>=0.35.0
40
- Requires-Dist: huggingface-hub<2.0.0,>=1.5.0
41
- Requires-Dist: psutil<8.0.0,>=7.0.0
42
- Requires-Dist: requests<3.0.0,>=2.32.0
43
- Requires-Dist: tqdm<5.0.0,>=4.67.0
44
- Requires-Dist: urwid<5.0.0,>=3.0.2
19
+ Requires-Dist: websockets<18.0,>=17.4
20
+ Requires-Dist: pyarrow<27.0.0,>=26.0.1
21
+ Requires-Dist: click<9.0.0,>=8.5.1
22
+ Requires-Dist: pydantic<3.0.0,>=2.14.3
23
+ Requires-Dist: aiofiles<26.0.0,>=25.1.0
24
+ Requires-Dist: rich<16.0.0,>=15.0.0
25
+ Requires-Dist: cryptography<51.0.0,>=50.0.2
26
+ Requires-Dist: PyYAML<7.0.0,>=6.0.3
27
+ Requires-Dist: certbot<6.0.0,>=5.10.0
28
+ Requires-Dist: numpy<2.4.0,>=2.3.5; python_version < "3.13"
29
+ Requires-Dist: numpy<2.5.0,>=2.4.6; python_version >= "3.13"
30
+ Requires-Dist: Pillow<14.0.0,>=13.0.0
31
+ Requires-Dist: trainingsample==0.4.0
32
+ Requires-Dist: pandas<4.0.0,>=3.1.1
33
+ Requires-Dist: datasets<6.0.0,>=5.2.0
34
+ Requires-Dist: boto3<2.0.0,>=1.44.3
35
+ Requires-Dist: webshart<0.8.0,>=0.7.0
36
+ Requires-Dist: pylance<9.0.0,>=8.0.1
37
+ Requires-Dist: duckdb<2.0.0,>=1.5.6
38
+ Requires-Dist: aiohttp<4.0.0,>=3.14.5
39
+ Requires-Dist: fastapi<0.137.0,>=0.136.3
40
+ Requires-Dist: uvicorn<1.0.0,>=0.54.0
41
+ Requires-Dist: huggingface-hub<2.0.0,>=1.33.0
42
+ Requires-Dist: psutil<8.0.0,>=7.2.2
43
+ Requires-Dist: requests<3.0.0,>=2.34.2
44
+ Requires-Dist: tqdm<5.0.0,>=4.70.1
45
+ Requires-Dist: urwid<6.0.0,>=5.1.3
45
46
  Provides-Extra: vllm
46
- Requires-Dist: vllm<0.32.0,>=0.31.0; extra == "vllm"
47
- Requires-Dist: torch==2.13.0; extra == "vllm"
48
- Requires-Dist: torchvision==0.28.0; extra == "vllm"
47
+ Requires-Dist: vllm<0.34.0,>=0.33.0; extra == "vllm"
48
+ Requires-Dist: torch==2.14.0; extra == "vllm"
49
+ Requires-Dist: torchvision==0.29.0; extra == "vllm"
49
50
  Requires-Dist: torchaudio==2.11.0; extra == "vllm"
50
- Requires-Dist: transformers<5.18.0,>=5.10.4; extra == "vllm"
51
+ Requires-Dist: transformers<5.21.0,>=5.16.1; extra == "vllm"
51
52
  Requires-Dist: qwen-vl-utils<0.1.0,>=0.0.14; extra == "vllm"
52
53
  Provides-Extra: captioning
53
- Requires-Dist: vllm<0.32.0,>=0.31.0; extra == "captioning"
54
- Requires-Dist: torch==2.13.0; extra == "captioning"
55
- Requires-Dist: torchvision==0.28.0; extra == "captioning"
54
+ Requires-Dist: vllm<0.34.0,>=0.33.0; extra == "captioning"
55
+ Requires-Dist: torch==2.14.0; extra == "captioning"
56
+ Requires-Dist: torchvision==0.29.0; extra == "captioning"
56
57
  Requires-Dist: torchaudio==2.11.0; extra == "captioning"
57
- Requires-Dist: transformers<5.18.0,>=5.10.4; extra == "captioning"
58
+ Requires-Dist: transformers<5.21.0,>=5.16.1; extra == "captioning"
58
59
  Requires-Dist: qwen-vl-utils<0.1.0,>=0.0.14; extra == "captioning"
59
60
  Provides-Extra: openai
60
61
  Provides-Extra: cpu
61
- Requires-Dist: torch>=2.13.0; extra == "cpu"
62
- Requires-Dist: torchvision>=0.28.0; extra == "cpu"
62
+ Requires-Dist: torch>=2.14.0; extra == "cpu"
63
+ Requires-Dist: torchvision>=0.29.0; extra == "cpu"
63
64
  Requires-Dist: torchaudio>=2.11.0; extra == "cpu"
64
65
  Provides-Extra: cuda
65
- Requires-Dist: torch>=2.13.0; extra == "cuda"
66
- Requires-Dist: torchvision>=0.28.0; extra == "cuda"
66
+ Requires-Dist: torch>=2.14.0; extra == "cuda"
67
+ Requires-Dist: torchvision>=0.29.0; extra == "cuda"
67
68
  Requires-Dist: torchaudio>=2.11.0; extra == "cuda"
68
69
  Provides-Extra: cuda13
69
- Requires-Dist: torch>=2.13.0; extra == "cuda13"
70
- Requires-Dist: torchvision>=0.28.0; extra == "cuda13"
70
+ Requires-Dist: torch>=2.14.0; extra == "cuda13"
71
+ Requires-Dist: torchvision>=0.29.0; extra == "cuda13"
71
72
  Requires-Dist: torchaudio>=2.11.0; extra == "cuda13"
72
73
  Provides-Extra: rocm
73
- Requires-Dist: torch>=2.13.0; extra == "rocm"
74
- Requires-Dist: torchvision>=0.28.0; extra == "rocm"
74
+ Requires-Dist: torch>=2.14.0; extra == "rocm"
75
+ Requires-Dist: torchvision>=0.29.0; extra == "rocm"
75
76
  Requires-Dist: torchaudio>=2.11.0; extra == "rocm"
76
77
  Provides-Extra: apple
77
- Requires-Dist: torch>=2.13.0; extra == "apple"
78
- Requires-Dist: torchvision>=0.28.0; extra == "apple"
78
+ Requires-Dist: torch>=2.14.0; extra == "apple"
79
+ Requires-Dist: torchvision>=0.29.0; extra == "apple"
79
80
  Requires-Dist: torchaudio>=2.11.0; extra == "apple"
80
- Requires-Dist: vllm-metal==0.1.0; (platform_system == "Darwin" and platform_machine == "arm64" and python_version >= "3.12") and extra == "apple"
81
+ Requires-Dist: qwen-vl-utils<0.1.0,>=0.0.14; extra == "apple"
81
82
  Provides-Extra: dev
82
- Requires-Dist: pytest<9.0.0,>=8.0.0; extra == "dev"
83
- Requires-Dist: pytest-asyncio<2.0.0,>=1.1.0; extra == "dev"
84
- Requires-Dist: pytest-cov<7.0.0,>=6.0.0; extra == "dev"
85
- Requires-Dist: transformers<5.18.0,>=5.10.4; extra == "dev"
86
- Requires-Dist: black<26.0.0,>=25.0.0; extra == "dev"
87
- Requires-Dist: ruff<1.0.0,>=0.12.0; extra == "dev"
88
- Requires-Dist: mypy<2.0.0,>=1.17.0; extra == "dev"
83
+ Requires-Dist: pytest<10.0.0,>=9.2.0; extra == "dev"
84
+ Requires-Dist: pytest-asyncio<2.0.0,>=1.5.0; extra == "dev"
85
+ Requires-Dist: pytest-cov<8.0.0,>=7.1.0; extra == "dev"
86
+ Requires-Dist: transformers<5.21.0,>=5.16.1; extra == "dev"
87
+ Requires-Dist: black<27.0.0,>=26.10.1; extra == "dev"
88
+ Requires-Dist: ruff<1.0.0,>=0.17.5; extra == "dev"
89
+ Requires-Dist: mypy<3.0.0,>=2.4.1; extra == "dev"
89
90
  Provides-Extra: all
90
- Requires-Dist: vllm<0.32.0,>=0.31.0; extra == "all"
91
- Requires-Dist: torch==2.13.0; extra == "all"
92
- Requires-Dist: torchvision==0.28.0; extra == "all"
91
+ Requires-Dist: vllm<0.34.0,>=0.33.0; extra == "all"
92
+ Requires-Dist: torch==2.14.0; extra == "all"
93
+ Requires-Dist: torchvision==0.29.0; extra == "all"
93
94
  Requires-Dist: torchaudio==2.11.0; extra == "all"
94
- Requires-Dist: transformers<5.18.0,>=5.10.4; extra == "all"
95
+ Requires-Dist: transformers<5.21.0,>=5.16.1; extra == "all"
95
96
  Requires-Dist: qwen-vl-utils<0.1.0,>=0.0.14; extra == "all"
96
97
  Dynamic: author
97
98
  Dynamic: license-file
@@ -128,11 +129,18 @@ pip install --upgrade pip
128
129
  pip install "caption-flow[vllm]"
129
130
  ```
130
131
 
131
- The Linux GPU worker extra targets vLLM 0.31.x with PyTorch 2.13.0,
132
- torchvision 0.28.0, and torchaudio 2.11.0 (as required by vLLM), plus
133
- Transformers 5.10.4–5.17.x. To upgrade an existing worker from a checkout,
132
+ The Linux GPU worker extra targets vLLM 0.33.x with PyTorch 2.14.0,
133
+ torchvision 0.29.0, and torchaudio 2.11.0 (as required by vLLM), plus
134
+ Transformers 5.16.1–5.20.x and Pillow 13. To upgrade an existing worker from a checkout,
134
135
  run `pip install --upgrade -e ".[vllm]"` in its environment and restart it.
135
136
 
137
+ The tested worker stack uses NumPy 2.3.x on Python 3.12 and 2.4.x
138
+ on Python 3.13, and FastAPI below 0.137. These bounds are shared with the
139
+ base install so adding the worker extra remains compatible. CI resolves
140
+ the full Linux worker and development dependencies on both Python versions.
141
+ Lance 8.x, DuckDB 1.x, and Hugging Face Hub 1.x remain bounded to their
142
+ existing major versions pending separate migration testing.
143
+
136
144
  An OpenAI-compatible API worker does not need the GPU dependencies:
137
145
 
138
146
  ```bash
@@ -144,26 +152,36 @@ For an orchestrator or monitor-only install, use `pip install -e .`.
144
152
  SimpleTuner. Terminal image previews remain optional because the current
145
153
  `term-image` release requires an older Pillow major than CaptionFlow uses.
146
154
 
147
- On Apple Silicon, install the MPS-compatible PyTorch chain and pinned Metal
148
- plugin with:
155
+ On Apple Silicon with macOS 14 or newer, install the MPS-compatible PyTorch
156
+ chain and image utilities with:
149
157
 
150
158
  ```bash
151
159
  pip install -e ".[apple]"
152
160
  ```
153
161
 
154
- CaptionFlow can use vLLM on Apple Silicon too, but the normal Linux `vllm`
155
- wheel is not the Apple install path. The pinned `vllm-metal` dependency is
156
- selected automatically on native arm64 Python 3.12+. For a ready-to-run
157
- Metal worker, use the upstream installer, which also builds/installs the
158
- Apple-specific vLLM core:
162
+ For native vLLM Metal captioning, use **macOS 15+, Apple Silicon, and Python
163
+ 3.12**. The current Metal wheels are published on
164
+ [GitHub releases](https://github.com/vllm-project/vllm-metal/releases), while
165
+ PyPI still carries the obsolete 0.1.0 plugin. From this checkout, install the
166
+ matching stable vLLM 0.33.0 core and Metal 0.33.0 wheels into your environment:
159
167
 
160
168
  ```bash
161
- curl -fsSL https://raw.githubusercontent.com/vllm-project/vllm-metal/main/install.sh | bash
162
- source ~/.venv-vllm-metal/bin/activate
163
- pip install -e .
169
+ python -m pip install --upgrade -r requirements.metal.txt
170
+ python -m pip install -e ".[dev]"
171
+ python -m pip check
172
+ python examples/metal_smoke.py
164
173
  ```
165
174
 
166
- Do not combine `.[apple]` with the Linux `.[vllm]` extra.
175
+ The smoke test downloads `mlx-community/Qwen3-VL-2B-Instruct-4bit` on first
176
+ use and runs two images through CaptionFlow's native caption pipeline. It
177
+ checks that the Metal plugin and MLX GPU are active, and that the captions
178
+ identify the images' shapes and different colors. Pass `--model /path/to/model`
179
+ to use a local checkpoint. The test does not connect to an orchestrator.
180
+
181
+ The stable recipe uses the core wheel's PyTorch 2.14.0 pin. Upstream's installer
182
+ can select newer development builds and override Torch with nightly packages;
183
+ those are separate from this recipe. `.[apple]` alone does not install a vLLM
184
+ runtime, and should not be combined with the Linux `.[vllm]` extra.
167
185
 
168
186
  For native macOS CPU vLLM instead, follow the
169
187
  [official source-build instructions](https://docs.vllm.ai/en/stable/getting_started/installation/cpu/?device=apple).
@@ -225,7 +243,7 @@ Options:
225
243
  * **csv**: exports CSV-compatible data columns to the `--output` path containing incomplete metadata
226
244
  * **json**: creates a `.json` file for each sample inside the `--output` subdirectory containing **complete** metadata; useful for webdatasets
227
245
  * **txt**: creates `.txt` file for each sample inside the `--output` subdirectory containing ONLY captions
228
- * **webshart**: updates an **existing per-shard metadata `.json` file** by writing captions under the plural `captions` key. Strings, native JSON objects, and mixed lists are supported. JSON objects stored as text in Lance output columns are decoded during export, preserving nested values instead of writing Python dictionary representations. Native objects supplied through `Caption.outputs` are encoded as JSON only for Lance persistence. Requires webshart 0.6.0 or newer for native JSON caption support (included in the base dependencies). For this format, pass `--output` as the path to the existing shard metadata JSON file when exporting one shard. If you export multiple shards, pass `--output` as a directory containing one existing `{shard_name}.json` file per shard.
246
+ * **webshart**: updates an **existing per-shard metadata `.json` file** by writing captions under the plural `captions` key. Strings, native JSON objects, and mixed lists are supported. JSON objects stored as text in Lance output columns are decoded during export, preserving nested values instead of writing Python dictionary representations. Native objects supplied through `Caption.outputs` are encoded as JSON only for Lance persistence. Requires webshart 0.7.x (included in the base dependencies), including native JSON caption support. For this format, pass `--output` as the path to the existing shard metadata JSON file when exporting one shard. If you export multiple shards, pass `--output` as a directory containing one existing `{shard_name}.json` file per shard.
229
247
  * **huggingface_hub**: creates a dataset on Hugging Face Hub, possibly `--private` and `--nsfw` where necessary
230
248
  * **all**: creates the directory/file-generating export formats in a specified `--output` directory. prefer a directory here; `webshart` is a special case that expects existing per-shard metadata `.json` files rather than creating new metadata files.
231
249
 
@@ -27,11 +27,18 @@ pip install --upgrade pip
27
27
  pip install "caption-flow[vllm]"
28
28
  ```
29
29
 
30
- The Linux GPU worker extra targets vLLM 0.31.x with PyTorch 2.13.0,
31
- torchvision 0.28.0, and torchaudio 2.11.0 (as required by vLLM), plus
32
- Transformers 5.10.4–5.17.x. To upgrade an existing worker from a checkout,
30
+ The Linux GPU worker extra targets vLLM 0.33.x with PyTorch 2.14.0,
31
+ torchvision 0.29.0, and torchaudio 2.11.0 (as required by vLLM), plus
32
+ Transformers 5.16.1–5.20.x and Pillow 13. To upgrade an existing worker from a checkout,
33
33
  run `pip install --upgrade -e ".[vllm]"` in its environment and restart it.
34
34
 
35
+ The tested worker stack uses NumPy 2.3.x on Python 3.12 and 2.4.x
36
+ on Python 3.13, and FastAPI below 0.137. These bounds are shared with the
37
+ base install so adding the worker extra remains compatible. CI resolves
38
+ the full Linux worker and development dependencies on both Python versions.
39
+ Lance 8.x, DuckDB 1.x, and Hugging Face Hub 1.x remain bounded to their
40
+ existing major versions pending separate migration testing.
41
+
35
42
  An OpenAI-compatible API worker does not need the GPU dependencies:
36
43
 
37
44
  ```bash
@@ -43,26 +50,36 @@ For an orchestrator or monitor-only install, use `pip install -e .`.
43
50
  SimpleTuner. Terminal image previews remain optional because the current
44
51
  `term-image` release requires an older Pillow major than CaptionFlow uses.
45
52
 
46
- On Apple Silicon, install the MPS-compatible PyTorch chain and pinned Metal
47
- plugin with:
53
+ On Apple Silicon with macOS 14 or newer, install the MPS-compatible PyTorch
54
+ chain and image utilities with:
48
55
 
49
56
  ```bash
50
57
  pip install -e ".[apple]"
51
58
  ```
52
59
 
53
- CaptionFlow can use vLLM on Apple Silicon too, but the normal Linux `vllm`
54
- wheel is not the Apple install path. The pinned `vllm-metal` dependency is
55
- selected automatically on native arm64 Python 3.12+. For a ready-to-run
56
- Metal worker, use the upstream installer, which also builds/installs the
57
- Apple-specific vLLM core:
60
+ For native vLLM Metal captioning, use **macOS 15+, Apple Silicon, and Python
61
+ 3.12**. The current Metal wheels are published on
62
+ [GitHub releases](https://github.com/vllm-project/vllm-metal/releases), while
63
+ PyPI still carries the obsolete 0.1.0 plugin. From this checkout, install the
64
+ matching stable vLLM 0.33.0 core and Metal 0.33.0 wheels into your environment:
58
65
 
59
66
  ```bash
60
- curl -fsSL https://raw.githubusercontent.com/vllm-project/vllm-metal/main/install.sh | bash
61
- source ~/.venv-vllm-metal/bin/activate
62
- pip install -e .
67
+ python -m pip install --upgrade -r requirements.metal.txt
68
+ python -m pip install -e ".[dev]"
69
+ python -m pip check
70
+ python examples/metal_smoke.py
63
71
  ```
64
72
 
65
- Do not combine `.[apple]` with the Linux `.[vllm]` extra.
73
+ The smoke test downloads `mlx-community/Qwen3-VL-2B-Instruct-4bit` on first
74
+ use and runs two images through CaptionFlow's native caption pipeline. It
75
+ checks that the Metal plugin and MLX GPU are active, and that the captions
76
+ identify the images' shapes and different colors. Pass `--model /path/to/model`
77
+ to use a local checkpoint. The test does not connect to an orchestrator.
78
+
79
+ The stable recipe uses the core wheel's PyTorch 2.14.0 pin. Upstream's installer
80
+ can select newer development builds and override Torch with nightly packages;
81
+ those are separate from this recipe. `.[apple]` alone does not install a vLLM
82
+ runtime, and should not be combined with the Linux `.[vllm]` extra.
66
83
 
67
84
  For native macOS CPU vLLM instead, follow the
68
85
  [official source-build instructions](https://docs.vllm.ai/en/stable/getting_started/installation/cpu/?device=apple).
@@ -124,7 +141,7 @@ Options:
124
141
  * **csv**: exports CSV-compatible data columns to the `--output` path containing incomplete metadata
125
142
  * **json**: creates a `.json` file for each sample inside the `--output` subdirectory containing **complete** metadata; useful for webdatasets
126
143
  * **txt**: creates `.txt` file for each sample inside the `--output` subdirectory containing ONLY captions
127
- * **webshart**: updates an **existing per-shard metadata `.json` file** by writing captions under the plural `captions` key. Strings, native JSON objects, and mixed lists are supported. JSON objects stored as text in Lance output columns are decoded during export, preserving nested values instead of writing Python dictionary representations. Native objects supplied through `Caption.outputs` are encoded as JSON only for Lance persistence. Requires webshart 0.6.0 or newer for native JSON caption support (included in the base dependencies). For this format, pass `--output` as the path to the existing shard metadata JSON file when exporting one shard. If you export multiple shards, pass `--output` as a directory containing one existing `{shard_name}.json` file per shard.
144
+ * **webshart**: updates an **existing per-shard metadata `.json` file** by writing captions under the plural `captions` key. Strings, native JSON objects, and mixed lists are supported. JSON objects stored as text in Lance output columns are decoded during export, preserving nested values instead of writing Python dictionary representations. Native objects supplied through `Caption.outputs` are encoded as JSON only for Lance persistence. Requires webshart 0.7.x (included in the base dependencies), including native JSON caption support. For this format, pass `--output` as the path to the existing shard metadata JSON file when exporting one shard. If you export multiple shards, pass `--output` as a directory containing one existing `{shard_name}.json` file per shard.
128
145
  * **huggingface_hub**: creates a dataset on Hugging Face Hub, possibly `--private` and `--nsfw` where necessary
129
146
  * **all**: creates the directory/file-generating export formats in a specified `--output` directory. prefer a directory here; `webshart` is a special case that expects existing per-shard metadata `.json` files rather than creating new metadata files.
130
147
 
@@ -1,5 +1,5 @@
1
1
  [build-system]
2
- requires = ["setuptools>=68.0.0", "wheel"]
2
+ requires = ["setuptools>=77.0.3", "wheel"]
3
3
  build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
@@ -23,58 +23,61 @@ def get_version() -> str:
23
23
 
24
24
 
25
25
  base_deps = [
26
- "websockets>=16.0,<17.0",
27
- "pyarrow>=21.0.0,<26.0.0",
28
- "click>=8.2.0,<9.0.0",
29
- "pydantic>=2.12.0,<3.0.0",
30
- "aiofiles>=24.1.0,<26.0.0",
31
- "rich>=14.0.0,<16.0.0",
32
- "cryptography>=45.0.0,<50.0.0",
33
- "PyYAML>=6.0.2,<7.0.0",
34
- "certbot>=5.0.0,<6.0.0",
35
- "numpy>=2.2.0,<3.0.0",
36
- "Pillow>=11.3.0,<13.0.0",
37
- "trainingsample>=0.3.2,<0.4.0",
38
- "pandas>=3.0.0,<4.0.0",
39
- "datasets>=5.0.0,<6.0.0",
40
- "boto3>=1.43.0,<2.0.0",
41
- "webshart>=0.6.0,<0.7.0",
42
- "pylance>=8.0.0,<9.0.0",
43
- "duckdb>=1.5.0,<2.0.0",
44
- "aiohttp>=3.13.3,<4.0.0",
45
- "fastapi>=0.133.0,<0.137.0",
46
- "uvicorn>=0.35.0,<1.0.0",
47
- "huggingface-hub>=1.5.0,<2.0.0",
48
- "psutil>=7.0.0,<8.0.0",
49
- "requests>=2.32.0,<3.0.0",
50
- "tqdm>=4.67.0,<5.0.0",
51
- "urwid>=3.0.2,<5.0.0",
26
+ "websockets>=17.4,<18.0",
27
+ "pyarrow>=26.0.1,<27.0.0",
28
+ "click>=8.5.1,<9.0.0",
29
+ "pydantic>=2.14.3,<3.0.0",
30
+ "aiofiles>=25.1.0,<26.0.0",
31
+ "rich>=15.0.0,<16.0.0",
32
+ "cryptography>=50.0.2,<51.0.0",
33
+ "PyYAML>=6.0.3,<7.0.0",
34
+ "certbot>=5.10.0,<6.0.0",
35
+ # vLLM's mistral-common requires NumPy <2.4 on Python 3.12;
36
+ # its pinned numba 0.65 requires NumPy <2.5 on Python 3.13.
37
+ "numpy>=2.3.5,<2.4.0; python_version < '3.13'",
38
+ "numpy>=2.4.6,<2.5.0; python_version >= '3.13'",
39
+ "Pillow>=13.0.0,<14.0.0",
40
+ "trainingsample==0.4.0",
41
+ "pandas>=3.1.1,<4.0.0",
42
+ "datasets>=5.2.0,<6.0.0",
43
+ "boto3>=1.44.3,<2.0.0",
44
+ "webshart>=0.7.0,<0.8.0",
45
+ "pylance>=8.0.1,<9.0.0",
46
+ "duckdb>=1.5.6,<2.0.0",
47
+ "aiohttp>=3.14.5,<4.0.0",
48
+ # vLLM 0.33 requires FastAPI below 0.137.
49
+ "fastapi>=0.136.3,<0.137.0",
50
+ "uvicorn>=0.54.0,<1.0.0",
51
+ "huggingface-hub>=1.33.0,<2.0.0",
52
+ "psutil>=7.2.2,<8.0.0",
53
+ "requests>=2.34.2,<3.0.0",
54
+ "tqdm>=4.70.1,<5.0.0",
55
+ "urwid>=5.1.3,<6.0.0",
52
56
  ]
53
57
 
54
- # Match vLLM 0.31's published requirements, including torchaudio 2.11.0.
58
+ # Match vLLM 0.33's published requirements, including torchaudio 2.11.0.
55
59
  # Keep these explicit so a worker install cannot silently combine incompatible
56
60
  # torch packages when another dependency broadens its requirements.
57
61
  vllm_deps = [
58
- "vllm>=0.31.0,<0.32.0",
59
- "torch==2.13.0",
60
- "torchvision==0.28.0",
62
+ "vllm>=0.33.0,<0.34.0",
63
+ "torch==2.14.0",
64
+ "torchvision==0.29.0",
61
65
  "torchaudio==2.11.0",
62
- "transformers>=5.10.4,<5.18.0",
66
+ "transformers>=5.16.1,<5.21.0",
63
67
  "qwen-vl-utils>=0.0.14,<0.1.0",
64
68
  ]
65
69
 
66
70
  PYTORCH_DEPENDENCIES = [
67
- "torch>=2.13.0",
68
- "torchvision>=0.28.0",
71
+ "torch>=2.14.0",
72
+ "torchvision>=0.29.0",
69
73
  "torchaudio>=2.11.0",
70
74
  ]
71
75
 
72
76
  APPLE_PYTORCH_DEPENDENCIES = [
73
- "torch>=2.13.0",
74
- "torchvision>=0.28.0",
75
- "torchaudio>=2.11.0",
76
- # vLLM Metal publishes Apple Silicon wheels for Python 3.12+.
77
- "vllm-metal==0.1.0; platform_system == 'Darwin' and platform_machine == 'arm64' and python_version >= '3.12'",
77
+ *PYTORCH_DEPENDENCIES,
78
+ "qwen-vl-utils>=0.0.14,<0.1.0",
79
+ # Install the matching vLLM core and Metal wheels from upstream GitHub
80
+ # releases separately; PyPI's vllm-metal 0.1.0 is obsolete.
78
81
  ]
79
82
 
80
83
  extras_require = {
@@ -89,13 +92,13 @@ extras_require = {
89
92
  "rocm": PYTORCH_DEPENDENCIES,
90
93
  "apple": APPLE_PYTORCH_DEPENDENCIES,
91
94
  "dev": [
92
- "pytest>=8.0.0,<9.0.0",
93
- "pytest-asyncio>=1.1.0,<2.0.0",
94
- "pytest-cov>=6.0.0,<7.0.0",
95
- "transformers>=5.10.4,<5.18.0",
96
- "black>=25.0.0,<26.0.0",
97
- "ruff>=0.12.0,<1.0.0",
98
- "mypy>=1.17.0,<2.0.0",
95
+ "pytest>=9.2.0,<10.0.0",
96
+ "pytest-asyncio>=1.5.0,<2.0.0",
97
+ "pytest-cov>=7.1.0,<8.0.0",
98
+ "transformers>=5.16.1,<5.21.0",
99
+ "black>=26.10.1,<27.0.0",
100
+ "ruff>=0.17.5,<1.0.0",
101
+ "mypy>=2.4.1,<3.0.0",
99
102
  ],
100
103
  "all": [*vllm_deps],
101
104
  }
@@ -1,6 +1,6 @@
1
1
  """CaptionFlow - Distributed community captioning system."""
2
2
 
3
- __version__ = "0.5.7"
3
+ __version__ = "0.6.1"
4
4
 
5
5
  from .monitor import Monitor
6
6
  from .orchestrator import Orchestrator
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: caption-flow
3
- Version: 0.5.7
3
+ Version: 0.6.1
4
4
  Summary: Self-contained distributed community captioning system
5
5
  Author: bghira
6
6
  Author-email: bghira <bghira@users.github.com>
@@ -16,82 +16,83 @@ Classifier: Programming Language :: Python :: 3.13
16
16
  Requires-Python: >=3.12,<3.14
17
17
  Description-Content-Type: text/markdown
18
18
  License-File: LICENSE
19
- Requires-Dist: websockets<17.0,>=16.0
20
- Requires-Dist: pyarrow<26.0.0,>=21.0.0
21
- Requires-Dist: click<9.0.0,>=8.2.0
22
- Requires-Dist: pydantic<3.0.0,>=2.12.0
23
- Requires-Dist: aiofiles<26.0.0,>=24.1.0
24
- Requires-Dist: rich<16.0.0,>=14.0.0
25
- Requires-Dist: cryptography<50.0.0,>=45.0.0
26
- Requires-Dist: PyYAML<7.0.0,>=6.0.2
27
- Requires-Dist: certbot<6.0.0,>=5.0.0
28
- Requires-Dist: numpy<3.0.0,>=2.2.0
29
- Requires-Dist: Pillow<13.0.0,>=11.3.0
30
- Requires-Dist: trainingsample<0.4.0,>=0.3.2
31
- Requires-Dist: pandas<4.0.0,>=3.0.0
32
- Requires-Dist: datasets<6.0.0,>=5.0.0
33
- Requires-Dist: boto3<2.0.0,>=1.43.0
34
- Requires-Dist: webshart<0.7.0,>=0.6.0
35
- Requires-Dist: pylance<9.0.0,>=8.0.0
36
- Requires-Dist: duckdb<2.0.0,>=1.5.0
37
- Requires-Dist: aiohttp<4.0.0,>=3.13.3
38
- Requires-Dist: fastapi<0.137.0,>=0.133.0
39
- Requires-Dist: uvicorn<1.0.0,>=0.35.0
40
- Requires-Dist: huggingface-hub<2.0.0,>=1.5.0
41
- Requires-Dist: psutil<8.0.0,>=7.0.0
42
- Requires-Dist: requests<3.0.0,>=2.32.0
43
- Requires-Dist: tqdm<5.0.0,>=4.67.0
44
- Requires-Dist: urwid<5.0.0,>=3.0.2
19
+ Requires-Dist: websockets<18.0,>=17.4
20
+ Requires-Dist: pyarrow<27.0.0,>=26.0.1
21
+ Requires-Dist: click<9.0.0,>=8.5.1
22
+ Requires-Dist: pydantic<3.0.0,>=2.14.3
23
+ Requires-Dist: aiofiles<26.0.0,>=25.1.0
24
+ Requires-Dist: rich<16.0.0,>=15.0.0
25
+ Requires-Dist: cryptography<51.0.0,>=50.0.2
26
+ Requires-Dist: PyYAML<7.0.0,>=6.0.3
27
+ Requires-Dist: certbot<6.0.0,>=5.10.0
28
+ Requires-Dist: numpy<2.4.0,>=2.3.5; python_version < "3.13"
29
+ Requires-Dist: numpy<2.5.0,>=2.4.6; python_version >= "3.13"
30
+ Requires-Dist: Pillow<14.0.0,>=13.0.0
31
+ Requires-Dist: trainingsample==0.4.0
32
+ Requires-Dist: pandas<4.0.0,>=3.1.1
33
+ Requires-Dist: datasets<6.0.0,>=5.2.0
34
+ Requires-Dist: boto3<2.0.0,>=1.44.3
35
+ Requires-Dist: webshart<0.8.0,>=0.7.0
36
+ Requires-Dist: pylance<9.0.0,>=8.0.1
37
+ Requires-Dist: duckdb<2.0.0,>=1.5.6
38
+ Requires-Dist: aiohttp<4.0.0,>=3.14.5
39
+ Requires-Dist: fastapi<0.137.0,>=0.136.3
40
+ Requires-Dist: uvicorn<1.0.0,>=0.54.0
41
+ Requires-Dist: huggingface-hub<2.0.0,>=1.33.0
42
+ Requires-Dist: psutil<8.0.0,>=7.2.2
43
+ Requires-Dist: requests<3.0.0,>=2.34.2
44
+ Requires-Dist: tqdm<5.0.0,>=4.70.1
45
+ Requires-Dist: urwid<6.0.0,>=5.1.3
45
46
  Provides-Extra: vllm
46
- Requires-Dist: vllm<0.32.0,>=0.31.0; extra == "vllm"
47
- Requires-Dist: torch==2.13.0; extra == "vllm"
48
- Requires-Dist: torchvision==0.28.0; extra == "vllm"
47
+ Requires-Dist: vllm<0.34.0,>=0.33.0; extra == "vllm"
48
+ Requires-Dist: torch==2.14.0; extra == "vllm"
49
+ Requires-Dist: torchvision==0.29.0; extra == "vllm"
49
50
  Requires-Dist: torchaudio==2.11.0; extra == "vllm"
50
- Requires-Dist: transformers<5.18.0,>=5.10.4; extra == "vllm"
51
+ Requires-Dist: transformers<5.21.0,>=5.16.1; extra == "vllm"
51
52
  Requires-Dist: qwen-vl-utils<0.1.0,>=0.0.14; extra == "vllm"
52
53
  Provides-Extra: captioning
53
- Requires-Dist: vllm<0.32.0,>=0.31.0; extra == "captioning"
54
- Requires-Dist: torch==2.13.0; extra == "captioning"
55
- Requires-Dist: torchvision==0.28.0; extra == "captioning"
54
+ Requires-Dist: vllm<0.34.0,>=0.33.0; extra == "captioning"
55
+ Requires-Dist: torch==2.14.0; extra == "captioning"
56
+ Requires-Dist: torchvision==0.29.0; extra == "captioning"
56
57
  Requires-Dist: torchaudio==2.11.0; extra == "captioning"
57
- Requires-Dist: transformers<5.18.0,>=5.10.4; extra == "captioning"
58
+ Requires-Dist: transformers<5.21.0,>=5.16.1; extra == "captioning"
58
59
  Requires-Dist: qwen-vl-utils<0.1.0,>=0.0.14; extra == "captioning"
59
60
  Provides-Extra: openai
60
61
  Provides-Extra: cpu
61
- Requires-Dist: torch>=2.13.0; extra == "cpu"
62
- Requires-Dist: torchvision>=0.28.0; extra == "cpu"
62
+ Requires-Dist: torch>=2.14.0; extra == "cpu"
63
+ Requires-Dist: torchvision>=0.29.0; extra == "cpu"
63
64
  Requires-Dist: torchaudio>=2.11.0; extra == "cpu"
64
65
  Provides-Extra: cuda
65
- Requires-Dist: torch>=2.13.0; extra == "cuda"
66
- Requires-Dist: torchvision>=0.28.0; extra == "cuda"
66
+ Requires-Dist: torch>=2.14.0; extra == "cuda"
67
+ Requires-Dist: torchvision>=0.29.0; extra == "cuda"
67
68
  Requires-Dist: torchaudio>=2.11.0; extra == "cuda"
68
69
  Provides-Extra: cuda13
69
- Requires-Dist: torch>=2.13.0; extra == "cuda13"
70
- Requires-Dist: torchvision>=0.28.0; extra == "cuda13"
70
+ Requires-Dist: torch>=2.14.0; extra == "cuda13"
71
+ Requires-Dist: torchvision>=0.29.0; extra == "cuda13"
71
72
  Requires-Dist: torchaudio>=2.11.0; extra == "cuda13"
72
73
  Provides-Extra: rocm
73
- Requires-Dist: torch>=2.13.0; extra == "rocm"
74
- Requires-Dist: torchvision>=0.28.0; extra == "rocm"
74
+ Requires-Dist: torch>=2.14.0; extra == "rocm"
75
+ Requires-Dist: torchvision>=0.29.0; extra == "rocm"
75
76
  Requires-Dist: torchaudio>=2.11.0; extra == "rocm"
76
77
  Provides-Extra: apple
77
- Requires-Dist: torch>=2.13.0; extra == "apple"
78
- Requires-Dist: torchvision>=0.28.0; extra == "apple"
78
+ Requires-Dist: torch>=2.14.0; extra == "apple"
79
+ Requires-Dist: torchvision>=0.29.0; extra == "apple"
79
80
  Requires-Dist: torchaudio>=2.11.0; extra == "apple"
80
- Requires-Dist: vllm-metal==0.1.0; (platform_system == "Darwin" and platform_machine == "arm64" and python_version >= "3.12") and extra == "apple"
81
+ Requires-Dist: qwen-vl-utils<0.1.0,>=0.0.14; extra == "apple"
81
82
  Provides-Extra: dev
82
- Requires-Dist: pytest<9.0.0,>=8.0.0; extra == "dev"
83
- Requires-Dist: pytest-asyncio<2.0.0,>=1.1.0; extra == "dev"
84
- Requires-Dist: pytest-cov<7.0.0,>=6.0.0; extra == "dev"
85
- Requires-Dist: transformers<5.18.0,>=5.10.4; extra == "dev"
86
- Requires-Dist: black<26.0.0,>=25.0.0; extra == "dev"
87
- Requires-Dist: ruff<1.0.0,>=0.12.0; extra == "dev"
88
- Requires-Dist: mypy<2.0.0,>=1.17.0; extra == "dev"
83
+ Requires-Dist: pytest<10.0.0,>=9.2.0; extra == "dev"
84
+ Requires-Dist: pytest-asyncio<2.0.0,>=1.5.0; extra == "dev"
85
+ Requires-Dist: pytest-cov<8.0.0,>=7.1.0; extra == "dev"
86
+ Requires-Dist: transformers<5.21.0,>=5.16.1; extra == "dev"
87
+ Requires-Dist: black<27.0.0,>=26.10.1; extra == "dev"
88
+ Requires-Dist: ruff<1.0.0,>=0.17.5; extra == "dev"
89
+ Requires-Dist: mypy<3.0.0,>=2.4.1; extra == "dev"
89
90
  Provides-Extra: all
90
- Requires-Dist: vllm<0.32.0,>=0.31.0; extra == "all"
91
- Requires-Dist: torch==2.13.0; extra == "all"
92
- Requires-Dist: torchvision==0.28.0; extra == "all"
91
+ Requires-Dist: vllm<0.34.0,>=0.33.0; extra == "all"
92
+ Requires-Dist: torch==2.14.0; extra == "all"
93
+ Requires-Dist: torchvision==0.29.0; extra == "all"
93
94
  Requires-Dist: torchaudio==2.11.0; extra == "all"
94
- Requires-Dist: transformers<5.18.0,>=5.10.4; extra == "all"
95
+ Requires-Dist: transformers<5.21.0,>=5.16.1; extra == "all"
95
96
  Requires-Dist: qwen-vl-utils<0.1.0,>=0.0.14; extra == "all"
96
97
  Dynamic: author
97
98
  Dynamic: license-file
@@ -128,11 +129,18 @@ pip install --upgrade pip
128
129
  pip install "caption-flow[vllm]"
129
130
  ```
130
131
 
131
- The Linux GPU worker extra targets vLLM 0.31.x with PyTorch 2.13.0,
132
- torchvision 0.28.0, and torchaudio 2.11.0 (as required by vLLM), plus
133
- Transformers 5.10.4–5.17.x. To upgrade an existing worker from a checkout,
132
+ The Linux GPU worker extra targets vLLM 0.33.x with PyTorch 2.14.0,
133
+ torchvision 0.29.0, and torchaudio 2.11.0 (as required by vLLM), plus
134
+ Transformers 5.16.1–5.20.x and Pillow 13. To upgrade an existing worker from a checkout,
134
135
  run `pip install --upgrade -e ".[vllm]"` in its environment and restart it.
135
136
 
137
+ The tested worker stack uses NumPy 2.3.x on Python 3.12 and 2.4.x
138
+ on Python 3.13, and FastAPI below 0.137. These bounds are shared with the
139
+ base install so adding the worker extra remains compatible. CI resolves
140
+ the full Linux worker and development dependencies on both Python versions.
141
+ Lance 8.x, DuckDB 1.x, and Hugging Face Hub 1.x remain bounded to their
142
+ existing major versions pending separate migration testing.
143
+
136
144
  An OpenAI-compatible API worker does not need the GPU dependencies:
137
145
 
138
146
  ```bash
@@ -144,26 +152,36 @@ For an orchestrator or monitor-only install, use `pip install -e .`.
144
152
  SimpleTuner. Terminal image previews remain optional because the current
145
153
  `term-image` release requires an older Pillow major than CaptionFlow uses.
146
154
 
147
- On Apple Silicon, install the MPS-compatible PyTorch chain and pinned Metal
148
- plugin with:
155
+ On Apple Silicon with macOS 14 or newer, install the MPS-compatible PyTorch
156
+ chain and image utilities with:
149
157
 
150
158
  ```bash
151
159
  pip install -e ".[apple]"
152
160
  ```
153
161
 
154
- CaptionFlow can use vLLM on Apple Silicon too, but the normal Linux `vllm`
155
- wheel is not the Apple install path. The pinned `vllm-metal` dependency is
156
- selected automatically on native arm64 Python 3.12+. For a ready-to-run
157
- Metal worker, use the upstream installer, which also builds/installs the
158
- Apple-specific vLLM core:
162
+ For native vLLM Metal captioning, use **macOS 15+, Apple Silicon, and Python
163
+ 3.12**. The current Metal wheels are published on
164
+ [GitHub releases](https://github.com/vllm-project/vllm-metal/releases), while
165
+ PyPI still carries the obsolete 0.1.0 plugin. From this checkout, install the
166
+ matching stable vLLM 0.33.0 core and Metal 0.33.0 wheels into your environment:
159
167
 
160
168
  ```bash
161
- curl -fsSL https://raw.githubusercontent.com/vllm-project/vllm-metal/main/install.sh | bash
162
- source ~/.venv-vllm-metal/bin/activate
163
- pip install -e .
169
+ python -m pip install --upgrade -r requirements.metal.txt
170
+ python -m pip install -e ".[dev]"
171
+ python -m pip check
172
+ python examples/metal_smoke.py
164
173
  ```
165
174
 
166
- Do not combine `.[apple]` with the Linux `.[vllm]` extra.
175
+ The smoke test downloads `mlx-community/Qwen3-VL-2B-Instruct-4bit` on first
176
+ use and runs two images through CaptionFlow's native caption pipeline. It
177
+ checks that the Metal plugin and MLX GPU are active, and that the captions
178
+ identify the images' shapes and different colors. Pass `--model /path/to/model`
179
+ to use a local checkpoint. The test does not connect to an orchestrator.
180
+
181
+ The stable recipe uses the core wheel's PyTorch 2.14.0 pin. Upstream's installer
182
+ can select newer development builds and override Torch with nightly packages;
183
+ those are separate from this recipe. `.[apple]` alone does not install a vLLM
184
+ runtime, and should not be combined with the Linux `.[vllm]` extra.
167
185
 
168
186
  For native macOS CPU vLLM instead, follow the
169
187
  [official source-build instructions](https://docs.vllm.ai/en/stable/getting_started/installation/cpu/?device=apple).
@@ -225,7 +243,7 @@ Options:
225
243
  * **csv**: exports CSV-compatible data columns to the `--output` path containing incomplete metadata
226
244
  * **json**: creates a `.json` file for each sample inside the `--output` subdirectory containing **complete** metadata; useful for webdatasets
227
245
  * **txt**: creates `.txt` file for each sample inside the `--output` subdirectory containing ONLY captions
228
- * **webshart**: updates an **existing per-shard metadata `.json` file** by writing captions under the plural `captions` key. Strings, native JSON objects, and mixed lists are supported. JSON objects stored as text in Lance output columns are decoded during export, preserving nested values instead of writing Python dictionary representations. Native objects supplied through `Caption.outputs` are encoded as JSON only for Lance persistence. Requires webshart 0.6.0 or newer for native JSON caption support (included in the base dependencies). For this format, pass `--output` as the path to the existing shard metadata JSON file when exporting one shard. If you export multiple shards, pass `--output` as a directory containing one existing `{shard_name}.json` file per shard.
246
+ * **webshart**: updates an **existing per-shard metadata `.json` file** by writing captions under the plural `captions` key. Strings, native JSON objects, and mixed lists are supported. JSON objects stored as text in Lance output columns are decoded during export, preserving nested values instead of writing Python dictionary representations. Native objects supplied through `Caption.outputs` are encoded as JSON only for Lance persistence. Requires webshart 0.7.x (included in the base dependencies), including native JSON caption support. For this format, pass `--output` as the path to the existing shard metadata JSON file when exporting one shard. If you export multiple shards, pass `--output` as a directory containing one existing `{shard_name}.json` file per shard.
229
247
  * **huggingface_hub**: creates a dataset on Hugging Face Hub, possibly `--private` and `--nsfw` where necessary
230
248
  * **all**: creates the directory/file-generating export formats in a specified `--output` directory. prefer a directory here; `webshart` is a special case that expects existing per-shard metadata `.json` files rather than creating new metadata files.
231
249
 
@@ -0,0 +1,92 @@
1
+ websockets<18.0,>=17.4
2
+ pyarrow<27.0.0,>=26.0.1
3
+ click<9.0.0,>=8.5.1
4
+ pydantic<3.0.0,>=2.14.3
5
+ aiofiles<26.0.0,>=25.1.0
6
+ rich<16.0.0,>=15.0.0
7
+ cryptography<51.0.0,>=50.0.2
8
+ PyYAML<7.0.0,>=6.0.3
9
+ certbot<6.0.0,>=5.10.0
10
+ Pillow<14.0.0,>=13.0.0
11
+ trainingsample==0.4.0
12
+ pandas<4.0.0,>=3.1.1
13
+ datasets<6.0.0,>=5.2.0
14
+ boto3<2.0.0,>=1.44.3
15
+ webshart<0.8.0,>=0.7.0
16
+ pylance<9.0.0,>=8.0.1
17
+ duckdb<2.0.0,>=1.5.6
18
+ aiohttp<4.0.0,>=3.14.5
19
+ fastapi<0.137.0,>=0.136.3
20
+ uvicorn<1.0.0,>=0.54.0
21
+ huggingface-hub<2.0.0,>=1.33.0
22
+ psutil<8.0.0,>=7.2.2
23
+ requests<3.0.0,>=2.34.2
24
+ tqdm<5.0.0,>=4.70.1
25
+ urwid<6.0.0,>=5.1.3
26
+
27
+ [:python_version < "3.13"]
28
+ numpy<2.4.0,>=2.3.5
29
+
30
+ [:python_version >= "3.13"]
31
+ numpy<2.5.0,>=2.4.6
32
+
33
+ [all]
34
+ vllm<0.34.0,>=0.33.0
35
+ torch==2.14.0
36
+ torchvision==0.29.0
37
+ torchaudio==2.11.0
38
+ transformers<5.21.0,>=5.16.1
39
+ qwen-vl-utils<0.1.0,>=0.0.14
40
+
41
+ [apple]
42
+ torch>=2.14.0
43
+ torchvision>=0.29.0
44
+ torchaudio>=2.11.0
45
+ qwen-vl-utils<0.1.0,>=0.0.14
46
+
47
+ [captioning]
48
+ vllm<0.34.0,>=0.33.0
49
+ torch==2.14.0
50
+ torchvision==0.29.0
51
+ torchaudio==2.11.0
52
+ transformers<5.21.0,>=5.16.1
53
+ qwen-vl-utils<0.1.0,>=0.0.14
54
+
55
+ [cpu]
56
+ torch>=2.14.0
57
+ torchvision>=0.29.0
58
+ torchaudio>=2.11.0
59
+
60
+ [cuda]
61
+ torch>=2.14.0
62
+ torchvision>=0.29.0
63
+ torchaudio>=2.11.0
64
+
65
+ [cuda13]
66
+ torch>=2.14.0
67
+ torchvision>=0.29.0
68
+ torchaudio>=2.11.0
69
+
70
+ [dev]
71
+ pytest<10.0.0,>=9.2.0
72
+ pytest-asyncio<2.0.0,>=1.5.0
73
+ pytest-cov<8.0.0,>=7.1.0
74
+ transformers<5.21.0,>=5.16.1
75
+ black<27.0.0,>=26.10.1
76
+ ruff<1.0.0,>=0.17.5
77
+ mypy<3.0.0,>=2.4.1
78
+
79
+ [openai]
80
+
81
+ [rocm]
82
+ torch>=2.14.0
83
+ torchvision>=0.29.0
84
+ torchaudio>=2.11.0
85
+
86
+ [vllm]
87
+ vllm<0.34.0,>=0.33.0
88
+ torch==2.14.0
89
+ torchvision==0.29.0
90
+ torchaudio==2.11.0
91
+ transformers<5.21.0,>=5.16.1
92
+ qwen-vl-utils<0.1.0,>=0.0.14
@@ -27,12 +27,12 @@ def requirements_by_name(requirements):
27
27
  @pytest.mark.parametrize("extra", ["vllm", "captioning", "all"])
28
28
  def test_vllm_extras_select_matching_runtime(package_config, extra):
29
29
  dependencies = requirements_by_name(package_config["extras_require"][extra])
30
- assert dependencies["vllm"].specifier.contains("0.31.0")
31
- assert not dependencies["vllm"].specifier.contains("0.30.0")
30
+ assert dependencies["vllm"].specifier.contains("0.33.0")
32
31
  assert not dependencies["vllm"].specifier.contains("0.32.0")
32
+ assert not dependencies["vllm"].specifier.contains("0.34.0")
33
33
  for name, version in (
34
- ("torch", "2.13.0"),
35
- ("torchvision", "0.28.0"),
34
+ ("torch", "2.14.0"),
35
+ ("torchvision", "0.29.0"),
36
36
  ("torchaudio", "2.11.0"),
37
37
  ):
38
38
  assert str(dependencies[name].specifier) == f"=={version}"
@@ -42,19 +42,19 @@ def test_vllm_extras_select_matching_runtime(package_config, extra):
42
42
  def test_transformers_matches_vllm_supported_range(package_config, extra):
43
43
  dependencies = requirements_by_name(package_config["extras_require"][extra])
44
44
  versions = dependencies["transformers"].specifier
45
- assert versions.contains("5.10.4")
46
- assert versions.contains("5.17.0")
47
- assert not versions.contains("5.10.3")
48
- assert not versions.contains("5.18.0")
45
+ assert versions.contains("5.16.1")
46
+ assert versions.contains("5.20.2")
47
+ assert not versions.contains("5.16.0")
48
+ assert not versions.contains("5.21.0")
49
49
 
50
50
 
51
51
  @pytest.mark.parametrize("extra", ["cpu", "cuda", "cuda13", "rocm", "apple"])
52
52
  def test_pytorch_extras_require_updated_family(package_config, extra):
53
53
  dependencies = requirements_by_name(package_config["extras_require"][extra])
54
- assert dependencies["torch"].specifier.contains("2.13.0")
55
- assert not dependencies["torch"].specifier.contains("2.12.0")
56
- assert dependencies["torchvision"].specifier.contains("0.28.0")
57
- assert not dependencies["torchvision"].specifier.contains("0.27.0")
54
+ assert dependencies["torch"].specifier.contains("2.14.0")
55
+ assert not dependencies["torch"].specifier.contains("2.13.0")
56
+ assert dependencies["torchvision"].specifier.contains("0.29.0")
57
+ assert not dependencies["torchvision"].specifier.contains("0.28.0")
58
58
  assert dependencies["torchaudio"].specifier.contains("2.11.0")
59
59
  assert "vllm" not in dependencies
60
60
 
@@ -22,6 +22,7 @@ def test_base_dependency_requires_structured_caption_support():
22
22
  for dependency in dependencies
23
23
  if (requirement := Requirement(dependency)).name == "webshart"
24
24
  )
25
- assert "0.6.0" in requirement.specifier
25
+ assert "0.7.0" in requirement.specifier
26
26
  assert "0.5.4" not in requirement.specifier
27
- assert "0.7.0" not in requirement.specifier
27
+ assert "0.6.0" not in requirement.specifier
28
+ assert "0.8.0" not in requirement.specifier
@@ -508,7 +508,10 @@ class TestCaptionWorker:
508
508
  # Mock tokenizer and processor
509
509
  mock_tokenizer = Mock()
510
510
  mock_tokenizer.encode = Mock(return_value=[1] * 100) # 100 tokens
511
+ # qwen-vl-utils uses the callable tokenizer; the fallback uses encode().
512
+ mock_tokenizer.return_value.input_ids = [1] * 100
511
513
  mock_processor = Mock()
514
+ mock_processor.apply_chat_template.return_value = "Describe this image"
512
515
  mock_sampling = Mock()
513
516
 
514
517
  stage = caption_worker.stages[0]
@@ -522,6 +525,13 @@ class TestCaptionWorker:
522
525
  assert len(processable) == 3
523
526
  assert len(too_long) == 0
524
527
 
528
+ # The 50-token safety buffer must still exclude these 100-token prompts.
529
+ processable, too_long = caption_worker._validate_and_split_batch(
530
+ batch, stage, mock_processor, mock_tokenizer, mock_sampling, max_length=150
531
+ )
532
+ assert processable == []
533
+ assert too_long == batch
534
+
525
535
  def test_resize_image_for_tokens(self, caption_worker):
526
536
  """Test image resizing for token reduction."""
527
537
  item = ProcessingItem(
@@ -1,89 +0,0 @@
1
- websockets<17.0,>=16.0
2
- pyarrow<26.0.0,>=21.0.0
3
- click<9.0.0,>=8.2.0
4
- pydantic<3.0.0,>=2.12.0
5
- aiofiles<26.0.0,>=24.1.0
6
- rich<16.0.0,>=14.0.0
7
- cryptography<50.0.0,>=45.0.0
8
- PyYAML<7.0.0,>=6.0.2
9
- certbot<6.0.0,>=5.0.0
10
- numpy<3.0.0,>=2.2.0
11
- Pillow<13.0.0,>=11.3.0
12
- trainingsample<0.4.0,>=0.3.2
13
- pandas<4.0.0,>=3.0.0
14
- datasets<6.0.0,>=5.0.0
15
- boto3<2.0.0,>=1.43.0
16
- webshart<0.7.0,>=0.6.0
17
- pylance<9.0.0,>=8.0.0
18
- duckdb<2.0.0,>=1.5.0
19
- aiohttp<4.0.0,>=3.13.3
20
- fastapi<0.137.0,>=0.133.0
21
- uvicorn<1.0.0,>=0.35.0
22
- huggingface-hub<2.0.0,>=1.5.0
23
- psutil<8.0.0,>=7.0.0
24
- requests<3.0.0,>=2.32.0
25
- tqdm<5.0.0,>=4.67.0
26
- urwid<5.0.0,>=3.0.2
27
-
28
- [all]
29
- vllm<0.32.0,>=0.31.0
30
- torch==2.13.0
31
- torchvision==0.28.0
32
- torchaudio==2.11.0
33
- transformers<5.18.0,>=5.10.4
34
- qwen-vl-utils<0.1.0,>=0.0.14
35
-
36
- [apple]
37
- torch>=2.13.0
38
- torchvision>=0.28.0
39
- torchaudio>=2.11.0
40
-
41
- [apple:platform_system == "Darwin" and platform_machine == "arm64" and python_version >= "3.12"]
42
- vllm-metal==0.1.0
43
-
44
- [captioning]
45
- vllm<0.32.0,>=0.31.0
46
- torch==2.13.0
47
- torchvision==0.28.0
48
- torchaudio==2.11.0
49
- transformers<5.18.0,>=5.10.4
50
- qwen-vl-utils<0.1.0,>=0.0.14
51
-
52
- [cpu]
53
- torch>=2.13.0
54
- torchvision>=0.28.0
55
- torchaudio>=2.11.0
56
-
57
- [cuda]
58
- torch>=2.13.0
59
- torchvision>=0.28.0
60
- torchaudio>=2.11.0
61
-
62
- [cuda13]
63
- torch>=2.13.0
64
- torchvision>=0.28.0
65
- torchaudio>=2.11.0
66
-
67
- [dev]
68
- pytest<9.0.0,>=8.0.0
69
- pytest-asyncio<2.0.0,>=1.1.0
70
- pytest-cov<7.0.0,>=6.0.0
71
- transformers<5.18.0,>=5.10.4
72
- black<26.0.0,>=25.0.0
73
- ruff<1.0.0,>=0.12.0
74
- mypy<2.0.0,>=1.17.0
75
-
76
- [openai]
77
-
78
- [rocm]
79
- torch>=2.13.0
80
- torchvision>=0.28.0
81
- torchaudio>=2.11.0
82
-
83
- [vllm]
84
- vllm<0.32.0,>=0.31.0
85
- torch==2.13.0
86
- torchvision==0.28.0
87
- torchaudio==2.11.0
88
- transformers<5.18.0,>=5.10.4
89
- qwen-vl-utils<0.1.0,>=0.0.14
File without changes
File without changes