Files
audio2text/README.md

199 lines
8.9 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# audio2text
音频 / 视频转双语字幕服务。上传视频 → ffmpeg 提取音频 → faster-whisper 识别英语 →
断句 + 时间戳重算 → NLLB 翻译为中文 → 输出双语 SRT。全程跑在 Docker 容器里,自带
网页上传界面,支持大文件分片上传与断点续传。
仿照 zikai 的 `server/` 风格分层(`controllers → services`**CPU 开发 / GPU 生产
同一份代码**,仅靠 `config.yaml``device` + `model` + `compute_type` 三项切换。
---
## 快速开始
### GPU 环境(需 NVIDIA GPU + nvidia runtime
```bash
AUDIO2TEXT_VARIANT=gpu ./setup.sh
./start.sh # 端口 8001
```
启动后打开 `http://127.0.0.1:8000/`拖入视频即可。详细部署流程、模型选型、CPU↔GPU 切换
见 [部署指南](./docs/DEPLOYMENT.md)。
---
## 功能特性
- **网页上传**:拖拽 / 选择文件多文件并发、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 # 一份 DockerfileARG 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 加载的类型化 Settingspydantic
├── 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 # 共享 DTOWord/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 内存即可)
```bash
./setup.sh # 构建镜像 + 生成 config.yaml
./start.sh # 启动容器(端口 8000
```
### GPU 生产环境(需 NVIDIA GPU + nvidia runtime
```bash
AUDIO2TEXT_VARIANT=gpu ./setup.sh
./start.sh # 自动检测 GPU 镜像 + nvidia-smi端口 8001
```
启动后打开 `http://127.0.0.1:8000/`拖入视频即可。详细部署流程、模型选型、CPU↔GPU 切换
见 [部署指南](./docs/DEPLOYMENT.md)。
---
## 离线部署(导入预构建镜像)
已有 `audio2text-gpu.tar` 镜像文件时,新机器无需构建,直接导入即可启动(仍需 NVIDIA 驱动 +
nvidia container runtime + 模型缓存 `./models`
```bash
# 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` 目录需包含 Whisper `large-v3-turbo` + NLLB `distilled-1.3B` 权重
> (约 5.5GB)。首次部署时从源机器拷贝 `models/` 目录,或联网用 `prefetch_models.sh` 预拉。
> 镜像内置 `HF_HUB_OFFLINE=1`,模型就位后完全离线运行,无需访问 HuggingFace。
详细步骤见 [Docker 说明 - 导入预构建镜像](./docs/DOCKER.md#导入预构建镜像离线部署)。
---
## 入口
| 入口 | 地址 |
|---|---|
| 主页(上传 + 最近任务) | `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` |
| 健康检查 | `http://127.0.0.1:8000/health` |
---
## 文档索引
详细文档按主题拆分,主页只保留核心速览:
| 文档 | 内容 |
|---|---|
| [部署指南](./docs/DEPLOYMENT.md) | CPU / GPU 完整部署流程、前置要求、模型选型、CPU↔GPU 切换、自定义端口 |
| [配置文件说明](./docs/CONFIG.md) | CPU/GPU 配置差异表、全部字段说明server/storage/asr/translation/...)、配置示例 |
| [Docker 说明](./docs/DOCKER.md) | 镜像构建、新建/重建/改配置/改依赖四种场景、**缓存分层与删除边界**、⚠️ until filter 失效根因、Volume 挂载 |
| [HTTP 接口](./docs/API.md) | 接口一览表、分片上传协议、请求/响应示例 |
| [架构与原理](./docs/ARCHITECTURE.md) | 断句算法、模型不共驻显存策略、GPU 利用率优化、缓存清理机制 |
| [常见问题](./docs/FAQ.md) | CPU 跑 NLLB、模型下载、断点续传、保留原始视频、自动清理等 |
---
## 依赖
- **Python**FastAPI + uvicorn + SQLAlchemy + faster-whisper + transformerstorch 按 VARIANT 分叉CPU/GPU 装不同 wheel。完整列表见 `requirements.txt`
- **系统**ffmpeg镜像内 apt 装、patchelf修复 ctranslate2 可执行栈。GPU 需宿主 NVIDIA 驱动 + nvidia container runtime
镜像构建与依赖安装细节见 [Docker 说明](./docs/DOCKER.md)。