add full source: transcribe pipeline, HTTP API, OpenAI endpoint, web UI, Docker

This commit is contained in:
2026-09-09 16:04:10 +08:00
parent 757861f1dd
commit 7010da8855
19 changed files with 2918 additions and 0 deletions
+101
View File
@@ -0,0 +1,101 @@
# Multi-stage, multi-arch build for record-asr.
#
# docker build -t record-asr .
# docker buildx build --platform linux/amd64,linux/arm64 -t record-asr:latest --push .
#
# buildx builds each platform NATIVELY (the builder image matches the target
# arch), so cgo links the correct prebuilt .so for that arch and NO cross
# compiler is needed — unlike the bare `make build-arm64` path.
# ---- builder ----
FROM golang:1.22-bookworm AS builder
WORKDIR /src
# Allow overriding the Go module proxy, e.g. for restricted networks:
# docker build --build-arg GOPROXY=https://goproxy.cn,direct -t record-asr .
ARG GOPROXY=https://proxy.golang.org,direct
ENV GOPROXY=${GOPROXY}
# Cache module downloads (incl. the large sherpa-onnx-go .so) separately from
# source so code changes don't re-download deps.
COPY go.mod go.sum ./
RUN go mod download
COPY . .
# Build, then copy the prebuilt .so that match THIS builder's arch into /out/lib.
# The glob avoids hard-coding the sherpa-onnx-go-linux version.
RUN set -eux; \
CGO_ENABLED=1 go build -trimpath -o /out/record-asr .; \
arch="$(go env GOARCH)"; \
case "$arch" in \
amd64) libd=x86_64-unknown-linux-gnu;; \
arm64) libd=aarch64-unknown-linux-gnu;; \
*) echo "unsupported arch: $arch" >&2; exit 1;; \
esac; \
mkdir -p /out/lib; \
cp "$(go env GOMODCACHE)/github.com/k2-fsa/sherpa-onnx-go-linux@"*/lib/"$libd"/*.so /out/lib/
# ---- models: download SenseVoice int8 + silero VAD at BUILD time ----
# These are arch-independent ONNX files, so the same download serves every
# platform. Baking them into the image means the container starts instantly
# and needs no network at runtime. (One-time ~230MB cost per build.)
FROM debian:bookworm-slim AS models
RUN apt-get update \
&& apt-get install -y --no-install-recommends ca-certificates curl bzip2 \
&& rm -rf /var/lib/apt/lists/*
# Extract ONLY model.int8.onnx + tokens.txt from the release tarball (skip the
# test wavs / float model) to keep the layer lean. --strip-components=1 flattens
# the top archive dir so files land directly in /models/sensevoice/.
RUN mkdir -p /models/sensevoice \
&& curl -fsSL -o /tmp/sv.tar.bz2 \
"https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/sherpa-onnx-sense-voice-zh-en-ja-ko-yue-int8-2024-07-17.tar.bz2" \
&& tar -xjf /tmp/sv.tar.bz2 -C /models/sensevoice \
--strip-components=1 --wildcards --no-anchored 'model.int8.onnx' 'tokens.txt' \
&& rm -f /tmp/sv.tar.bz2 \
&& curl -fsSL -o /models/silero_vad.onnx \
"https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/silero_vad.onnx" \
&& test -s /models/sensevoice/model.int8.onnx \
&& test -s /models/sensevoice/tokens.txt \
&& test -s /models/silero_vad.onnx \
&& ls -lh /models/sensevoice /models/silero_vad.onnx
# ---- runtime (glibc; sherpa-onnx .so are glibc-built, so NOT alpine/musl) ----
FROM debian:bookworm-slim
# APT_MIRROR: optionally swap deb.debian.org for a faster regional mirror, e.g.
# docker build --build-arg APT_MIRROR=mirrors.tuna.tsinghua.edu.cn -t record-asr .
# Defaults to the upstream deb.debian.org (no swap). ffmpeg (~250MB of codec
# libs) decodes m4a/aac/opus/wma — beep is pure-Go for wav/mp3/flac/ogg only.
ARG APT_MIRROR=
RUN set -eux; \
if [ -n "$APT_MIRROR" ]; then \
f=/etc/apt/sources.list.d/debian.sources; \
if [ -f "$f" ]; then sed -i "s|deb.debian.org|$APT_MIRROR|g; s|security.debian.org|$APT_MIRROR|g" "$f"; \
else sed -i "s|deb.debian.org|$APT_MIRROR|g; s|security.debian.org|$APT_MIRROR|g" /etc/apt/sources.list; fi; \
fi; \
apt-get update \
&& apt-get install -y --no-install-recommends ca-certificates curl ffmpeg \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /app
COPY --from=builder /out/record-asr /app/record-asr
COPY --from=builder /out/lib /app/lib
COPY --from=models /models /models
# Defaults; override via -e / compose. Models are baked in at /models, so
# startup skips the download entirely. Only /app/data (tasks + uploads) is a
# volume; it never holds models.
ENV ASR_ADDR=:8080 \
ASR_DATA_DIR=/app/data \
ASR_MODEL_DIR=/models \
ASR_DOWNLOAD_TIMEOUT=1800 \
LD_LIBRARY_PATH=/app/lib
VOLUME /app/data
EXPOSE 8080
HEALTHCHECK --interval=30s --timeout=5s --start-period=30s --retries=3 \
CMD curl -fsS http://127.0.0.1:8080/healthz || exit 1
ENTRYPOINT ["/app/record-asr"]