caption-flow 0.5.7__tar.gz → 0.6.0__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.0}/PKG-INFO +87 -69
  2. {caption_flow-0.5.7 → caption_flow-0.6.0}/README.md +31 -14
  3. {caption_flow-0.5.7 → caption_flow-0.6.0}/pyproject.toml +1 -1
  4. {caption_flow-0.5.7 → caption_flow-0.6.0}/setup.py +46 -43
  5. {caption_flow-0.5.7 → caption_flow-0.6.0}/src/caption_flow/__init__.py +1 -1
  6. {caption_flow-0.5.7 → caption_flow-0.6.0}/src/caption_flow.egg-info/PKG-INFO +87 -69
  7. caption_flow-0.6.0/src/caption_flow.egg-info/requires.txt +92 -0
  8. {caption_flow-0.5.7 → caption_flow-0.6.0}/tests/test_dependency_config.py +12 -12
  9. {caption_flow-0.5.7 → caption_flow-0.6.0}/tests/test_worker_caption.py +10 -0
  10. caption_flow-0.5.7/src/caption_flow.egg-info/requires.txt +0 -89
  11. {caption_flow-0.5.7 → caption_flow-0.6.0}/LICENSE +0 -0
  12. {caption_flow-0.5.7 → caption_flow-0.6.0}/setup.cfg +0 -0
  13. {caption_flow-0.5.7 → caption_flow-0.6.0}/src/caption_flow/cli.py +0 -0
  14. {caption_flow-0.5.7 → caption_flow-0.6.0}/src/caption_flow/models.py +0 -0
  15. {caption_flow-0.5.7 → caption_flow-0.6.0}/src/caption_flow/monitor.py +0 -0
  16. {caption_flow-0.5.7 → caption_flow-0.6.0}/src/caption_flow/orchestrator.py +0 -0
  17. {caption_flow-0.5.7 → caption_flow-0.6.0}/src/caption_flow/processors/__init__.py +0 -0
  18. {caption_flow-0.5.7 → caption_flow-0.6.0}/src/caption_flow/processors/base.py +0 -0
  19. {caption_flow-0.5.7 → caption_flow-0.6.0}/src/caption_flow/processors/huggingface.py +0 -0
  20. {caption_flow-0.5.7 → caption_flow-0.6.0}/src/caption_flow/processors/local_filesystem.py +0 -0
  21. {caption_flow-0.5.7 → caption_flow-0.6.0}/src/caption_flow/processors/webdataset.py +0 -0
  22. {caption_flow-0.5.7 → caption_flow-0.6.0}/src/caption_flow/storage/__init__.py +0 -0
  23. {caption_flow-0.5.7 → caption_flow-0.6.0}/src/caption_flow/storage/exporter.py +0 -0
  24. {caption_flow-0.5.7 → caption_flow-0.6.0}/src/caption_flow/storage/manager.py +0 -0
  25. {caption_flow-0.5.7 → caption_flow-0.6.0}/src/caption_flow/utils/__init__.py +0 -0
  26. {caption_flow-0.5.7 → caption_flow-0.6.0}/src/caption_flow/utils/auth.py +0 -0
  27. {caption_flow-0.5.7 → caption_flow-0.6.0}/src/caption_flow/utils/caption_utils.py +0 -0
  28. {caption_flow-0.5.7 → caption_flow-0.6.0}/src/caption_flow/utils/certificates.py +0 -0
  29. {caption_flow-0.5.7 → caption_flow-0.6.0}/src/caption_flow/utils/checkpoint_tracker.py +0 -0
  30. {caption_flow-0.5.7 → caption_flow-0.6.0}/src/caption_flow/utils/chunk_tracker.py +0 -0
  31. {caption_flow-0.5.7 → caption_flow-0.6.0}/src/caption_flow/utils/image_processor.py +0 -0
  32. {caption_flow-0.5.7 → caption_flow-0.6.0}/src/caption_flow/utils/json_utils.py +0 -0
  33. {caption_flow-0.5.7 → caption_flow-0.6.0}/src/caption_flow/utils/output_policy.py +0 -0
  34. {caption_flow-0.5.7 → caption_flow-0.6.0}/src/caption_flow/utils/prompt_template.py +0 -0
  35. {caption_flow-0.5.7 → caption_flow-0.6.0}/src/caption_flow/utils/retry_queue.py +0 -0
  36. {caption_flow-0.5.7 → caption_flow-0.6.0}/src/caption_flow/utils/unicode_utils.py +0 -0
  37. {caption_flow-0.5.7 → caption_flow-0.6.0}/src/caption_flow/utils/vllm_config.py +0 -0
  38. {caption_flow-0.5.7 → caption_flow-0.6.0}/src/caption_flow/viewer.py +0 -0
  39. {caption_flow-0.5.7 → caption_flow-0.6.0}/src/caption_flow/workers/base.py +0 -0
  40. {caption_flow-0.5.7 → caption_flow-0.6.0}/src/caption_flow/workers/caption.py +0 -0
  41. {caption_flow-0.5.7 → caption_flow-0.6.0}/src/caption_flow/workers/data.py +0 -0
  42. {caption_flow-0.5.7 → caption_flow-0.6.0}/src/caption_flow/workers/openai_compatible.py +0 -0
  43. {caption_flow-0.5.7 → caption_flow-0.6.0}/src/caption_flow/workers/pipeline.py +0 -0
  44. {caption_flow-0.5.7 → caption_flow-0.6.0}/src/caption_flow.egg-info/SOURCES.txt +0 -0
  45. {caption_flow-0.5.7 → caption_flow-0.6.0}/src/caption_flow.egg-info/dependency_links.txt +0 -0
  46. {caption_flow-0.5.7 → caption_flow-0.6.0}/src/caption_flow.egg-info/entry_points.txt +0 -0
  47. {caption_flow-0.5.7 → caption_flow-0.6.0}/src/caption_flow.egg-info/top_level.txt +0 -0
  48. {caption_flow-0.5.7 → caption_flow-0.6.0}/tests/test_caption_pipeline.py +0 -0
  49. {caption_flow-0.5.7 → caption_flow-0.6.0}/tests/test_caption_utils.py +0 -0
  50. {caption_flow-0.5.7 → caption_flow-0.6.0}/tests/test_certificates.py +0 -0
  51. {caption_flow-0.5.7 → caption_flow-0.6.0}/tests/test_chunk_completion_index.py +0 -0
  52. {caption_flow-0.5.7 → caption_flow-0.6.0}/tests/test_cli.py +0 -0
  53. {caption_flow-0.5.7 → caption_flow-0.6.0}/tests/test_config_reload.py +0 -0
  54. {caption_flow-0.5.7 → caption_flow-0.6.0}/tests/test_duplicate_job_assignments.py +0 -0
  55. {caption_flow-0.5.7 → caption_flow-0.6.0}/tests/test_exporter.py +0 -0
  56. {caption_flow-0.5.7 → caption_flow-0.6.0}/tests/test_fix_verification.py +0 -0
  57. {caption_flow-0.5.7 → caption_flow-0.6.0}/tests/test_huggingface_ranges.py +0 -0
  58. {caption_flow-0.5.7 → caption_flow-0.6.0}/tests/test_image_processor.py +0 -0
  59. {caption_flow-0.5.7 → caption_flow-0.6.0}/tests/test_json_utils.py +0 -0
  60. {caption_flow-0.5.7 → caption_flow-0.6.0}/tests/test_main.py +0 -0
  61. {caption_flow-0.5.7 → caption_flow-0.6.0}/tests/test_monitor.py +0 -0
  62. {caption_flow-0.5.7 → caption_flow-0.6.0}/tests/test_openai_compatible_worker.py +0 -0
  63. {caption_flow-0.5.7 → caption_flow-0.6.0}/tests/test_orchestrator_storage_order.py +0 -0
  64. {caption_flow-0.5.7 → caption_flow-0.6.0}/tests/test_processors.py +0 -0
  65. {caption_flow-0.5.7 → caption_flow-0.6.0}/tests/test_range_level_distribution.py +0 -0
  66. {caption_flow-0.5.7 → caption_flow-0.6.0}/tests/test_result_acceptance.py +0 -0
  67. {caption_flow-0.5.7 → caption_flow-0.6.0}/tests/test_retry_queue.py +0 -0
  68. {caption_flow-0.5.7 → caption_flow-0.6.0}/tests/test_storage_components.py +0 -0
  69. {caption_flow-0.5.7 → caption_flow-0.6.0}/tests/test_unicode_utils.py +0 -0
  70. {caption_flow-0.5.7 → caption_flow-0.6.0}/tests/test_viewer.py +0 -0
  71. {caption_flow-0.5.7 → caption_flow-0.6.0}/tests/test_vllm_config.py +0 -0
  72. {caption_flow-0.5.7 → caption_flow-0.6.0}/tests/test_webdataset_cache_wait.py +0 -0
  73. {caption_flow-0.5.7 → caption_flow-0.6.0}/tests/test_webdataset_prefetch.py +0 -0
  74. {caption_flow-0.5.7 → caption_flow-0.6.0}/tests/test_webdataset_ranges.py +0 -0
  75. {caption_flow-0.5.7 → caption_flow-0.6.0}/tests/test_webshart_dependency.py +0 -0
  76. {caption_flow-0.5.7 → caption_flow-0.6.0}/tests/test_webshart_export_contract.py +0 -0
  77. {caption_flow-0.5.7 → caption_flow-0.6.0}/tests/test_worker_reconnection_complete.py +0 -0
  78. {caption_flow-0.5.7 → caption_flow-0.6.0}/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.0
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
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
30
31
  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
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
34
35
  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
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).
@@ -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).
@@ -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",
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",
37
40
  "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
+ "pandas>=3.1.1,<4.0.0",
42
+ "datasets>=5.2.0,<6.0.0",
43
+ "boto3>=1.44.3,<2.0.0",
41
44
  "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",
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.0"
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.0
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
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
30
31
  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
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
34
35
  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
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).
@@ -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,>=0.3.2
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.7.0,>=0.6.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
 
@@ -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