cwchang commited on
Commit
8d33c35
·
1 Parent(s): 62132be

feat: add Hugging Face Spaces Docker deployment

Browse files

- Multi-stage Dockerfile for frontend + backend
- Automatic model download from Hugging Face Hub
- Nginx reverse proxy on port 7860
- CPU-only deployment (8-12GB RAM)
- Environment detection for API URL configuration

Files changed (4) hide show
  1. .dockerignore +54 -0
  2. Dockerfile.huggingface +113 -0
  3. README-HF.md +64 -0
  4. docker-entrypoint.sh +35 -0
.dockerignore ADDED
@@ -0,0 +1,54 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+ *.so
6
+ .Python
7
+ build/
8
+ env/
9
+ venv/
10
+ .venv
11
+
12
+ # Node - 注意:為了 HF Spaces,我們保留 node_modules
13
+ # node_modules/
14
+ npm-debug.log*
15
+ yarn-debug.log*
16
+ yarn-error.log*
17
+
18
+ # Docker
19
+ .dockerignore
20
+ docker-compose*.yml
21
+ Dockerfile*
22
+ !Dockerfile.huggingface
23
+
24
+ # Git
25
+ .git/
26
+ .gitignore
27
+
28
+ # IDE
29
+ .vscode/
30
+ .idea/
31
+ *.swp
32
+
33
+ # 上傳和輸出(運行時生成)
34
+ backend/uploads/
35
+ backend/outputs/
36
+ outputs/
37
+
38
+ # 模型(運行時下載)
39
+ models/
40
+
41
+ # 環境變數
42
+ .env
43
+ .env.local
44
+
45
+ # 文檔和腳本
46
+ *.md
47
+ !README-HF.md
48
+ *.sh
49
+ !docker-entrypoint.sh
50
+
51
+ # 測試
52
+ *.log
53
+ .pytest_cache/
54
+ .coverage
Dockerfile.huggingface ADDED
@@ -0,0 +1,113 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Dockerfile for Hugging Face Spaces
2
+ # 完整的前端 + 後端部署
3
+
4
+ # Stage 1: 構建前端
5
+ FROM node:20-alpine AS frontend-builder
6
+
7
+ WORKDIR /app/frontend
8
+
9
+ # 複製前端文件
10
+ COPY frontend/package.json frontend/yarn.lock ./
11
+ COPY frontend/node_modules ./node_modules
12
+ COPY frontend/ ./
13
+
14
+ # 設置 API URL(HF Spaces 使用同一域名)
15
+ ENV VITE_API_URL=/api
16
+
17
+ # 構建前端
18
+ RUN yarn build
19
+
20
+ # Stage 2: 後端 + 前端服務
21
+ FROM python:3.12-slim
22
+
23
+ WORKDIR /app
24
+
25
+ # 安裝系統依賴
26
+ RUN apt-get update && apt-get install -y \
27
+ git \
28
+ wget \
29
+ curl \
30
+ build-essential \
31
+ libsndfile1 \
32
+ libsndfile1-dev \
33
+ ffmpeg \
34
+ sox \
35
+ libsox-dev \
36
+ libsox-fmt-all \
37
+ libavcodec-dev \
38
+ libavformat-dev \
39
+ libavutil-dev \
40
+ libswresample-dev \
41
+ nginx \
42
+ && rm -rf /var/lib/apt/lists/*
43
+
44
+ # 安裝 uv
45
+ RUN pip install --no-cache-dir uv
46
+
47
+ # 複製後端代碼
48
+ COPY pyproject.toml /app/
49
+ COPY backend /app/backend
50
+
51
+ # 安裝 Python 依賴
52
+ RUN uv pip install --system --no-cache \
53
+ torch==2.5.1 torchvision==0.20.1 torchaudio==2.5.1 \
54
+ --index-url https://download.pytorch.org/whl/cpu && \
55
+ uv pip install --system --no-cache \
56
+ qwen-tts \
57
+ fastapi \
58
+ uvicorn[standard] \
59
+ python-multipart \
60
+ soundfile \
61
+ huggingface-hub \
62
+ tqdm
63
+
64
+ # 從前端構建階段複製靜態文件
65
+ COPY --from=frontend-builder /app/frontend/dist /app/frontend/dist
66
+
67
+ # 創建必要目錄
68
+ RUN mkdir -p /app/backend/uploads /app/backend/outputs
69
+
70
+ # Nginx 配置
71
+ RUN echo 'server { \n\
72
+ listen 7860; \n\
73
+ server_name _; \n\
74
+ \n\
75
+ # 前端靜態文件 \n\
76
+ location / { \n\
77
+ root /app/frontend/dist; \n\
78
+ try_files $uri $uri/ /index.html; \n\
79
+ } \n\
80
+ \n\
81
+ # API 代理到後端 \n\
82
+ location /api { \n\
83
+ proxy_pass http://127.0.0.1:8000; \n\
84
+ proxy_http_version 1.1; \n\
85
+ proxy_set_header Upgrade $http_upgrade; \n\
86
+ proxy_set_header Connection "upgrade"; \n\
87
+ proxy_set_header Host $host; \n\
88
+ proxy_set_header X-Real-IP $remote_addr; \n\
89
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; \n\
90
+ proxy_set_header X-Forwarded-Proto $scheme; \n\
91
+ proxy_read_timeout 300s; \n\
92
+ } \n\
93
+ }' > /etc/nginx/sites-available/default
94
+
95
+ # 環境變數
96
+ ENV PYTHONUNBUFFERED=1
97
+ ENV MODEL_PATH=/app/models/Qwen3-TTS-12Hz-1.7B-Base
98
+ ENV UPLOAD_DIR=/app/backend/uploads
99
+ ENV OUTPUT_DIR=/app/backend/outputs
100
+ ENV USE_CPU=true
101
+
102
+ # 暴露 HF Spaces 端口
103
+ EXPOSE 7860
104
+
105
+ # 健康檢查
106
+ HEALTHCHECK --interval=30s --timeout=10s --start-period=120s --retries=3 \
107
+ CMD curl -f http://localhost:7860/api/status || exit 1
108
+
109
+ # 啟動腳本
110
+ COPY docker-entrypoint.sh /app/
111
+ RUN chmod +x /app/docker-entrypoint.sh
112
+
113
+ CMD ["/app/docker-entrypoint.sh"]
README-HF.md ADDED
@@ -0,0 +1,64 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ title: Qwen3-TTS Voice Clone
3
+ emoji: 🎤
4
+ colorFrom: blue
5
+ colorTo: purple
6
+ sdk: docker
7
+ pinned: false
8
+ license: apache-2.0
9
+ ---
10
+
11
+ # 🎤 Qwen3-TTS 語音複製
12
+
13
+ 基於 Qwen3-TTS-12Hz-1.7B-Base 的全功能語音複製應用。
14
+
15
+ ## ✨ 功能特色
16
+
17
+ - 🎯 **3秒快速複製**: 僅需 3-10 秒參考音訊
18
+ - 🌏 **多語言支持**: 中、英、日、韓等 10 種語言
19
+ - 🎨 **高相似度**: 聲音相似度可達 95%
20
+ - 💻 **完整 Web UI**: React 前端 + FastAPI 後端
21
+ - 🚀 **即開即用**: 模型自動下載
22
+
23
+ ## 🚀 使用方法
24
+
25
+ 1. 上傳 3-10 秒的參考音訊(清晰人聲)
26
+ 2. 輸入參考音訊的逐字稿
27
+ 3. 輸入想要生成的目標文字
28
+ 4. 選擇語言
29
+ 5. 點擊「複製並生成」
30
+
31
+ ## 📊 效能說明
32
+
33
+ - **CPU 模式**: 10-20 秒/次
34
+ - **記憶體**: 約 8-12GB
35
+ - **模型大小**: 4.3GB
36
+
37
+ ## 🛠️ 技術棧
38
+
39
+ - **前端**: React + TypeScript + Tailwind CSS
40
+ - **後端**: FastAPI + Python
41
+ - **模型**: Qwen3-TTS-12Hz-1.7B-Base
42
+ - **部署**: Docker
43
+
44
+ ## 📝 本地運行
45
+
46
+ ```bash
47
+ # Clone 項目
48
+ git clone https://huggingface.co/spaces/你的用戶名/qwen3-tts-clone
49
+ cd qwen3-tts-clone
50
+
51
+ # 使用 Docker
52
+ docker build -f Dockerfile.huggingface -t qwen3-tts .
53
+ docker run -p 7860:7860 qwen3-tts
54
+ ```
55
+
56
+ 訪問: http://localhost:7860
57
+
58
+ ## 🤝 貢獻
59
+
60
+ 基於 [Qwen3-TTS](https://github.com/QwenLM/Qwen3-TTS) by Alibaba Qwen Team
61
+
62
+ ## 📄 授權
63
+
64
+ Apache 2.0 License
docker-entrypoint.sh ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/bin/bash
2
+ set -e
3
+
4
+ echo "🚀 啟動 Qwen3-TTS 服務..."
5
+
6
+ # 下載模型(如果不存在)
7
+ if [ ! -d "$MODEL_PATH" ]; then
8
+ echo "📥 下載模型..."
9
+ mkdir -p /app/models
10
+
11
+ python3 << 'PYTHON'
12
+ from huggingface_hub import snapshot_download
13
+ import os
14
+
15
+ model_path = os.environ.get('MODEL_PATH', '/app/models/Qwen3-TTS-12Hz-1.7B-Base')
16
+ print(f"下載模型到: {model_path}")
17
+
18
+ snapshot_download(
19
+ repo_id="Qwen/Qwen3-TTS-12Hz-1.7B-Base",
20
+ local_dir=model_path,
21
+ local_dir_use_symlinks=False,
22
+ )
23
+ print("✅ 模型下載完成")
24
+ PYTHON
25
+ else
26
+ echo "✅ 模型已存在"
27
+ fi
28
+
29
+ # 啟動 Nginx(前端)
30
+ echo "🌐 啟動 Nginx(端口 7860)..."
31
+ nginx
32
+
33
+ # 啟動後端
34
+ echo "🔧 啟動後端 API(端口 8000)..."
35
+ uvicorn backend.main:app --host 127.0.0.1 --port 8000