1e355e6138e7af4999f0127529fdb5c2a0d08208
README: - 新增「离线部署(导入预构建镜像)」章节:docker load + 启动命令 - 功能特性更新:设置页、任务删除、进度细分、离线运行、/docs 公开 docs/DOCKER.md: - 新增「导入预构建镜像(离线部署)」完整章节: 前置要求、导出步骤、需拷贝文件清单、导入启动命令、离线说明、后续更新代码 .gitignore: - 排除 *.tar(导出的镜像文件不入库)
audio2text
音频 / 视频转双语字幕服务。上传视频 → ffmpeg 提取音频 → faster-whisper 识别英语 → 断句 + 时间戳重算 → NLLB 翻译为中文 → 输出双语 SRT。全程跑在 Docker 容器里,自带 网页上传界面,支持大文件分片上传与断点续传。
仿照 zikai 的 server/ 风格分层(controllers → services),CPU 开发 / GPU 生产
同一份代码,仅靠 config.yaml 的 device + model + compute_type 三项切换。
功能特性
- 网页上传:拖拽 / 选择文件,多文件并发、4 MiB 分片、断点续传
- 双语字幕:英文在上、中文在下,亦可单独下载英文 / 中文字幕
- faster-whisper 转写:词级时间戳,断句精确(取首末词时间戳)
- NLLB-200 英译中:ASR 与翻译模型不共驻,翻译时独占显存跑大 batch
- 设置页:运行时调整 batch_size / beam_size,保存后对后续任务生效(DB 持久化)
- 任务管理:删除已完成/失败任务及其产物,进度条按批次细分
- 任务状态机:
queued -> uploading -> extracting -> transcribing -> segmenting -> translating -> done - 实时日志页:按级别分层(debug=详细子步骤 / info=阶段转换 / error=完整 traceback)
- 定时缓存清理:任务产物默认保留 7 天,超期连同 DB 记录一并删除
- SQLite 持久化(自包含,无需外部 DB)
- 离线运行:模型缓存就位后完全离线,无需访问 HuggingFace
/docs(Swagger UI)公开访问
架构
Spring 风格分层,HTTP 边界(controllers)与业务逻辑(services)分离:
audio2text/
├── Dockerfile # 一份 Dockerfile,ARG VARIANT=cpu|gpu 出两个镜像
├── docker-compose.yml # cpu / gpu / dev 三个 profile
├── setup.sh / start.sh / stop.sh # 安装 / 启动 / 停止(包装 docker 命令)
├── scripts/
│ └── prefetch_models.{sh,py} # 预拉模型权重到 ./models volume(避免首次启动下载)
├── requirements.txt
├── config.example.yaml # 配置模板(复制为 config.yaml 后填值)
├── docs/ # 详细文档(见下方索引)
└── app/
├── main.py # FastAPI 应用工厂
├── config.py # 从 config.yaml 加载的类型化 Settings(pydantic)
├── database.py # SQLite 引擎 / Session / Base / get_db
├── security.py # /docs 的 Basic Auth(常量时间比较)
├── controllers/ # FastAPI 路由 —— HTTP 边界
│ ├── upload_router.py # 分片上传(建会话/查状态/传片/complete)
│ └── task_router.py # 任务列表 / 状态 / 下载字幕
├── services/ # 业务逻辑
│ ├── types.py # 共享 DTO(Word/Segment/Subtitle,纯 dataclass)
│ ├── upload_service.py # 分片上传会话 + 拼接 + 创建任务
│ ├── ffmpeg_service.py # 提取音频 16k mono pcm
│ ├── asr_service.py # faster-whisper 转写
│ ├── segmenter.py # 断句 + 时间戳重算(纯算法,零模型依赖)
│ ├── translate_service.py # NLLB 翻译
│ ├── model_manager.py # 模型加载/卸载(不共驻核心)
│ ├── scheduler.py # ffmpeg 串行队列 + GPU 调度线程
│ ├── pipeline.py # 编排:提取→识别→断句→翻译→写SRT
│ ├── srt_writer.py # SRT 写入 + 双语合并
│ ├── log_buffer.py # 内存日志缓冲(供 /logs 页面查询)
│ ├── reaper.py # 清理被放弃的上传会话(短 TTL)
│ └── cache_cleaner.py # 定时清理超期任务产物 + 孤儿目录(长保留期)
├── models/ # SQLAlchemy ORM
│ ├── task.py # Task(转写任务,状态机)
│ └── upload_session.py # UploadSession(分片会话,含 task_id FK)
├── schemas/ # pydantic 请求/响应 DTO
│ └── task.py
└── views/
├── _shared.py # 共享前端资产(BASE_CSS + SHARED_JS + 上传协议 + 页面骨架)
├── home_html.py # 主页(上传入口 + 最近任务卡片)
├── history_html.py # 历史任务分页表格(含搜索)
└── logs_html.py # 实时日志页
数据流
浏览器 /(主页)
│ 分片上传 (4 MiB/片, 可断点续传)
▼
upload_router ──► upload_service ──► UploadSession(SQLite) + 分片落盘
│ complete
▼
创建 Task(queued) ──► scheduler
│
├─ ffmpeg 串行队列(最多 1 个并发,其余排队)→ 16k mono wav
│ (按配置删原始视频)
├─ GPU 调度线程(单线程,模型复用):
│ get_asr → asr_service.transcribe → segments(带词级时间戳)
│ unload_asr → get_translator
│ translate_service.translate → 中文译文(独占显存大 batch)
└─ srt_writer → en.srt / zh.srt / bilingual.srt
更新 Task(done) + 写 output_dir
快速开始
CPU 开发环境(2GB 内存即可)
./setup.sh # 构建镜像 + 生成 config.yaml
./start.sh # 启动容器(端口 8000)
GPU 生产环境(需 NVIDIA GPU + nvidia runtime)
AUDIO2TEXT_VARIANT=gpu ./setup.sh
./start.sh # 自动检测 GPU 镜像 + nvidia-smi,端口 8001
启动后打开 http://127.0.0.1:8000/,拖入视频即可。详细部署流程、模型选型、CPU↔GPU 切换
见 部署指南。
离线部署(导入预构建镜像)
已有 audio2text-gpu.tar 镜像文件时,新机器无需构建,直接导入即可启动(仍需 NVIDIA 驱动 +
nvidia container runtime + 模型缓存 ./models):
# 1. 导入镜像
docker load -i audio2text-gpu.tar
# 2. 准备配置 + 数据目录
mkdir -p data-gpu/uploads data-gpu/.work data-gpu/outputs models
# 3. 启动容器(config.gpu.yaml 需自行准备,或从项目仓库取)
docker run -d --name audio2text-gpu \
--gpus all \
-p 8001:8000 \
-v "$(pwd)/data-gpu:/data" \
-v "$(pwd)/models:/models" \
-v "$(pwd)/config.gpu.yaml:/app/config.yaml:ro" \
--restart unless-stopped \
audio2text:gpu
模型缓存:
./models目录需包含 Whisperlarge-v3-turbo+ NLLBdistilled-1.3B权重 (约 5.5GB)。首次部署时从源机器拷贝models/目录,或联网用prefetch_models.sh预拉。 镜像内置HF_HUB_OFFLINE=1,模型就位后完全离线运行,无需访问 HuggingFace。
详细步骤见 Docker 说明 - 导入预构建镜像。
入口
| 入口 | 地址 |
|---|---|
| 主页(上传 + 最近任务) | http://127.0.0.1:8000/ |
| 历史任务 | http://127.0.0.1:8000/history |
| 实时日志 | http://127.0.0.1:8000/logs |
| API 文档 | http://127.0.0.1:8000/docs(Basic Auth) |
| 健康检查 | http://127.0.0.1:8000/health |
文档索引
详细文档按主题拆分,主页只保留核心速览:
| 文档 | 内容 |
|---|---|
| 部署指南 | CPU / GPU 完整部署流程、前置要求、模型选型、CPU↔GPU 切换、自定义端口 |
| 配置文件说明 | CPU/GPU 配置差异表、全部字段说明(server/storage/asr/translation/...)、配置示例 |
| Docker 说明 | 镜像构建、新建/重建/改配置/改依赖四种场景、缓存分层与删除边界、⚠️ until filter 失效根因、Volume 挂载 |
| HTTP 接口 | 接口一览表、分片上传协议、请求/响应示例 |
| 架构与原理 | 断句算法、模型不共驻显存策略、GPU 利用率优化、缓存清理机制 |
| 常见问题 | CPU 跑 NLLB、模型下载、断点续传、保留原始视频、自动清理等 |
依赖
- Python:FastAPI + uvicorn + SQLAlchemy + faster-whisper + transformers(torch 按 VARIANT 分叉,CPU/GPU 装不同 wheel)。完整列表见
requirements.txt - 系统:ffmpeg(镜像内 apt 装)、patchelf(修复 ctranslate2 可执行栈)。GPU 需宿主 NVIDIA 驱动 + nvidia container runtime
镜像构建与依赖安装细节见 Docker 说明。
Description
Languages
Python
92.6%
Dockerfile
4.2%
Shell
3.2%