Deploy Tencent's Hunyuan3D as a RunPod serverless endpoint for image-to-3D generation with PBR textures.
This endpoint combines three model components:
| Component | Model Size | VRAM | Description |
|---|---|---|---|
| Omni | 3.3B | ~10GB | Quality shape generation (default), supports pose/skeleton |
| Mini-Fast | 0.6B | ~5GB | Fast shape generation (fast_mode=true) |
| Paint 2.1 | 2B | ~21GB | PBR texture synthesis |
This deployment uses a prebuilt Linux wheel for the custom_rasterizer CUDA extension, avoiding compilation issues during Docker builds (no GPU available at build time).
Requirements:
RunPod clones your GitHub repo and builds the Dockerfile on their infrastructure.
# Create a new repo or use existing one
git init
git add Dockerfile handler.py test_input.json README.md
git commit -m "Hunyuan3D-2.1 RunPod serverless worker"
git remote add origin https://github.com/YOUR_USER/hunyuan3d-runpod.git
git push -u origin main
Dockerfile (or leave default if in root)Build stages:
Check logs if build fails. Common issues:
Changes to your repo don't auto-deploy. To update:
| Limit | Value |
|---|---|
| Max build time | 30 minutes |
| GPU during build | Not available (why prebuilt wheel is essential) |
# Test with RunPod SDK local server
python handler.py --rp_serve_api --rp_log_level DEBUG
# Send test request
curl -X POST http://localhost:8000/runsync \
-H "Content-Type: application/json" \
-d @test_input.json
# Submit a job
curl -X POST https://api.runpod.ai/v2/YOUR_ENDPOINT_ID/run \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"input": {
"image_base64": "'$(base64 -w0 input.png)'",
"generate_texture": true,
"output_format": "glb"
}
}'
# Check status
curl https://api.runpod.ai/v2/YOUR_ENDPOINT_ID/status/JOB_ID \
-H "Authorization: Bearer YOUR_API_KEY"
| Parameter | Type | Default | Description |
|---|---|---|---|
image_base64 | string | required | Base64 encoded input image |
fast_mode | boolean | false | Use Mini-Fast (0.6B) instead of Omni (3.3B) for faster inference |
skeleton_base64 | string | optional | Base64 encoded skeleton/pose file (Omni only) |
skeleton_data | array | optional | Bone coordinates as JSON array (Omni only) |
generate_texture | boolean | true | Generate PBR textures |
output_format | string | "glb" | Output format: "glb" or "obj" |
num_views | integer | 6 | Number of views for texture synthesis |
texture_resolution | integer | 512 | Texture map resolution |
{
"download_url": "https://s3api-eur-is-1.runpod.io/...",
"s3_key": "outputs/job-id/model.glb",
"format": "glb",
"textured": true,
"size_mb": 12.34
}
import requests
# From the API response
result = response.json()["output"]
# Download from presigned URL
model_data = requests.get(result["download_url"]).content
with open(f"output.{result['format']}", "wb") as f:
f.write(model_data)
| Variable | Default | Description |
|---|---|---|
MAX_NUM_VIEW | 6 | Default number of texture views |
TEXTURE_RESOLUTION | 512 | Default texture resolution |
HF_HOME | /runpod-volume/models | HuggingFace cache directory |
RunPod has payload size limits:
/run endpoint: 10 MB maximum/runsync endpoint: 20 MB maximumFor larger images, consider:
The prebuilt wheel wasn't installed correctly. Check:
python -c "import custom_rasterizer; print('OK')"Reduce texture settings:
{
"input": {
"image_base64": "...",
"num_views": 4,
"texture_resolution": 256
}
}
Or disable textures entirely: "generate_texture": false
Models are loaded from Network Volume on first request. Cold starts typically take 30-60s for model loading. To reduce:
Default timeout is 600s. For high-resolution textures, increase via RunPod endpoint settings.
Dockerfile - Container build configurationhandler.py - RunPod serverless handlertest_input.json - Sample test input for local testingREADME.md - This documentation5 commits
1 commits
Python
87.1%
Dockerfile
12.9%
Deploy Tencent's Hunyuan3D as a RunPod serverless endpoint for image-to-3D generation with PBR textures.
This endpoint combines three model components:
| Component | Model Size | VRAM | Description |
|---|---|---|---|
| Omni | 3.3B | ~10GB | Quality shape generation (default), supports pose/skeleton |
| Mini-Fast | 0.6B | ~5GB | Fast shape generation (fast_mode=true) |
| Paint 2.1 | 2B | ~21GB | PBR texture synthesis |
This deployment uses a prebuilt Linux wheel for the custom_rasterizer CUDA extension, avoiding compilation issues during Docker builds (no GPU available at build time).
Requirements:
RunPod clones your GitHub repo and builds the Dockerfile on their infrastructure.
# Create a new repo or use existing one
git init
git add Dockerfile handler.py test_input.json README.md
git commit -m "Hunyuan3D-2.1 RunPod serverless worker"
git remote add origin https://github.com/YOUR_USER/hunyuan3d-runpod.git
git push -u origin main
Dockerfile (or leave default if in root)Build stages:
Check logs if build fails. Common issues:
Changes to your repo don't auto-deploy. To update:
| Limit | Value |
|---|---|
| Max build time | 30 minutes |
| GPU during build | Not available (why prebuilt wheel is essential) |
# Test with RunPod SDK local server
python handler.py --rp_serve_api --rp_log_level DEBUG
# Send test request
curl -X POST http://localhost:8000/runsync \
-H "Content-Type: application/json" \
-d @test_input.json
# Submit a job
curl -X POST https://api.runpod.ai/v2/YOUR_ENDPOINT_ID/run \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"input": {
"image_base64": "'$(base64 -w0 input.png)'",
"generate_texture": true,
"output_format": "glb"
}
}'
# Check status
curl https://api.runpod.ai/v2/YOUR_ENDPOINT_ID/status/JOB_ID \
-H "Authorization: Bearer YOUR_API_KEY"
| Parameter | Type | Default | Description |
|---|---|---|---|
image_base64 | string | required | Base64 encoded input image |
fast_mode | boolean | false | Use Mini-Fast (0.6B) instead of Omni (3.3B) for faster inference |
skeleton_base64 | string | optional | Base64 encoded skeleton/pose file (Omni only) |
skeleton_data | array | optional | Bone coordinates as JSON array (Omni only) |
generate_texture | boolean | true | Generate PBR textures |
output_format | string | "glb" | Output format: "glb" or "obj" |
num_views | integer | 6 | Number of views for texture synthesis |
texture_resolution | integer | 512 | Texture map resolution |
{
"download_url": "https://s3api-eur-is-1.runpod.io/...",
"s3_key": "outputs/job-id/model.glb",
"format": "glb",
"textured": true,
"size_mb": 12.34
}
import requests
# From the API response
result = response.json()["output"]
# Download from presigned URL
model_data = requests.get(result["download_url"]).content
with open(f"output.{result['format']}", "wb") as f:
f.write(model_data)
| Variable | Default | Description |
|---|---|---|
MAX_NUM_VIEW | 6 | Default number of texture views |
TEXTURE_RESOLUTION | 512 | Default texture resolution |
HF_HOME | /runpod-volume/models | HuggingFace cache directory |
RunPod has payload size limits:
/run endpoint: 10 MB maximum/runsync endpoint: 20 MB maximumFor larger images, consider:
The prebuilt wheel wasn't installed correctly. Check:
python -c "import custom_rasterizer; print('OK')"Reduce texture settings:
{
"input": {
"image_base64": "...",
"num_views": 4,
"texture_resolution": 256
}
}
Or disable textures entirely: "generate_texture": false
Models are loaded from Network Volume on first request. Cold starts typically take 30-60s for model loading. To reduce:
Default timeout is 600s. For high-resolution textures, increase via RunPod endpoint settings.
Dockerfile - Container build configurationhandler.py - RunPod serverless handlertest_input.json - Sample test input for local testingREADME.md - This documentation5 commits
1 commits
Python
87.1%
Dockerfile
12.9%