poly-hammer-worker 0.1.1.dev12__tar.gz → 0.3.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 (46) hide show
  1. poly_hammer_worker-0.3.0/.dockerignore +35 -0
  2. {poly_hammer_worker-0.1.1.dev12 → poly_hammer_worker-0.3.0}/.gitignore +2 -0
  3. poly_hammer_worker-0.3.0/PKG-INFO +14 -0
  4. poly_hammer_worker-0.3.0/README.md +82 -0
  5. poly_hammer_worker-0.3.0/compose.yml +72 -0
  6. poly_hammer_worker-0.3.0/docs/index.md +320 -0
  7. poly_hammer_worker-0.3.0/poly_hammer_worker/__init__.py +1 -0
  8. poly_hammer_worker-0.3.0/poly_hammer_worker/api_client.py +70 -0
  9. poly_hammer_worker-0.3.0/poly_hammer_worker/base_job.py +231 -0
  10. poly_hammer_worker-0.3.0/poly_hammer_worker/cli.py +547 -0
  11. {poly_hammer_worker-0.1.1.dev12 → poly_hammer_worker-0.3.0}/poly_hammer_worker/hardware.py +4 -19
  12. poly_hammer_worker-0.3.0/poly_hammer_worker/jobs/__init__.py +104 -0
  13. poly_hammer_worker-0.3.0/poly_hammer_worker/jobs/hello_motion/Dockerfile +31 -0
  14. poly_hammer_worker-0.3.0/poly_hammer_worker/jobs/hello_motion/__init__.py +19 -0
  15. poly_hammer_worker-0.3.0/poly_hammer_worker/jobs/hello_motion/config.py +11 -0
  16. poly_hammer_worker-0.3.0/poly_hammer_worker/jobs/hello_motion/job.py +172 -0
  17. poly_hammer_worker-0.3.0/poly_hammer_worker/jobs/hello_motion/mock-event.json +10 -0
  18. poly_hammer_worker-0.3.0/poly_hammer_worker/jobs/hello_motion/motion.npz +0 -0
  19. poly_hammer_worker-0.3.0/poly_hammer_worker/jobs/hello_motion/requirements.txt +6 -0
  20. poly_hammer_worker-0.3.0/poly_hammer_worker/jobs/hy_motion/Dockerfile +92 -0
  21. poly_hammer_worker-0.3.0/poly_hammer_worker/jobs/hy_motion/__init__.py +37 -0
  22. poly_hammer_worker-0.3.0/poly_hammer_worker/jobs/hy_motion/config.py +34 -0
  23. poly_hammer_worker-0.3.0/poly_hammer_worker/jobs/hy_motion/job.py +373 -0
  24. poly_hammer_worker-0.3.0/poly_hammer_worker/jobs/hy_motion/mock-event.json +10 -0
  25. poly_hammer_worker-0.3.0/poly_hammer_worker/jobs/hy_motion/requirements.txt +20 -0
  26. poly_hammer_worker-0.3.0/poly_hammer_worker/logging_setup.py +75 -0
  27. poly_hammer_worker-0.3.0/poly_hammer_worker/progress.py +291 -0
  28. poly_hammer_worker-0.3.0/poly_hammer_worker/utilities.py +338 -0
  29. poly_hammer_worker-0.3.0/poly_hammer_worker/worker.py +341 -0
  30. poly_hammer_worker-0.3.0/pyproject.toml +33 -0
  31. poly_hammer_worker-0.3.0/scripts/patch_hatchet_logger.py +73 -0
  32. poly_hammer_worker-0.3.0/tests/test_download_token.py +80 -0
  33. poly_hammer_worker-0.3.0/tests/test_progress.py +65 -0
  34. poly_hammer_worker-0.3.0/uv.lock +1638 -0
  35. poly_hammer_worker-0.1.1.dev12/PKG-INFO +0 -101
  36. poly_hammer_worker-0.1.1.dev12/README.md +0 -88
  37. poly_hammer_worker-0.1.1.dev12/poly_hammer_worker/__init__.py +0 -1
  38. poly_hammer_worker-0.1.1.dev12/poly_hammer_worker/api_client.py +0 -128
  39. poly_hammer_worker-0.1.1.dev12/poly_hammer_worker/cli.py +0 -158
  40. poly_hammer_worker-0.1.1.dev12/poly_hammer_worker/docker_runner.py +0 -393
  41. poly_hammer_worker-0.1.1.dev12/poly_hammer_worker/image_discovery.py +0 -188
  42. poly_hammer_worker-0.1.1.dev12/poly_hammer_worker/logging_config.py +0 -73
  43. poly_hammer_worker-0.1.1.dev12/poly_hammer_worker/worker_loop.py +0 -337
  44. poly_hammer_worker-0.1.1.dev12/pyproject.toml +0 -25
  45. poly_hammer_worker-0.1.1.dev12/uv.lock +0 -491
  46. {poly_hammer_worker-0.1.1.dev12 → poly_hammer_worker-0.3.0}/poly_hammer_worker/banner.py +0 -0
@@ -0,0 +1,35 @@
1
+ # Dependencies
2
+ node_modules
3
+ **/node_modules
4
+ frontend/node_modules
5
+
6
+ # Build outputs
7
+ dist
8
+ **/dist
9
+ frontend/dist
10
+
11
+ # Python
12
+ __pycache__
13
+ *.pyc
14
+ .venv
15
+ backend/.venv
16
+
17
+ # Git
18
+ .git
19
+ .gitignore
20
+
21
+ # IDE
22
+ .vscode
23
+ .idea
24
+
25
+ # Test artifacts
26
+ htmlcov
27
+ .coverage
28
+ .pytest_cache
29
+ playwright-report
30
+ test-results
31
+
32
+ # Misc
33
+ *.log
34
+ .DS_Store
35
+ Thumbs.db
@@ -6,7 +6,9 @@ node_modules/
6
6
  scratches
7
7
  backend/reports
8
8
  .terraform
9
+ .terraform-*
9
10
  terraform.tfvars
10
11
  .vite/
11
12
  secret.env
12
13
  __pycache__/
14
+ .hatchet/
@@ -0,0 +1,14 @@
1
+ Metadata-Version: 2.4
2
+ Name: poly-hammer-worker
3
+ Version: 0.3.0
4
+ Summary: Poly Hammer self-hosted GPU worker — runs AI inference inside Docker
5
+ License-Expression: MIT
6
+ Requires-Python: <4,>=3.10
7
+ Requires-Dist: hatchet-sdk>=1.32.0
8
+ Requires-Dist: hf-transfer>=0.1.9
9
+ Requires-Dist: httpx>=0.27
10
+ Requires-Dist: huggingface-hub<1.0,>=0.30.0
11
+ Requires-Dist: modal>=1.3.2
12
+ Requires-Dist: psutil>=5.9
13
+ Requires-Dist: rich>=13.0
14
+ Requires-Dist: typer>=0.12
@@ -0,0 +1,82 @@
1
+ # Self-Hosted Worker Images
2
+
3
+ Docker images for running Poly Hammer AI inference workers on your own hardware.
4
+ Model weights are volume-mounted at runtime via named Docker volumes.
5
+
6
+ ## Quick Start
7
+
8
+ ```bash
9
+ # From workers/self-hosted/:
10
+ docker compose build
11
+
12
+ # Or build a single image:
13
+ docker compose build hy-motion
14
+ docker compose build hello-motion
15
+ ```
16
+
17
+ This produces locally-tagged images:
18
+
19
+ | Service | Image Tag | GPU Required |
20
+ |---------|-----------|-------------|
21
+ | HY-Motion | `ph-hy-motion:latest` | Yes |
22
+ | Hello Motion | `ph-hello-motion:latest` | No |
23
+
24
+ ## Hardware Requirements
25
+
26
+ ### HY-Motion (`ph-hy-motion`)
27
+
28
+ | Resource | Minimum |
29
+ |----------|---------|
30
+ | GPU VRAM | 24 GB (Lite model) / 40 GB (full model) |
31
+ | System RAM | 16–32 GB |
32
+ | Disk (image) | ~40 GB |
33
+ | Disk (build) | ~80 GB (temporary build layers) |
34
+
35
+ ### Hello Motion (`ph-hello-motion`)
36
+
37
+ No GPU required. Uses a bundled motion.npz fixture to simulate the full
38
+ inference pipeline. Useful for end-to-end testing of the worker system.
39
+
40
+ ## License Notices
41
+
42
+ **You must review and accept the following licenses before building these images.**
43
+
44
+ ### HY-Motion (`ph-hy-motion`)
45
+
46
+ - **Tencent Hunyuan Community License**: The HY-Motion model weights are released by Tencent under the [Tencent Hunyuan Community License Agreement](https://github.com/Tencent/HunyuanVideo/blob/main/LICENSE.txt). This license includes territory restrictions and usage conditions. Review it carefully.
47
+ - **CLIP (OpenAI)**: The CLIP text encoder is released under the [MIT License](https://github.com/openai/CLIP/blob/main/LICENSE).
48
+ - **Qwen3 (Alibaba)**: The Qwen3 text encoder is released under the [Apache 2.0 License](https://huggingface.co/Qwen/Qwen3-8B/blob/main/LICENSE).
49
+
50
+ ## Downloading Weights
51
+
52
+ Weights are not baked into the image — download them once into a named volume:
53
+
54
+ ```bash
55
+ docker volume create hy-motion-weights
56
+
57
+ # Allocate a TTY (-it) so the live progress panel renders:
58
+ docker run --rm -it --gpus all \
59
+ -v hy-motion-weights:/weights \
60
+ ph-hy-motion download-weights --job hy-motion --all
61
+ ```
62
+
63
+ Expect roughly **50 GB** for `--all` and 20–60 minutes on a typical
64
+ residential connection (`hf-transfer` is enabled by default).
65
+
66
+ ### Helpful flags
67
+
68
+ | Flag | Purpose |
69
+ |------|---------|
70
+ | `--hf-token <token>` | Authenticate with HuggingFace. Lifts anonymous rate limits and unlocks gated repos. Also reads `HF_TOKEN` / `HUGGING_FACE_HUB_TOKEN` env vars. |
71
+ | `--no-progress` | Disable the live panel (use under `docker run -d` or in CI where there is no TTY). |
72
+ | `--dry-run` | Print the download plan and exit without contacting HuggingFace. |
73
+ | `--retries N` | Retry attempts per step on transient failures (default: 3, exponential backoff). |
74
+ | `-v` / `--verbose` | Enable DEBUG logging from `ph-worker` and `huggingface_hub`. |
75
+ | `-q` / `--quiet` | Suppress INFO logs; only show warnings, errors, and the progress panel. |
76
+
77
+ ### Why doesn't it look like anything is happening?
78
+
79
+ If you ran `docker run` without `-t` (no TTY), Rich's live panel can't draw
80
+ and you'll only see the periodic INFO log lines from `huggingface_hub`
81
+ (e.g. `Fetching N files`). Pass `-it` for the panel, or `--no-progress` to
82
+ opt into log-only mode.
@@ -0,0 +1,72 @@
1
+ # =============================================================================
2
+ # Self-Hosted Worker Images — Local Build
3
+ #
4
+ # Each image IS a Hatchet worker. Run directly:
5
+ # docker run --gpus all ph-hy-motion start --token <WORKER_TOKEN>
6
+ #
7
+ # Build all images (from workers/self-hosted/):
8
+ # docker compose build
9
+ #
10
+ # Build a single image:
11
+ # docker compose --env-file secret.env build hy-motion
12
+ # docker compose build ph-hello-motion
13
+ #
14
+ # Build a specific CUDA variant:
15
+ # docker compose build hy-motion-cu121
16
+ #
17
+ # See README.md for license notices and hardware requirements.
18
+ # =============================================================================
19
+
20
+ services:
21
+ # ---------------------------------------------------------------------------
22
+ # HY-Motion — Default (cu128 / CUDA 13.1 — Blackwell, Hopper, Ampere)
23
+ # ---------------------------------------------------------------------------
24
+ hy-motion:
25
+ image: ghcr.io/poly-hammer/ph-hy-motion:latest
26
+ build:
27
+ context: .
28
+ dockerfile: poly_hammer_worker/jobs/hy_motion/Dockerfile
29
+ volumes:
30
+ - hy-motion-weights:/weights
31
+ deploy:
32
+ resources:
33
+ reservations:
34
+ devices:
35
+ - driver: nvidia
36
+ count: 1
37
+ capabilities: [gpu]
38
+
39
+ # ---------------------------------------------------------------------------
40
+ # HY-Motion — cu121 (CUDA 12.1 — RTX 20xx+, driver ≥530)
41
+ # ---------------------------------------------------------------------------
42
+ hy-motion-cu121:
43
+ image: ghcr.io/poly-hammer/ph-hy-motion:cu121
44
+ build:
45
+ context: .
46
+ dockerfile: poly_hammer_worker/jobs/hy_motion/Dockerfile
47
+ args:
48
+ CUDA_TAG: 12.1.1-cudnn8-devel-ubuntu22.04
49
+ TORCH_INDEX_URL: https://download.pytorch.org/whl/cu121
50
+ TORCH_VERSION: "2.6.0"
51
+ TORCHVISION_VERSION: "0.21.0"
52
+ volumes:
53
+ - hy-motion-weights:/weights
54
+ deploy:
55
+ resources:
56
+ reservations:
57
+ devices:
58
+ - driver: nvidia
59
+ count: 1
60
+ capabilities: [gpu]
61
+
62
+ # ---------------------------------------------------------------------------
63
+ # Hello Motion — Debug Image (no GPU)
64
+ # ---------------------------------------------------------------------------
65
+ ph-hello-motion:
66
+ image: ghcr.io/poly-hammer/ph-hello-motion:latest
67
+ build:
68
+ context: .
69
+ dockerfile: poly_hammer_worker/jobs/hello_motion/Dockerfile
70
+
71
+ volumes:
72
+ hy-motion-weights:
@@ -0,0 +1,320 @@
1
+ # Self-Hosted Worker Setup Guide
2
+
3
+ Run Poly Hammer AI inference on your own GPU hardware. This guide covers
4
+ installing Docker, setting up NVIDIA GPU support, choosing the right image
5
+ for your hardware, and running your first worker.
6
+
7
+ ---
8
+
9
+ ## Prerequisites
10
+
11
+ | Requirement | Minimum |
12
+ |-------------|---------|
13
+ | NVIDIA GPU | RTX 2060 or newer (Turing, Ampere, Ada Lovelace, Hopper, Blackwell) |
14
+ | GPU VRAM | 24 GB (Lite model) / 40 GB (Full model) |
15
+ | System RAM | 16 GB (Lite) / 32 GB (Full) |
16
+ | Disk space | ~40 GB for the image + ~30 GB for model weights |
17
+ | Docker | 24.0+ with NVIDIA Container Toolkit |
18
+
19
+ ---
20
+
21
+ ## 1. Install Docker
22
+
23
+ ### Linux (Ubuntu / Debian)
24
+
25
+ ```bash
26
+ # Install Docker Engine
27
+ curl -fsSL https://get.docker.com | sh
28
+
29
+ # Add your user to the docker group (log out and back in after)
30
+ sudo usermod -aG docker $USER
31
+ ```
32
+
33
+ ### Windows
34
+
35
+ 1. Install [Docker Desktop for Windows](https://docs.docker.com/desktop/setup/install/windows-install/)
36
+ 2. Enable **WSL 2 backend** during setup (required for GPU passthrough)
37
+ 3. In Docker Desktop settings, ensure **"Use the WSL 2 based engine"** is checked
38
+
39
+ > **Note:** GPU passthrough on Windows requires WSL 2 with an Ubuntu distribution.
40
+ > All Docker commands below should be run inside your WSL 2 terminal, not PowerShell.
41
+
42
+ ---
43
+
44
+ ## 2. Install NVIDIA GPU Support
45
+
46
+ ### Linux
47
+
48
+ Install the NVIDIA driver and the [NVIDIA Container Toolkit](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html),
49
+ which lets Docker containers access your GPU:
50
+
51
+ ```bash
52
+ # 1. Install the latest NVIDIA driver (if not already installed)
53
+ sudo apt-get update
54
+ sudo apt-get install -y nvidia-driver-570
55
+
56
+ # 2. Add the NVIDIA Container Toolkit repository
57
+ curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey \
58
+ | sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg
59
+ curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list \
60
+ | sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' \
61
+ | sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list
62
+
63
+ # 3. Install the toolkit
64
+ sudo apt-get update
65
+ sudo apt-get install -y nvidia-container-toolkit
66
+
67
+ # 4. Configure Docker to use the NVIDIA runtime
68
+ sudo nvidia-ctk runtime configure --runtime=docker
69
+ sudo systemctl restart docker
70
+ ```
71
+
72
+ ### Windows (WSL 2)
73
+
74
+ GPU support in WSL 2 is provided automatically by the Windows NVIDIA driver —
75
+ you do **not** install a separate Linux driver inside WSL.
76
+
77
+ 1. Install the latest [NVIDIA Game Ready or Studio driver](https://www.nvidia.com/Download/index.aspx) on Windows
78
+ 2. Open your WSL 2 Ubuntu terminal and install the Container Toolkit:
79
+
80
+ ```bash
81
+ # Inside WSL 2 Ubuntu
82
+ curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey \
83
+ | sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg
84
+ curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list \
85
+ | sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' \
86
+ | sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list
87
+ sudo apt-get update
88
+ sudo apt-get install -y nvidia-container-toolkit
89
+ sudo nvidia-ctk runtime configure --runtime=docker
90
+ sudo systemctl restart docker
91
+ ```
92
+
93
+ ### Verify GPU Access
94
+
95
+ Run this to confirm Docker can see your GPU:
96
+
97
+ ```bash
98
+ docker run --rm --gpus all nvidia/cuda:12.1.1-base-ubuntu22.04 nvidia-smi
99
+ ```
100
+
101
+ You should see your GPU name, driver version, and CUDA version in the output.
102
+
103
+ ---
104
+
105
+ ## 3. Choose Your CUDA Variant
106
+
107
+ Worker images are published in two CUDA variants. Pick the one that matches
108
+ your GPU generation and driver version:
109
+
110
+ | Tag | CUDA | PyTorch | Base Image | Best For | Min Driver |
111
+ |-----|------|---------|------------|----------|------------|
112
+ | `:latest` | 13.1 (cu128) | 2.10.0 | `nvidia/cuda:13.1.1-cudnn-devel-ubuntu24.04` | RTX 50xx (Blackwell), H100, A100, RTX 30xx/40xx | 570+ |
113
+ | `:cu121` | 12.1 (cu121) | 2.6.0 | `nvidia/cuda:12.1.1-cudnn-devel-ubuntu22.04` | RTX 20xx (Turing), RTX 30xx, GTX 16xx | 530+ |
114
+
115
+ **How to check your driver version:**
116
+
117
+ ```bash
118
+ nvidia-smi
119
+ # Look for "Driver Version: XXX.XX" in the top-right of the table
120
+ ```
121
+
122
+ **How to choose:**
123
+
124
+ - If your driver is **570+** (most current systems), use `:latest` — it supports all GPUs from Ampere onward and adds native Blackwell sm_120 support.
125
+ - If your driver is **530–569** or you have a **Turing-era GPU** (RTX 2060–2080, GTX 1660), use `:cu121`.
126
+ - When in doubt, use `:cu121` — it has the widest hardware compatibility.
127
+
128
+ ---
129
+
130
+ ## 4. Authenticate with the Registry
131
+
132
+ Worker images are hosted on GitHub Container Registry (GHCR) and require
133
+ authentication. You need a **GitHub account** that has been granted access
134
+ to the `poly-hammer` organization's packages.
135
+
136
+ ```bash
137
+ # Log in to GHCR (use a GitHub Personal Access Token with read:packages scope)
138
+ echo $GITHUB_PAT | docker login ghcr.io -u YOUR_GITHUB_USERNAME --password-stdin
139
+ ```
140
+
141
+ ---
142
+
143
+ ## 5. Pull the Image
144
+
145
+ ```bash
146
+ # Default variant (cu128 — CUDA 13.1)
147
+ docker pull ghcr.io/poly-hammer/ph-hy-motion:latest
148
+
149
+ # Or the cu121 variant for older GPUs / drivers
150
+ docker pull ghcr.io/poly-hammer/ph-hy-motion:cu121
151
+ ```
152
+
153
+ ---
154
+
155
+ ## 6. Download Model Weights
156
+
157
+ Weights are stored in a named Docker volume so they persist across container
158
+ restarts and image upgrades. You only need to download them once.
159
+
160
+ ```bash
161
+ # Create a named volume
162
+ docker volume create hy-motion-weights
163
+
164
+ # Download all model weights (~30 GB, one-time)
165
+ docker run --rm --gpus all \
166
+ -v hy-motion-weights:/weights \
167
+ ghcr.io/poly-hammer/ph-hy-motion:latest \
168
+ download-weights --job hy-motion --all
169
+ ```
170
+
171
+ Replace `:latest` with `:cu121` if you chose the cu121 variant.
172
+
173
+ > **Tip:** You can also download a single model variant:
174
+ >
175
+ > ```bash
176
+ > docker run --rm --gpus all \
177
+ > -v hy-motion-weights:/weights \
178
+ > ghcr.io/poly-hammer/ph-hy-motion:latest \
179
+ > download-weights --job hy-motion --model hy-motion-1.0-lite
180
+ > ```
181
+
182
+ ---
183
+
184
+ ## 7. Start the Worker
185
+
186
+ You need a **worker registration token** from the Poly Hammer Portal.
187
+ Go to **Credentials > Tokens > Add Token** and select the
188
+ **Worker Registration** type.
189
+
190
+ ```bash
191
+ docker run -d --gpus all \
192
+ --restart unless-stopped \
193
+ --name ph-worker \
194
+ -v hy-motion-weights:/weights \
195
+ ghcr.io/poly-hammer/ph-hy-motion:latest \
196
+ start --token YOUR_WORKER_TOKEN
197
+ ```
198
+
199
+ The worker will:
200
+
201
+ 1. Register with the portal and receive Hatchet credentials
202
+ 2. Detect your GPU hardware
203
+ 3. Connect to the task orchestrator
204
+ 4. Begin accepting inference jobs
205
+
206
+ ### Custom Worker Name
207
+
208
+ By default the worker identifies itself as `{hostname}/{container_name}`.
209
+ Override it with `--name`:
210
+
211
+ ```bash
212
+ docker run -d --gpus all \
213
+ --restart unless-stopped \
214
+ --name ph-worker \
215
+ -v hy-motion-weights:/weights \
216
+ ghcr.io/poly-hammer/ph-hy-motion:latest \
217
+ start --token YOUR_WORKER_TOKEN --name "my-workstation"
218
+ ```
219
+
220
+ ---
221
+
222
+ ## 8. Verify the Worker
223
+
224
+ ### Check GPU Detection
225
+
226
+ ```bash
227
+ docker run --rm --gpus all ghcr.io/poly-hammer/ph-hy-motion:latest check-gpu
228
+ ```
229
+
230
+ Expected output:
231
+
232
+ ```
233
+ GPU detected
234
+ Model: NVIDIA GeForce RTX 4090
235
+ VRAM: 24.0 GB
236
+ CUDA: 13.1
237
+ CPU: 16 cores
238
+ RAM: 64.0 GB
239
+ ```
240
+
241
+ ### Check Worker Logs
242
+
243
+ ```bash
244
+ docker logs -f ph-worker
245
+ ```
246
+
247
+ ### Portal Status
248
+
249
+ Once connected, your worker will appear on the **Workers** page in the
250
+ portal with an **Active** status badge.
251
+
252
+ ---
253
+
254
+ ## Updating the Worker
255
+
256
+ When a new image version is published, pull and recreate:
257
+
258
+ ```bash
259
+ docker pull ghcr.io/poly-hammer/ph-hy-motion:latest
260
+ docker stop ph-worker && docker rm ph-worker
261
+
262
+ # Re-run with the same volume — no need to re-download weights
263
+ docker run -d --gpus all \
264
+ --restart unless-stopped \
265
+ --name ph-worker \
266
+ -v hy-motion-weights:/weights \
267
+ ghcr.io/poly-hammer/ph-hy-motion:latest \
268
+ start --token YOUR_WORKER_TOKEN
269
+ ```
270
+
271
+ ---
272
+
273
+ ## Troubleshooting
274
+
275
+ ### "No GPU detected"
276
+
277
+ - **Linux:** Make sure the NVIDIA Container Toolkit is installed and Docker is
278
+ restarted. Run `nvidia-smi` on the host to verify drivers are loaded.
279
+ - **Windows/WSL 2:** Make sure you're running Docker commands from inside WSL 2
280
+ (not PowerShell). Confirm the Windows NVIDIA driver is installed.
281
+ - **Both:** Ensure you're passing `--gpus all` to `docker run`.
282
+
283
+ ### "Permission denied" pulling from GHCR
284
+
285
+ - Log in with `docker login ghcr.io` using a PAT that has `read:packages` scope.
286
+ - Confirm your GitHub account has access to the `poly-hammer` org.
287
+
288
+ ### Worker shows "Inactive" in the portal
289
+
290
+ - The worker heartbeat is stale (>5 seconds since last ping). Check
291
+ `docker logs ph-worker` for connection errors.
292
+ - Verify your network allows outbound traffic to the portal and Hatchet gRPC
293
+ endpoint.
294
+
295
+ ### Out of VRAM errors
296
+
297
+ - The full **HY-Motion 1.0** model requires **40 GB VRAM** (A100, A6000).
298
+ - The **HY-Motion 1.0 Lite** model requires **24 GB VRAM** (RTX 3090, RTX 4090).
299
+ - If your GPU has less than 24 GB, it cannot run either model.
300
+
301
+ ### Wrong CUDA variant
302
+
303
+ If you see CUDA errors at runtime, you may have the wrong image variant for
304
+ your driver version. Check with `nvidia-smi` and pick the appropriate tag
305
+ (`:latest` for driver 570+, `:cu121` for driver 530+).
306
+
307
+ ---
308
+
309
+ ## Hardware Compatibility Reference
310
+
311
+ | GPU Family | Architecture | Example GPUs | Recommended Tag | Min Driver |
312
+ |------------|-------------|--------------|-----------------|------------|
313
+ | RTX 50xx | Blackwell | RTX 5090, RTX 5080 | `:latest` | 570+ |
314
+ | RTX 40xx | Ada Lovelace | RTX 4090, RTX 4080, RTX 4070 Ti | `:latest` or `:cu121` | 530+ |
315
+ | RTX 30xx | Ampere | RTX 3090, RTX 3080, A100, A6000 | `:latest` or `:cu121` | 530+ |
316
+ | RTX 20xx | Turing | RTX 2080 Ti, RTX 2070 | `:cu121` | 530+ |
317
+ | GTX 16xx | Turing | GTX 1660 Ti, GTX 1660 Super | `:cu121` | 530+ |
318
+ | Data Center | Hopper | H100, H200 | `:latest` | 530+ |
319
+
320
+ > **Note:** GTX 10xx (Pascal) and older GPUs are not supported.
@@ -0,0 +1 @@
1
+ """Poly Hammer self-hosted GPU worker — Docker-native Hatchet worker agent."""
@@ -0,0 +1,70 @@
1
+ """
2
+ HTTP client for the Poly Hammer Portal worker API.
3
+
4
+ Used during worker startup to exchange a portal worker-registration token
5
+ for Hatchet credentials via ``POST /v1/workers/register``.
6
+ """
7
+
8
+ import logging
9
+ from dataclasses import dataclass
10
+
11
+ import httpx
12
+
13
+ logger = logging.getLogger(__name__)
14
+
15
+
16
+ @dataclass(frozen=True)
17
+ class RegistrationResult:
18
+ """Credentials returned by the portal registration endpoint."""
19
+
20
+ hatchet_token: str
21
+ grpc_host: str
22
+ tls_strategy: str
23
+ user_id: str
24
+ portal_token_id: str
25
+
26
+
27
+ class PortalClient:
28
+ """Thin HTTP client for the portal worker registration API."""
29
+
30
+ def __init__(self, portal_url: str, worker_token: str) -> None:
31
+ self._base_url = portal_url.rstrip("/")
32
+ self._token = worker_token
33
+
34
+ def register(self) -> RegistrationResult:
35
+ """Exchange the worker-registration token for Hatchet credentials.
36
+
37
+ Calls ``POST /v1/workers/register`` with the portal token and
38
+ returns the Hatchet JWT, gRPC host, TLS strategy, and user ID.
39
+ """
40
+ url = f"{self._base_url}/v1/workers/register"
41
+ headers = {"Authorization": f"Bearer {self._token}"}
42
+
43
+ resp = httpx.post(url, headers=headers, timeout=15)
44
+
45
+ if resp.status_code == 401:
46
+ raise SystemExit(
47
+ "Authentication failed. Check that your --token is a valid "
48
+ "WORKER_REGISTRATION token from the portal."
49
+ )
50
+ if resp.status_code == 503:
51
+ raise SystemExit(
52
+ "Hatchet is not configured on this portal instance. "
53
+ "Contact the portal administrator."
54
+ )
55
+ resp.raise_for_status()
56
+
57
+ data = resp.json()
58
+ result = RegistrationResult(
59
+ hatchet_token=data["hatchet_token"],
60
+ grpc_host=data["grpc_host"],
61
+ tls_strategy=data["tls_strategy"],
62
+ user_id=data["user_id"],
63
+ portal_token_id=data["portal_token_id"],
64
+ )
65
+ logger.info(
66
+ "Registered with portal (user=%s, grpc=%s)",
67
+ result.user_id,
68
+ result.grpc_host,
69
+ )
70
+ return result