Skip to content

Latest commit

 

History

History
822 lines (593 loc) · 40.8 KB

README-zh.md

File metadata and controls

822 lines (593 loc) · 40.8 KB

English | 简体中文 | 繁體中文 | Русский

ScribeCrate

开源、自托管的音频转录 API。

构建状态  Docker Pulls  License: MIT  Open In Colab

ScribeCrate 是一个自托管的语音转文字 API,用于转录音频、生成字幕,并将语音翻译为英语。它使用 Whisper 模型,由 faster-whisper 驱动,提供兼容 OpenAI 的转录和翻译接口。可通过 Docker 部署,使用 CPU 或 NVIDIA GPU 运行。

本项目原名为 docker-whisper,由 hwdsl2 维护。Docker 镜像名称仍为 hwdsl2/whisper-server。

功能特性:

  • 兼容 OpenAI 的 API: 提供 POST /v1/audio/transcriptions 和 POST /v1/audio/translations 接口,可与支持 OpenAI Whisper API 的客户端集成。
  • 私密的本地处理: 音频保留在您的服务器上,不发送给第三方进行转录。
  • 说话人分离: 通过可选的本地 sherpa-onnx 扩展,识别每个片段中的说话人。
  • 流式结果: 添加 stream=true,即可在解码时通过 Server-Sent Events(SSE)逐段接收转录结果,无需等待整个上传文件处理完成。
  • Whisper 模型支持: 可选择 tiny、base、small、medium、large-v3、large-v3-turbo 等模型。
  • CPU 和 GPU 支持: 可使用 CPU 运行,或使用 :cuda 镜像通过 NVIDIA GPU 加速推理。
  • 广泛的音频格式支持: 支持 MP3、M4A、WAV、WebM、OGG、FLAC 及 FFmpeg 支持的其他音频格式。
  • 灵活的输出格式: JSON、纯文本、详细 JSON、SRT 字幕和 WebVTT 字幕。
  • 离线运行: 使用预先缓存的模型和 WHISPER_LOCAL_ONLY,无需访问互联网即可运行。
  • 自动构建: 镜像通过 GitHub Actions 自动构建和发布,构建工作流公开可查。

在线试用: 在 Colab 中打开(无需 Docker 或本地安装)

也可作为 Self-Hosted AI Stack 的一部分使用,一条命令即可部署完整的自托管 AI 技术栈。

📘 The Self-Hosted AI Builder’s Guide(电子书 · 平装书)是一本关于构建、保护和运维自己的私有 AI 技术栈的实用指南。

快速开始

使用以下命令启动 ScribeCrate:

docker run \
    --name whisper \
    --restart=always \
    -v whisper-data:/var/lib/whisper \
    -p 9000:9000 \
    -d hwdsl2/whisper-server
GPU 快速开始(NVIDIA CUDA)

如果您有 NVIDIA GPU,可使用 :cuda 镜像进行硬件加速推理:

docker run \
    --name whisper \
    --restart=always \
    --gpus=all \
    -v whisper-data:/var/lib/whisper \
    -p 9000:9000 \
    -d hwdsl2/whisper-server:cuda

要求: NVIDIA GPU、NVIDIA 驱动 575.57.08+(Linux)或 576.57+(Windows),以及主机上已安装 NVIDIA Container Toolkit。:cuda 镜像仅支持 linux/amd64。

重要: 此镜像运行默认 base 模型需要至少 700 MB 可用内存。内存为 512 MB 或更少的系统不受支持。

Note

如需面向互联网的部署,请使用反向代理来添加 HTTPS。同时,请将上述 docker run 命令中的 -p 9000:9000 替换为 -p 127.0.0.1:9000:9000,以防止从外部直接访问未加密端口。

首次启动时,Whisper base 模型(约 145 MB)将自动下载并缓存。查看日志确认服务器已就绪:

docker logs whisper

看到 "ScribeCrate transcription server is ready" 后,获取全新安装在上述持久化数据卷中自动生成的 API 密钥:

scribe_api_key="$(docker exec whisper whisper_manage --getkey)"

转录您的第一个音频文件,将 您的服务器IP 替换为服务器地址,并将 audio.mp3 替换为您的音频文件:

curl http://您的服务器IP:9000/v1/audio/transcriptions \
    -H "Authorization: Bearer $scribe_api_key" \
    -F file=@audio.mp3 \
    -F model=whisper-1

响应:

{"text": "转录的文字内容显示在这里。"}

提示: 需要示例音频文件进行测试?可以使用来自 Azure Samples 仓库的英语语音示例(WAV 格式,MIT 许可证):

curl -L -o sample_speech.wav \
    "https://github.com/Azure-Samples/cognitive-services-speech-sdk/raw/master/sampledata/audiofiles/katiesteve.wav"

curl http://您的服务器IP:9000/v1/audio/transcriptions \
    -H "Authorization: Bearer $scribe_api_key" \
    -F file=@sample_speech.wav \
    -F model=whisper-1

另外,你也可以在不使用 Docker 的情况下安装 Whisper。如需了解更多关于此镜像的使用方法,请阅读以下各节。

ScribeCrate 与 ScribeCrate Live 的选择

ScribeCrate Live 是独立部署的服务器,由 WhisperLive 提供支持。

ScribeCrate ScribeCrate Live
使用场景 转录完整音频文件 实时麦克风/音频流
协议 HTTP REST WebSocket(流式)+ HTTP REST
延迟 处理完成后返回 JSON;SSE 逐段返回 逐步返回分段结果
适合 会议录音、上传的音频文件 浏览器采集、RTSP 流、实时字幕
镜像大小 ~190 MB(:cuda 约 3.1 GB) ~580 MB(:cuda 约 4.3 GB)

社区

自托管 VPN 和网络项目

系统要求

  • 已安装 Docker 的 Linux 服务器(本地或云端)
  • 支持的架构:amd64(x86_64)、arm64(例如 Raspberry Pi 4/5、AWS Graviton)
  • 最低内存:默认 base 模型约需 700 MB 可用内存(请参阅模型列表)
  • 首次启动需要访问互联网以下载模型(之后模型将缓存在本地)。使用预先缓存的模型并设置 WHISPER_LOCAL_ONLY=true 时不需要网络访问。

GPU 加速(:cuda 镜像)要求:

  • 支持 CUDA 的 NVIDIA GPU(计算能力 6.0+)
  • 主机已安装 NVIDIA 驱动 575.57.08+(Linux)或 576.57+(Windows)
  • 已安装 NVIDIA Container Toolkit
  • :cuda 镜像仅支持 linux/amd64

如需面向公网部署,请参阅使用反向代理以启用 HTTPS。

下载

从 Docker Hub 获取可信构建:

docker pull hwdsl2/whisper-server

如需 NVIDIA GPU 加速,请拉取 :cuda 标签:

docker pull hwdsl2/whisper-server:cuda

也可从 Quay.io 下载:

docker pull quay.io/hwdsl2/whisper-server
docker image tag quay.io/hwdsl2/whisper-server hwdsl2/whisper-server

CPU 镜像支持 linux/amd64 和 linux/arm64。:cuda 标签仅支持 linux/amd64。

环境变量

所有变量均为可选。挂载 /var/lib/whisper 数据卷的新安装会自动生成 Bearer 令牌。没有密钥的既有安装会保持开放以兼容旧行为。

此 Docker 镜像使用以下变量,可在 env 文件中声明(参见示例):

变量 说明 默认值
WHISPER_MODEL 使用的 Whisper 模型。请参阅模型列表。 base
WHISPER_LANGUAGE 默认转录语言。使用 BCP-47 语言代码(如 zh、en、ja)或 auto 自动检测。 auto
WHISPER_PORT API 的 HTTP 端口(1–65535)。 9000
WHISPER_DEVICE 计算设备:cpu、cuda 或 auto。使用 :cuda 镜像时设为 cuda 以启用 GPU 加速。auto 自动检测 GPU,无 GPU 时回退到 CPU。 cpu
WHISPER_COMPUTE_TYPE 量化 / 计算类型。CPU 推荐 int8;CUDA 推荐 float16。 int8(CPU)/ float16(CUDA)
WHISPER_THREADS 推理使用的 CPU 线程数。设为物理核心数可获得最佳延迟。 2
WHISPER_API_KEY 可选的 Bearer 令牌。新持久化安装会自动生成。设置后所有请求须包含 Authorization: Bearer <key>。显式设置为空可禁用认证。 新持久化安装自动生成
WHISPER_LOG_LEVEL 日志级别:DEBUG、INFO、WARNING、ERROR、CRITICAL。 INFO
WHISPER_BEAM 转录和翻译解码的 beam 大小。较大的值可能以速度换取精度。使用 1 可获得最快的贪婪解码。 5
WHISPER_MAX_REQUEST_BEAM 每个请求的 beam 覆盖值允许的最大 beam 大小。设为 0 可禁用此限制。 10
WHISPER_CONDITION_ON_PREVIOUS_TEXT 使用前一窗口的文本作为解码上下文。设为 false 可能减少重复反馈循环,但也可能降低窗口间的一致性。 true
WHISPER_NO_REPEAT_NGRAM_SIZE 限制解码中的重复 token n-gram。0 表示禁用;接受 0 至 2147483647 的规范十进制整数。n-gram 是模型 token 的序列,不一定对应完整的单词。 0
WHISPER_MAX_UPLOAD_MB 上传音频文件的最大大小(MB)。超过此限制的请求会返回 HTTP 413。设为 0 可禁用此限制。 1024
WHISPER_LOCAL_ONLY 设为任意非空值(如 true)时,禁止 HuggingFace 和说话人分离 ONNX 模型的自动下载。适用于预先缓存模型的离线或隔离网络部署。 (未设置)
WHISPER_WORD_TIMESTAMPS 设为 true 时,全局启用词级时间戳。verbose_json 输出将包含顶层 words 数组,含每个词的起止时间和置信度。也可通过 timestamp_granularities[]=word 按请求启用。 (未设置)
WHISPER_DIARIZATION 设为 true 启用说话人分离,识别每个片段中的说话人。使用 sherpa-onnx 和 pyannote segmentation-3.0 ONNX 模型(使用默认嵌入模型时约 46 MB,首次使用时自动下载)。不支持流式模式。 (未设置)
WHISPER_DIARIZE_EMBEDDING_MODEL 说话人嵌入模型文件名,取自 sherpa-onnx speaker-recongition-models 发布。默认模型使用中文普通话训练;英语音频可考虑 wespeaker_en_voxceleb_resnet34_LM.onnx 或 nemo_en_titanet_large.onnx。参见说话人分离。 3dspeaker_speech_eres2net_base_sv_zh-cn_3dspeaker_16k.onnx
WHISPER_DIARIZE_NUM_SPEAKERS 说话人确切数量(如已知)。提高聚类准确性。设为 -1 或留空表示自动检测。 -1
WHISPER_DIARIZE_THREADS 分割和嵌入模型各自使用的 CPU 线程数。接受 1 至 2147483647 的规范十进制整数;未设置或为空时继承 WHISPER_THREADS。 WHISPER_THREADS
WHISPER_DIARIZE_THRESHOLD 自动检测时使用的聚类阈值。值越小检测到的说话人越多,值越大检测到的越少。设置确切说话人数量时会忽略此项。 0.5
WHISPER_DISABLE_USAGE_COUNTS 设为 1 可禁用匿名聚合使用计数。 (未设置)

注: 在 env 文件中,值可用单引号括起,例如 VAR='value'。= 两侧不要有空格。如更改 WHISPER_PORT,请相应更新 docker run 命令中的 -p 参数。

重复控制适用于转录和翻译的批处理及 SSE 路径。对于容易重复的录音,可尝试 WHISPER_CONDITION_ON_PREVIOUS_TEXT=false 和 WHISPER_NO_REPEAT_NGRAM_SIZE=3。这可能抑制正常重复或降低解码窗口间的一致性,不能保证消除幻觉。

这些设置的值可包含首尾 ASCII 空白,以及最多一对匹配的外层引号。空值使用默认值。布尔值接受 true/false,不区分 ASCII 字母大小写;整数必须使用 ASCII 数字,且不能包含正负号或前导零。非空无效值会在模型加载前阻止启动。

绑定挂载的 api_server.py 会覆盖镜像内置的 API。移除该挂载可使用内置 API;若需保留自定义版本,请在升级时同步更新。手动替换脚本时,请使用同一版本的 api_server.py、diarizer.py 和 diarization_models.py。

修改绑定挂载的 /whisper.env 后,请重启容器。如果容器仍读取到旧文件内容,请仅重建该容器。更改 Docker/Compose 容器环境变量或镜像时,需要重建容器,并保留原数据卷及 Compose 项目。单纯重启不会应用这些变更。

移除这些选项可恢复默认解码设置。更新或回滚时不要删除模型数据卷。

使用 env 文件的示例:

cp whisper.env.example whisper.env
# 编辑 whisper.env 配置您的设置,然后:
docker run \
    --name whisper \
    --restart=always \
    -v whisper-data:/var/lib/whisper \
    -v ./whisper.env:/whisper.env:ro \
    -p 9000:9000 \
    -d hwdsl2/whisper-server

绑定挂载的 env 文件会在容器启动时读取。修改后请重启容器;如果容器仍读取到旧文件内容,请保留原数据卷并重建容器。

也可通过 --env-file 传入
docker run \
    --name whisper \
    --restart=always \
    -v whisper-data:/var/lib/whisper \
    -p 9000:9000 \
    --env-file=whisper.env \
    -d hwdsl2/whisper-server

使用 docker-compose

cp whisper.env.example whisper.env
# 按需编辑 whisper.env,然后:
docker compose up -d
docker logs whisper

示例 docker-compose.yml(已包含在项目中):

services:
  whisper:
    image: hwdsl2/whisper-server
    container_name: whisper
    restart: always
    ports:
      - "9000:9000/tcp"  # 如使用主机反向代理,改为 "127.0.0.1:9000:9000/tcp"
    volumes:
      - whisper-data:/var/lib/whisper
      - ./whisper.env:/whisper.env:ro

volumes:
  whisper-data:
    name: whisper-data

Note

如需面向公网部署,请使用反向代理启用 HTTPS。同时,请将 docker-compose.yml 中的 "9000:9000/tcp" 改为 "127.0.0.1:9000:9000/tcp",以防止未加密端口被直接访问。

使用 docker-compose 部署 GPU(NVIDIA CUDA)

项目提供了单独的 docker-compose.cuda.yml 用于 GPU 部署:

cp whisper.env.example whisper.env
# 按需编辑 whisper.env,然后:
docker compose -f docker-compose.cuda.yml up -d
docker logs whisper

示例 docker-compose.cuda.yml(已包含在项目中):

services:
  whisper:
    image: hwdsl2/whisper-server:cuda
    container_name: whisper
    restart: always
    ports:
      - "9000:9000/tcp"  # 如使用主机反向代理,改为 "127.0.0.1:9000:9000/tcp"
    volumes:
      - whisper-data:/var/lib/whisper
      - ./whisper.env:/whisper.env:ro
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: 1
              capabilities: [gpu]

volumes:
  whisper-data:
    name: whisper-data

API 参考

ScribeCrate 提供兼容 OpenAI 音频转录和音频翻译接口的端点。使用 OpenAI SDK 的客户端应配置基础 URL,并使用您的 ScribeCrate API 密钥:

身份验证: 全新的持久化安装需要 API 密钥。使用以下命令获取密钥,供 SDK 配置和下面的 curl 示例使用:

scribe_api_key="$(docker exec whisper whisper_manage --getkey)"

export OPENAI_BASE_URL="http://您的服务器IP:9000/v1"
export OPENAI_API_KEY="$scribe_api_key"

如果已禁用 API 密钥认证,请省略 curl 示例中的 Authorization 请求头。OpenAI SDK 客户端仍要求提供非空密钥;此时请设置 OPENAI_API_KEY=unused。

说话人分离启用时是本地 sherpa-onnx 扩展,并不等同于 OpenAI 的说话人分离模型。OpenAI 专用的转录选项(如 gpt-4o-transcribe-diarize、response_format=diarized_json、include=logprobs、chunking_strategy、known_speaker_names 和 known_speaker_references)不受支持,并会返回 400。

转录音频

POST /v1/audio/transcriptions
Content-Type: multipart/form-data

参数:

参数 类型 必填 说明
file 文件 ✅ 音频文件。支持格式:mp3、mp4、m4a、wav、webm、ogg、flac 及 ffmpeg 支持的所有格式。
model 字符串 ✅ 传入 whisper-1(值被接受,但始终使用当前活跃模型)。
language 字符串 — BCP-47 语言代码。覆盖本次请求的 WHISPER_LANGUAGE 设置。
prompt 字符串 — 可选文本,用于引导模型风格或延续前一段内容。
response_format 字符串 — 输出格式,默认为 json。请参阅响应格式。stream=true 时忽略此参数。不支持 OpenAI 专用的 diarized_json。
temperature 浮点数 — 采样温度(0–1),默认为 0。
stream 布尔值 — 启用 SSE 流式传输。为 true 时,段落将在解码时以 text/event-stream 事件形式返回。默认为 false。
timestamp_granularities[] 数组 — 时间戳粒度。值:word、segment。包含 word 时,verbose_json 输出包含顶层 words 数组。默认:["segment"]。

本地 faster-whisper 扩展: 可设置 beam,为单个转录或翻译请求覆盖 WHISPER_BEAM。这不是 OpenAI API 架构的一部分,因此不要将其发送到托管的 OpenAI API 或严格兼容 OpenAI 的网关。每请求默认上限为 10(WHISPER_MAX_REQUEST_BEAM);将该变量设为 0 可禁用上限。Beam 搜索主要影响 temperature=0 时的确定性解码。

示例:

curl http://您的服务器IP:9000/v1/audio/transcriptions \
    -H "Authorization: Bearer $scribe_api_key" \
    -F file=@meeting.m4a \
    -F model=whisper-1 \
    -F language=zh

使用 API 密钥认证:

curl http://您的服务器IP:9000/v1/audio/transcriptions \
    -H "Authorization: Bearer your_api_key" \
    -F file=@audio.mp3 \
    -F model=whisper-1

响应格式

response_format 说明
json {"text": "..."} — 默认,与 OpenAI 基础响应格式一致
text 纯文本,无 JSON 封装
verbose_json 完整 JSON,包含语言、时长、逐段时间戳及对数概率
srt SubRip 字幕格式(.srt)
vtt WebVTT 字幕格式(.vtt)

示例 — 流式接收解码段落:

curl http://您的服务器IP:9000/v1/audio/transcriptions \
    -H "Authorization: Bearer $scribe_api_key" \
    -F file=@long-audio.mp3 \
    -F model=whisper-1 \
    -F stream=true

SSE 响应(使用 OpenAI 流式转录协议):

data: {"type":"transcript.text.delta","delta":"您好,最近怎么样?"}

data: {"type":"transcript.text.delta","delta":" 我很好,谢谢。"}

data: {"type":"transcript.text.done","text":"您好,最近怎么样? 我很好,谢谢。"}

data: [DONE]

上传后第一个增量文本通常在 1–3 秒内到达。每个 transcript.text.delta 事件包含刚解码的段落的增量文本。最后的 transcript.text.done 事件包含与标准 json 响应等效的完整转录文本。

示例 — 通过浏览器 fetch 进行流式传输
const form = new FormData();
form.append("file", audioBlob, "audio.webm");
form.append("model", "whisper-1");
form.append("stream", "true");

const res = await fetch("http://您的服务器IP:9000/v1/audio/transcriptions", {
  method: "POST",
  headers: { Authorization: "Bearer your_api_key" },
  body: form,
});

const reader = res.body.getReader();
const decoder = new TextDecoder();
let buffer = "";

while (true) {
  const { done, value } = await reader.read();
  if (done) break;
  buffer += decoder.decode(value, { stream: true });
  // SSE frames are separated by "\n\n"; split and process complete frames
  const frames = buffer.split("\n\n");
  buffer = frames.pop(); // keep any incomplete trailing frame
  for (const frame of frames) {
    if (!frame.startsWith("data: ")) continue;
    const payload = frame.slice(6);
    if (payload.startsWith("[DONE]")) break;
    const event = JSON.parse(payload);
    if (event.type === "transcript.text.delta") console.log(event.delta);
    if (event.type === "transcript.text.done") console.log("Full text:", event.text);
  }
}

示例 — 获取 SRT 字幕:

curl http://您的服务器IP:9000/v1/audio/transcriptions \
    -H "Authorization: Bearer $scribe_api_key" \
    -F file=@video.mp4 \
    -F model=whisper-1 \
    -F response_format=srt

示例 — 带时间戳的详细 JSON:

curl http://您的服务器IP:9000/v1/audio/transcriptions \
    -H "Authorization: Bearer $scribe_api_key" \
    -F file=@audio.mp3 \
    -F model=whisper-1 \
    -F response_format=verbose_json

示例 — 带词级时间戳的详细 JSON:

curl http://您的服务器IP:9000/v1/audio/transcriptions \
    -H "Authorization: Bearer $scribe_api_key" \
    -F file=@audio.mp3 \
    -F model=whisper-1 \
    -F response_format=verbose_json \
    -F "timestamp_granularities[]=word"

当 timestamp_granularities[] 包含 word 时,verbose_json 响应包含顶层 words 数组:

{
  "word": "hello",
  "start": 0.5,
  "end": 0.8,
  "probability": 0.98
}

翻译音频

POST /v1/audio/translations
Content-Type: multipart/form-data

将任意语言的音频翻译为英文文本。与 OpenAI 音频翻译接口兼容。接受常见的翻译参数。输出始终为英文。

注意: 若要将语音翻译成英语,请使用 base、small、medium 或 large-v3 等非 turbo 多语言模型。仅支持英语的(.en)模型不支持此任务,large-v3-turbo / turbo 也未针对翻译任务训练。 当服务器加载上述不支持翻译的模型时,批处理和流式翻译请求均返回 HTTP 400。请求中的 model 字段不会覆盖服务器端的 WHISPER_MODEL 配置。

示例:

curl http://您的服务器IP:9000/v1/audio/translations \
    -H "Authorization: Bearer $scribe_api_key" \
    -F file=@french_audio.mp3 \
    -F model=whisper-1

列出模型

GET /v1/models

返回 OpenAI 兼容格式的当前活跃模型。

curl http://您的服务器IP:9000/v1/models -H "Authorization: Bearer $scribe_api_key"

交互式 API 文档

可在以下地址访问交互式 Swagger UI:

http://您的服务器IP:9000/docs

持久化数据

所有服务器数据存储在 Docker 数据卷(容器内的 /var/lib/whisper)中:

/var/lib/whisper/
├── models--Systran--faster-whisper-*/   # 缓存的 Whisper 模型文件(从 HuggingFace 下载)
├── .port                 # 当前端口(供 whisper_manage 使用)
├── .model                # 当前模型名称(供 whisper_manage 使用)
└── .server_addr          # 缓存的服务器 IP(供 whisper_manage 使用)

请备份 Docker 数据卷以保留已下载的模型。模型文件较大(145 MB – 3 GB),首次启动时下载可能需要数分钟;保留数据卷可避免在重建容器时重新下载。

提示: /var/lib/whisper 数据卷与 docker-whisper-live 的 /var/lib/whisper-live 数据卷使用相同的 HuggingFace 缓存布局。如果已通过 docker-whisper-live 下载了模型,可绑定挂载相同的数据卷目录以避免重复下载。

管理服务器

在运行中的容器内使用 whisper_manage 来查看和管理服务器。

显示服务器信息:

docker exec whisper whisper_manage --showinfo

列出可用模型:

docker exec whisper whisper_manage --listmodels

预先下载模型:

docker exec whisper whisper_manage --downloadmodel large-v3-turbo

切换模型

要更换活跃模型:

  1. (可选但建议) 在服务器运行时预先下载新模型:

    docker exec whisper whisper_manage --downloadmodel large-v3-turbo
  2. 在 whisper.env 文件中更新 WHISPER_MODEL(或在 docker run 命令中添加 -e WHISPER_MODEL=large-v3-turbo)。

  3. 重启容器:

    docker restart whisper

可用模型:

模型 磁盘占用 内存(约) 说明
tiny ~75 MB ~250 MB 最快;精度较低
tiny.en ~75 MB ~250 MB 仅英语
base ~145 MB ~700 MB 良好平衡 — 默认
base.en ~145 MB ~700 MB 仅英语
small ~465 MB ~1.5 GB 更高精度
small.en ~465 MB ~1.5 GB 仅英语
medium ~1.5 GB ~5 GB 高精度
medium.en ~1.5 GB ~5 GB 仅英语
large-v1 ~3 GB ~10 GB 旧版大型模型
large-v2 ~3 GB ~10 GB 非常高精度
large-v3 ~3 GB ~10 GB 最高精度
large-v3-turbo ~1.6 GB ~6 GB 高速 + 高精度 ⭐;仅用于转录
turbo ~1.6 GB ~6 GB large-v3-turbo 的别名;仅用于转录

提示: 对于转录,在硬件资源充足时,large-v3-turbo 是比 large-v3 更快的选择。若要将语音翻译成英语,请选择 base、small、medium 或 large-v3 等非 turbo 多语言模型。

内存数据为近似值,基于 INT8 量化(默认)。模型缓存在 /var/lib/whisper Docker 数据卷中,仅需下载一次。

保护你的服务器

如果你的 ScribeCrate 服务器可从公网访问 —— 即使只是短暂可达 —— 也请至少采取以下保护措施。转录对 CPU/GPU 资源消耗较大,未做身份验证的接口可能被滥用,浪费你的计算资源。

1. 使用 API 密钥。 挂载 /var/lib/whisper 数据卷的新安装会自动生成 API 密钥。可用 docker exec whisper whisper_manage --showkey 查看;脚本中可用 docker exec whisper whisper_manage --getkey。没有密钥的既有安装会保持开放以兼容旧行为;也可以在 env 文件中设置 WHISPER_API_KEY 手动启用认证。所有已认证请求必须包含 Authorization: Bearer <key>。

# 生成 32 字节的随机密钥
openssl rand -hex 32

2. 在反向代理后面时绑定到 localhost。 将 -p 9000:9000 替换为 -p 127.0.0.1:9000:9000(或在 docker-compose.yml 中将 "9000:9000/tcp" 改为 "127.0.0.1:9000:9000/tcp"),使未加密端口无法从主机外部直接访问。

3. 限制上传大小。 服务器会拒绝超过 WHISPER_MAX_UPLOAD_MB(默认 1024)的上传。对于面向互联网的部署,还应配置反向代理在请求到达应用前拒绝超大上传(例如 nginx client_max_body_size 100M;)。

4. 注意日志级别。 WHISPER_LOG_LEVEL=DEBUG 可能会将转录文本写入日志。在共享系统上请保持 INFO 或更高级别。

5. 浏览器调用时在代理处启用 CORS。 本服务器默认不设置 Access-Control-Allow-Origin 响应头;若需在不同源的网页中直接调用本 API,请在反向代理处添加 CORS 头。

6. 考虑限流。 在服务器前部署限流(如 nginx limit_req_zone、Caddy rate_limit),限制每个客户端 IP 的并发转录请求数。

使用反向代理

如需面向公网部署,可在 ScribeCrate 前置反向代理处理 HTTPS 终止。在本地或可信网络中使用无需 HTTPS,但将 API 端点暴露在公网时建议启用 HTTPS。

从反向代理访问 ScribeCrate 容器时使用以下地址之一:

  • whisper:9000 — 如果反向代理作为容器运行在与 ScribeCrate 同一 Docker 网络中(例如定义在同一 docker-compose.yml 中)。
  • 127.0.0.1:9000 — 如果反向代理运行在主机上且端口 9000 已发布(默认 docker-compose.yml 会发布该端口)。

使用 Caddy(Docker 镜像)的示例(自动 Let's Encrypt TLS,反向代理在同一 Docker 网络中):

Caddyfile:

whisper.example.com {
  reverse_proxy whisper:9000
}

使用 nginx 的示例(反向代理运行在主机上):

server {
    listen 443 ssl;
    server_name whisper.example.com;

    ssl_certificate     /path/to/cert.pem;
    ssl_certificate_key /path/to/key.pem;

    # 音频文件可能较大——按需调整上传限制
    client_max_body_size 100M;

    location / {
        proxy_pass         http://127.0.0.1:9000;
        proxy_set_header   Host $host;
        proxy_set_header   X-Real-IP $remote_addr;
        proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header   X-Forwarded-Proto $scheme;
        proxy_http_version 1.1;       # 流式传输(SSE)所需
        proxy_read_timeout 300s;
    }
}

更新 Docker 镜像

如需更新 Docker 镜像和容器,首先下载最新版本:

docker pull hwdsl2/whisper-server

如果镜像已是最新版本,您将看到:

Status: Image is up to date for hwdsl2/whisper-server:latest

否则将下载最新版本。删除并重新创建容器:

docker rm -f whisper
# 然后使用相同的数据卷和端口重新运行快速开始中的 docker run 命令。

您下载的模型将保留在 whisper-data 数据卷中。

与其他 AI 服务配合使用

ScribeCrate 可作为更广泛的自托管 AI 设置中的语音转文字服务。

如需完整和轻量级 Docker Compose 技术栈、手动 docker run 示例,以及结合 SpeakCrate、EmbedCrate、GatewayCrate、InferCrate、ParseCrate 和 UplinkCrate 的语音/RAG/MCP 流水线示例,请参阅 Self-Hosted AI Stack。

相关 AI 服务:

说话人分离

说话人分离功能识别每个转录片段中谁在说话。这是一个本地扩展,基于 sherpa-onnx 使用导出为 ONNX 格式的 pyannote segmentation-3.0 模型。

启用说话人分离:

# 在 whisper.env 中:
WHISPER_DIARIZATION=true

ONNX 模型(使用默认嵌入模型时共约 46 MB)在首次使用时自动下载并缓存到 /var/lib/whisper 数据卷。预先下载:

docker exec whisper whisper_manage --downloaddiarize

启用说话人分离后的输出:

verbose_json 在每个片段中添加 speaker 字段:

{
  "segments": [
    {"id": 0, "start": 1.0, "end": 3.5, "text": "我们下周发布吧。", "speaker": "SPEAKER_00"},
    {"id": 1, "start": 4.0, "end": 6.2, "text": "我觉得 QA 还需要两天。", "speaker": "SPEAKER_01"}
  ]
}

srt 和 vtt 在文本前添加说话人标签:

1
00:00:01,000 --> 00:00:03,500
[SPEAKER_00] 我们下周发布吧。

2
00:00:04,000 --> 00:00:06,200
[SPEAKER_01] 我觉得 QA 还需要两天。

text 格式在说话人变化时显示标签:

[SPEAKER_00] 我们下周发布吧。
[SPEAKER_01] 我觉得 QA 还需要两天。

注意事项:

Important

说话人分离需要完整音频分析,不支持流式模式(stream=true)。两者同时启用时,说话人分离会被静默跳过。

  • 如果已知确切说话人数量,设置 WHISPER_DIARIZE_NUM_SPEAKERS 可提高准确性。
  • 说话人分离在转录完成后运行。处理时间取决于音频时长、硬件和线程设置,可能超过转录时间。

说话人分离线程: 分割和嵌入模型现在都继承 WHISPER_THREADS(通常为 2),不再各自使用一个线程。这会改变现有已启用说话人分离的部署的 CPU 资源使用情况。设置 WHISPER_DIARIZE_THREADS=1 可保留之前的每模型线程设置,也可根据 CPU 资源预算选择其他线程数。移除该选项或将其留空会恢复继承行为,而不是之前的单线程默认值。

与重复控制选项相同,WHISPER_DIARIZE_THREADS 的值可包含首尾 ASCII 空白,以及最多一对匹配的外层引号。使用 1 至 2147483647 的 ASCII 十进制数字,不含正负号或前导零。非空无效值会在模型加载前阻止启动,即使未启用说话人分离也是如此。仅设置此选项不会启用说话人分离。

这不是整个进程的线程数上限。其他库和请求工作线程可能使用额外线程,增加线程数不能保证加速或输出完全一致。即使使用 :cuda 镜像,说话人分离仍在 CPU 上运行,且仅支持批处理。请按照环境变量的重启/重建说明应用更改;更新或回滚时保留模型数据卷。

说话人嵌入模型: 默认嵌入模型 3dspeaker_speech_eres2net_base_sv_zh-cn_3dspeaker_16k.onnx 使用中文普通话训练。在英语录音中,它可能把同一位说话人拆分为多个标签。设置 WHISPER_DIARIZE_EMBEDDING_MODEL 可使用 sherpa-onnx speaker-recongition-models 发布中的其他模型,例如:

# 在 whisper.env 中:
WHISPER_DIARIZE_EMBEDDING_MODEL=wespeaker_en_voxceleb_resnet34_LM.onnx

英语训练的选项包括 wespeaker_en_voxceleb_resnet34_LM.onnx(约 27 MB)和 nemo_en_titanet_large.onnx(约 101 MB)。嵌入模型文件的大小随所选模型而变化;这些大小不包括共享分割模型(约 6 MB)。没有适用于所有录音的最佳模型,请用自己的音频比较效果。请使用项目维护的允许列表中支持的确切 .onnx 文件名,并注意区分大小写。无法识别的非空值会在加载模型前阻止启动,即使未启用说话人分离也是如此。该值可包含首尾 ASCII 空白,以及最多一对匹配的外层引号。

所选模型会在首次使用时下载,并缓存在 /var/lib/whisper 数据卷中,与之前使用过的模型并存。whisper_manage --downloaddiarize 会预下载容器启动时配置的模型。聚类阈值与模型相关:切换模型后,请重新调整 WHISPER_DIARIZE_THRESHOLD 或设置 WHISPER_DIARIZE_NUM_SPEAKERS。未设置或为空时保持默认模型,现有缓存文件名和阈值不受影响。

模型校验: 说话人分离 ONNX 模型会在处理管道加载时,按固定的预期文件大小和 SHA-256 哈希值进行校验,已有缓存文件也包括在内。通过校验的缓存文件会直接复用,无需重新下载。未通过校验的现有缓存文件会被保留,日志中会指出对应文件。请将该文件移走,再在允许下载的情况下重启,以获取通过校验的副本。校验、下载或模型加载失败时,会记录警告并禁用说话人分离,转录仍可使用。新下载的模型在存入正式缓存前也会经过校验;未完成或失败的下载不会被使用。支持通过符号链接使用模型文件及现有分割模型目录。链接指向的模型必须是普通文件,并通过相同校验。失效链接或无效目标会被保留,并在日志中报告;请修复链接或其目标,或将对应缓存项移走后重试。

启用说话人分离且允许自动下载时,容器和 Colab 的启动等待时间会涵盖两个 ONNX 模型的下载及重试。仅使用 Whisper 或处于离线模式时,等待上限为五分钟。如果服务器进程退出,会提前停止等待。

如果之前曾用其他权重替换默认嵌入文件,请将其移至对应的受支持文件名,并显式选择该模型。切换回默认模型前,请恢复或重新下载官方默认权重。

离线兼容性变化: WHISPER_LOCAL_ONLY 现在还会阻止说话人分离 ONNX 模型的自动下载,不再仅限于 HuggingFace 下载。启用离线模式前,请预先缓存分割模型和选中的嵌入模型。显式执行 whisper_manage --downloaddiarize 仍允许预先下载 ONNX 模型;Whisper 的 --downloadmodel 命令保留现有的离线检查。例如:

docker exec whisper whisper_manage --downloaddiarize wespeaker_en_voxceleb_resnet34_LM.onnx

不提供参数时,使用容器启动时保存的模型;没有保存的选择时使用现有默认模型。预先下载不会改变当前使用的模型。请按环境变量的重启/重建说明应用选择更改,并保留模型数据卷以便回滚。

支持的权重来自 sherpa-onnx 上游模型发布。模型权重遵循各自的上游许可证,与 ScribeCrate 的 MIT 许可证分开。

使用计数

此镜像使用公开的 GitHub Release 资源下载次数进行匿名聚合使用计数。计数是近似值,不代表唯一用户或活跃安装。镜像不会发送遥测负载,也不会使用私有收集器。仅当服务器成功启动且挂载了 /var/lib/whisper 卷后,才会以尽力而为方式计数;当该持久化安装首次运行不同镜像构建时,也会再次计数。要退出,请设置 WHISPER_DISABLE_USAGE_COUNTS=1。

技术细节

  • 基础镜像::latest 使用 python:3.12-slim;:cuda 使用 nvidia/cuda
  • 运行时:Python 3(虚拟环境位于 /opt/venv)
  • STT 引擎:faster-whisper + CTranslate2(CPU 默认 INT8,CUDA 默认 FP16)
  • API 框架:FastAPI + Uvicorn
  • 音频解码:PyAV(内置 FFmpeg 库)
  • 数据目录:/var/lib/whisper(Docker 数据卷)
  • 模型存储:HuggingFace Hub 格式,存储在数据卷中——下载一次,重启后复用

授权协议

注: 预构建镜像中包含的软件组件(如 faster-whisper 及其依赖项)均受各自版权持有者所选许可证约束。使用预构建镜像时,用户有责任确保其使用方式符合镜像内所有软件的相关许可证要求。

版权所有 (C) 2026 Lin Song
本作品采用 MIT 许可证授权。

faster-whisper 版权归 SYSTRAN 所有,依据 MIT 许可证分发。

ScribeCrate 是使用 Whisper 模型的独立服务器,与 OpenAI 或 SYSTRAN 无关联,未获其背书或赞助。