Every whisper.cpp invocation loads the model from scratch, which for a large model takes longer than recognising a few seconds of speech. Running it once per file meant that across seventeen thousand recordings the loading would dominate the work entirely. Files now go in batches of sixteen — 40 files took 3 runs instead of 40 in a stub test, with each file still getting its own result. A batch has to be one language, since -l applies to the whole invocation, so work is grouped by the language derived from the wavs/<code>/ path. Results come back as files next to the inputs (-otxt) rather than on stdout, because with several files in one run stdout cannot be split per file. Cancellation now lands between batches rather than between files, which at sixteen files is close enough. Thread count is left at whisper's own default and exposed as catalog.whisper.threads: raising it buys speed at the cost of heat, and on a fanless machine that turns into throttling anyway. Docker: whisper.cpp bumped to v1.9.2 to match what Homebrew installs. The library naming changed there — versioned sonames like libggml.so.0 — and the copy pattern had to widen to match, otherwise the binary could not start. Verified with a stub in place of whisper-cli, on the host and inside the container: batching holds, each file gets its own text, and the temp directory works as uid 10001. Nothing was left in the transcript table. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
74 lines
3.4 KiB
Docker
74 lines
3.4 KiB
Docker
# Build wymaga submodułu vendor/Rex-EMoolator — composite build kompiluje :core
|
|
# ze źródeł. Jeśli katalog jest pusty, settings.gradle przerwie z komunikatem.
|
|
FROM eclipse-temurin:21-jdk AS build
|
|
WORKDIR /src
|
|
|
|
# najpierw sam opis buildu: zmiana w kodzie nie unieważnia pobranych zależności
|
|
COPY gradlew settings.gradle build.gradle gradle.properties ./
|
|
COPY gradle ./gradle
|
|
COPY vendor ./vendor
|
|
RUN ./gradlew --no-daemon dependencies --configuration runtimeClasspath > /dev/null 2>&1 || true
|
|
|
|
COPY src ./src
|
|
# installDist zamiast build: pomija check, a więc i verifyCoreVersion, które
|
|
# potrzebowałoby gita w obrazie. Wersję i tak przypina submoduł.
|
|
RUN ./gradlew --no-daemon installDist \
|
|
&& grep '^coreVersion=' gradle.properties | cut -d= -f2 > /src/core-version
|
|
|
|
# whisper.cpp budowany ze źródeł: w repozytoriach Debiana go nie ma, a binarka
|
|
# z hosta jest nie do użycia — tam macOS, tu Linux.
|
|
#
|
|
# GGML_NATIVE=OFF, bo domyślnie ggml stroi kod pod procesor maszyny budującej
|
|
# (na arm64 przekazuje -mcpu=native+nodotprod..., czego GCC 12 nie rozumie),
|
|
# a obraz i tak ma chodzić także na innym sprzęcie niż ten, na którym powstał
|
|
FROM debian:bookworm-slim AS whisper
|
|
RUN apt-get update \
|
|
&& apt-get install -y --no-install-recommends git cmake build-essential ca-certificates \
|
|
&& git clone --depth 1 --branch v1.9.2 https://github.com/ggerganov/whisper.cpp /src \
|
|
&& cmake -S /src -B /src/build -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=ON \
|
|
-DGGML_NATIVE=OFF -DWHISPER_BUILD_TESTS=OFF -DWHISPER_BUILD_EXAMPLES=ON \
|
|
&& cmake --build /src/build --target whisper-cli -j "$(nproc)" \
|
|
&& mkdir -p /out/bin /out/lib \
|
|
&& cp /src/build/bin/whisper-cli /out/bin/ \
|
|
&& find /src/build \( -name 'libwhisper.so*' -o -name 'libggml*.so*' \) \
|
|
-exec cp -P {} /out/lib/ \; \
|
|
&& rm -rf /var/lib/apt/lists/* /src
|
|
|
|
FROM eclipse-temurin:21-jre
|
|
WORKDIR /app
|
|
|
|
# obrazy płyt montowane z zewnątrz, tylko do odczytu; katalog danych to wolumen
|
|
VOLUME ["/data"]
|
|
|
|
# whisper.cpp i ffmpeg wchodzą do obrazu, bo to kilkadziesiąt megabajtów.
|
|
# Model NIE wchodzi: waży kilkaset megabajtów do kilku gigabajtów, każdy trzyma
|
|
# inny i wybór należy do użytkownika — montuje się go pod /models i wskazuje
|
|
# przez WHISPER_MODEL. Bez modelu katalog działa normalnie, a front mówi wprost,
|
|
# czego brakuje: mówcę i kontekst kwestii bierzemy z dialogi.dta, nie z modelu.
|
|
RUN apt-get update \
|
|
&& apt-get install -y --no-install-recommends ffmpeg \
|
|
&& rm -rf /var/lib/apt/lists/*
|
|
# kopiujemy wprost z drzewa budowania: `cmake --install` chciałby zainstalować
|
|
# wszystkie przykłady, a budujemy tylko whisper-cli
|
|
COPY --from=whisper /out/bin/whisper-cli /usr/local/bin/whisper-cli
|
|
COPY --from=whisper /out/lib/ /usr/local/lib/
|
|
RUN ldconfig
|
|
ENV WHISPER_BIN=/usr/local/bin/whisper-cli
|
|
# file.encoding ustawia entrypoint przez JAVA_OPTS; JAVA_TOOL_OPTIONS robiłoby
|
|
# to samo, ale JVM wypisuje wtedy "Picked up..." przy każdym uruchomieniu
|
|
ENV CATALOG_DATA=/data
|
|
|
|
COPY --from=build /src/build/install/rex-catalog /app
|
|
COPY --from=build /src/core-version /app/core-version
|
|
COPY docker-entrypoint.sh /app/entrypoint.sh
|
|
RUN chmod +x /app/entrypoint.sh \
|
|
&& useradd --uid 10001 --create-home katalog \
|
|
&& mkdir -p /data /media \
|
|
&& chown katalog:katalog /data
|
|
USER katalog
|
|
|
|
EXPOSE 8765
|
|
ENTRYPOINT ["/app/entrypoint.sh"]
|
|
# domyślnie wstajemy jako serwer; front i MCP dzielą port
|
|
CMD ["serve", "--host", "0.0.0.0"]
|