Files
audio2text/Dockerfile
audio2text dev 7635e5e766 feat: 设置页调 batch_size + 删除任务 + /docs 去认证 + 离线模式
设置页(/settings):
- 新增 Setting DB 模型(键值存储,持久化运行时覆盖)
- config.py 加 _apply_overrides:get_settings() 合并 DB 覆盖值
  (_applying_overrides 标志防递归:DB 初始化回调 get_settings 时不重入)
- save_setting() 写 DB + 清 lru_cache,后续任务读到新值
- settings_router.py: GET/PUT /api/settings
- settings_html.py: 设置页表单(batch_size/beam_size/sort_by_length)
  + 设备只读信息 + 保存后 reload 确认
- 验证:改 asr_batch_size=16 beam_size=1 -> 任务 ASR 日志确认生效
- 验证:重启容器后设置从 DB 恢复(持久化)

删除任务:
- task_router.py: DELETE /api/tasks/{id},仅 done/failed 可删
  删字幕/音频/视频产物 + UploadSession + Task DB 记录
- home_html.py + history_html.py: done/failed 任务显示删除按钮
  + confirm 确认 + 调用 DELETE API + 刷新列表
- 验证:删除 task 15 成功,删除进行中 task 返回 409

/docs 去认证:
- 移除 require_docs_auth 依赖,/docs /redoc /openapi.json 直接公开

离线模式:
- Dockerfile dev/final 加 HF_HUB_OFFLINE=1 TRANSFORMERS_OFFLINE=1
  (模型已缓存在 ./models volume,无需联网验证)
- 验证:离线模式完整跑通 ASR+翻译(task 15 done)
2026-07-11 11:33:34 +08:00

129 lines
7.1 KiB
Docker
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.

# syntax=docker/dockerfile:1.7
# audio2text — 一份 DockerfileCPU(dev) / GPU(prod) 双形态。
# docker build --build-arg VARIANT=cpu -t audio2text:cpu .
# docker build --build-arg VARIANT=gpu -t audio2text:gpu .
# docker compose --profile dev up -d --build # 开发dev target + 源码挂载 + reload
#
# 分层目标:依赖层(deps)稳定固化,代码层(final/dev)在最末,改代码不重装依赖。
# BuildKit 缓存挂载(--mount=type=cache)pip wheel 跨构建复用,二次构建秒级。
#
# 安全约束PyTorch CPU wheel 与 GPU(CUDA) wheel 是两个不兼容二进制包。
# - CPU 版 torch.cuda.is_available()=FalseCPU 预期)
# - GPU 版 torch.cuda.is_available()=TrueGPU 可调度)
# 因此 torch 必须按 VARIANT 分叉装不同 wheel绝不能跨 variant 共享依赖层。
# deps 阶段用 FROM base-${VARIANT}CPU/GPU 是两条独立构建链,各自装对应 torch。
ARG VARIANT=cpu
# ---------------------------------------------------------------------------
# 1. 基础镜像分叉CPU 用 slim PythonGPU 用 CUDA runtime + 手动装 python3.12
# ---------------------------------------------------------------------------
FROM python:3.12-slim AS base-cpu
FROM nvidia/cuda:12.1.0-runtime-ubuntu22.04 AS base-gpu
# Ubuntu 22.04 默认源只有 python3.10/3.11,需加 deadsnakes PPA 才能装 python3.12。
# 注意:不能用 python3-pip那是 3.10 的系统 pip会把包装到 3.10 site-packages
# 用 python3.12 -m ensurepip 给 3.12 装 pip确保所有包进 3.12 目录。
# DEBIAN_FRONTEND=noninteractive 避免 tzdata 等包进入交互式配置卡住构建。
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update -y && apt-get install -y --no-install-recommends \
software-properties-common gnupg ca-certificates \
&& add-apt-repository -y ppa:deadsnakes/ppa \
&& apt-get update -y && apt-get install -y --no-install-recommends \
python3.12 python3.12-venv python3.12-dev \
&& rm -rf /var/lib/apt/lists/* \
&& ln -sf /usr/bin/python3.12 /usr/local/bin/python3 \
&& ln -sf /usr/bin/python3.12 /usr/local/bin/python \
&& python3 -m ensurepip \
&& python3 -m pip install --upgrade pip
# ---------------------------------------------------------------------------
# 2. deps系统依赖 + Python 依赖(含 torch。CPU/GPU 各自一条独立链。
# final / dev 都 FROM deps继承对应 variant 的 torch不串。
# ---------------------------------------------------------------------------
FROM base-${VARIANT} AS deps
ARG VARIANT
ENV PYTHONUNBUFFERED=1 \
PIP_NO_CACHE_DIR=1 \
HF_HOME=/models/huggingface \
CT2_CACHE=/models/ctranslate2
# ffmpeg 是核心系统依赖patchelf 用于修复 ctranslate2 可执行栈
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
--mount=type=cache,target=/var/lib/apt,sharing=locked \
apt-get update -y && apt-get install -y --no-install-recommends \
ffmpeg ca-certificates patchelf \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /app
COPY requirements.txt /app/requirements.txt
# 【顺序关键】必须先装 torch按 VARIANT 分叉),再装 requirements。
# 原因requirements 里的 transformers / accelerate 依赖 torch若先装 requirements
# pip 会从默认 PyPI 拉来 GPU 版 torch + nvidia-* 全家桶(~2GB即使后续覆盖装 CPU torch
# 那些无用的 nvidia 包仍残留在镜像里。先装 torch 让 pip 解析 requirements 时 torch 已满足。
#
# CPU 走 cpu index~200MB无 nvidia 依赖GPU 走默认 PyPI带 CUDA~2.5GB)。
# 两套 wheel 二进制不兼容CPU 版 cuda.is_available()=FalseGPU 版 =True。不可共享。
RUN --mount=type=cache,target=/root/.cache/pip,sharing=locked \
pip install --upgrade pip && \
if [ "$VARIANT" = "cpu" ]; then \
pip install torch --index-url https://download.pytorch.org/whl/cpu ; \
else \
pip install torch ; \
fi
# torch 已就位requirements 里的 transformers/accelerate 解析时复用已装 torch不重复拉
RUN --mount=type=cache,target=/root/.cache/pip,sharing=locked \
pip install -r /app/requirements.txt
# ctranslate2 的 .so 带可执行栈标志PT_GNU_STACK X在某些内核 + Docker 组合下
# 会触发 "cannot enable executable stack as shared object requires"。用 patchelf
# 清掉该标志(改为 RW无需放宽容器安全策略。
# 注意:库在 ctranslate2.libs/ 隐藏目录pip wheel 拆分产物),不在 ctranslate2/ 包目录。
RUN for d in /usr/local/lib/python3.12/site-packages/ctranslate2.libs \
/usr/local/lib/python3.12/site-packages/ctranslate2; do \
[ -d "$d" ] && find "$d" -name '*.so*' \
-exec patchelf --clear-execstack {} \; 2>/dev/null || true; \
done; \
python -c "import ctranslate2; print('ctranslate2 stack fix verified', ctranslate2.__version__)"
# ---------------------------------------------------------------------------
# 3. dev从 deps 继承依赖,不 COPY 代码compose 用 volume 挂载源码)。
# 开启 uvicorn --reload改代码零重建、保存即生效。
# 注意dev 必须在 final 之前,保证 `docker build` 默认 target 是 final。
# ---------------------------------------------------------------------------
FROM deps AS dev
VOLUME ["/data", "/models"]
# ctranslate2/faster-whisper 用系统动态链接器找 cuDNN不走 torch 的库加载),
# 需把 torch wheel 自带的 nvidia 库目录加入 LD_LIBRARY_PATH否则 GPU 推理报
# "Unable to load libcudnn_ops.so.9"。放在 final/dev 而非 deps避免 ENV 变化
# 导致 deps 的 apt/pip 层缓存失效。CPU 镜像无此目录,路径被忽略不影响。
ENV CONFIG_PATH=/app/config.yaml \
LD_LIBRARY_PATH=/usr/local/lib/python3.12/site-packages/nvidia/cudnn/lib:/usr/local/lib/python3.12/dist-packages/nvidia/cudnn/lib:/usr/local/lib/python3.12/site-packages/nvidia/cublas/lib:/usr/local/lib/python3.12/dist-packages/nvidia/cublas/lib \
HF_HUB_OFFLINE=1 \
TRANSFORMERS_OFFLINE=1
EXPOSE 8000
CMD ["python", "-m", "uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000", "--reload"]
# ---------------------------------------------------------------------------
# 4. finalprod从 deps 继承全部依赖,只加 app 代码。
# 放在最后 = `docker build` 默认 target。setup.sh / start.sh 依赖此默认行为。
# ---------------------------------------------------------------------------
FROM deps AS final
COPY app /app/app
COPY scripts /app/scripts
COPY config.example.yaml /app/config.example.yaml
# 运行时数据:上传 / 中间产物 / 输出字幕 / 模型缓存
# 全部走 volume镜像本身无状态、无敏感数据
VOLUME ["/data", "/models"]
ENV CONFIG_PATH=/app/config.yaml \
LD_LIBRARY_PATH=/usr/local/lib/python3.12/site-packages/nvidia/cudnn/lib:/usr/local/lib/python3.12/dist-packages/nvidia/cudnn/lib:/usr/local/lib/python3.12/site-packages/nvidia/cublas/lib:/usr/local/lib/python3.12/dist-packages/nvidia/cublas/lib \
HF_HUB_OFFLINE=1 \
TRANSFORMERS_OFFLINE=1
EXPOSE 8000
CMD ["python", "-m", "uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]