Skip to content

Commit 3deb137

Browse files
committed
vosk: Add version 0.3.45
1 parent e555049 commit 3deb137

2 files changed

Lines changed: 244 additions & 0 deletions

File tree

‎.github/workflows/build-vosk.yml‎

Lines changed: 239 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,239 @@
1+
# SPDX-FileCopyrightText: 2026 The RISE Project
2+
# SPDX-License-Identifier: MIT
3+
---
4+
# vosk publishes no sdist and has no GitHub Actions CI; the wheels come from
5+
# https://github.com/alphacep/vosk-api/blob/v0.3.45/travis/Dockerfile.dockcross-manylinux
6+
# and travis/build-wheels-dockcross.sh, whose CROSS_TRIPLE case already names
7+
# riscv64, built here natively in the manylinux image instead of under dockcross.
8+
name: Build vosk wheels (riscv64)
9+
10+
on:
11+
workflow_dispatch:
12+
inputs:
13+
version:
14+
description: 'Version glob to (re)build; empty builds every version of docs/packages/vosk.yaml not released yet'
15+
required: false
16+
default: ''
17+
pull_request:
18+
branches: [main]
19+
paths:
20+
- '.github/workflows/build-vosk.yml'
21+
- 'docs/packages/vosk.yaml'
22+
push:
23+
branches: [main]
24+
paths:
25+
- '.github/workflows/build-vosk.yml'
26+
- 'docs/packages/vosk.yaml'
27+
28+
run-name: build-vosk ${{ inputs.version && format('- {0}', inputs.version) || '' }}
29+
30+
concurrency:
31+
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
32+
cancel-in-progress: true
33+
34+
permissions:
35+
contents: read
36+
37+
env:
38+
MANYLINUX_RISCV64_IMAGE: quay.io/pypa/manylinux_2_39_riscv64
39+
# Upstream's Dockerfiles clone these three branch heads unpinned; pinned to the
40+
# commits they resolve to, so a rebuild of this version stays reproducible.
41+
KALDI_REF: bc5baf14231660bd50b7d05788865b4ac6c34481
42+
OPENFST_REF: 18e94e63870ebcf79ebb42b7035cd3cb626ec090
43+
CLAPACK_REF: f4e1647de96343fb20eea08a9d4f0e0d04c31c51
44+
OPENBLAS_VERSION: v0.3.20
45+
VOSK_MODEL: vosk-model-small-en-us-0.15
46+
47+
jobs:
48+
setup:
49+
uses: $/.github/workflows/_setup.yml
50+
with:
51+
package: vosk
52+
version: ${{ inputs.version }}
53+
54+
build_wheels:
55+
name: Build vosk ${{ matrix.version }} py3-manylinux_riscv64
56+
runs-on: ubuntu-24.04-riscv
57+
timeout-minutes: 720
58+
needs: [setup]
59+
if: needs.setup.outputs.versions != '[]'
60+
61+
strategy:
62+
fail-fast: false
63+
matrix:
64+
version: ${{ fromJSON(needs.setup.outputs.versions) }}
65+
66+
env:
67+
VOSK_VERSION: ${{ matrix.version }}
68+
69+
steps:
70+
- name: Checkout alphacep/vosk-api
71+
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
72+
with:
73+
repository: alphacep/vosk-api
74+
ref: v${{ env.VOSK_VERSION }}
75+
path: vosk-api
76+
persist-credentials: false
77+
78+
- name: Build wheel
79+
run: |
80+
mkdir -p wheelhouse
81+
set -o pipefail
82+
docker run --rm -i --network=host \
83+
-v "${GITHUB_WORKSPACE}:/work" \
84+
-w /work \
85+
-e KALDI_REF \
86+
-e OPENFST_REF \
87+
-e CLAPACK_REF \
88+
-e OPENBLAS_VERSION \
89+
"${MANYLINUX_RISCV64_IMAGE}" \
90+
bash <<'SCRIPT' 2>&1 | tee build.log
91+
set -eux
92+
93+
dnf install -y --disablerepo=extras --setopt=install_weak_deps=False autoconf automake libtool
94+
95+
fetch() {
96+
mkdir -p "$2" && git -C "$2" init -q .
97+
git -C "$2" fetch -q --depth 1 "$1" "$3"
98+
git -C "$2" checkout -q FETCH_HEAD
99+
}
100+
101+
fetch https://github.com/alphacep/kaldi /opt/kaldi "${KALDI_REF}"
102+
cd /opt/kaldi/tools
103+
git clone -q --depth 1 -b "${OPENBLAS_VERSION}" --single-branch https://github.com/xianyi/OpenBLAS
104+
fetch https://github.com/alphacep/clapack /opt/kaldi/tools/clapack "${CLAPACK_REF}"
105+
fetch https://github.com/alphacep/openfst /opt/kaldi/tools/openfst "${OPENFST_REF}"
106+
107+
# TARGET is what upstream's build-dockcross-manylinux.sh passes per architecture
108+
# (ARMV8 there); RISCV64_GENERIC is the only riscv64 target of OpenBLAS 0.3.20
109+
# whose kernels are plain C, C910V being RVV 0.7.1.
110+
make -C OpenBLAS ONLY_CBLAS=1 TARGET=RISCV64_GENERIC HOSTCC=gcc USE_LOCKING=1 USE_THREAD=0 -j "$(nproc)" all
111+
make -C OpenBLAS ONLY_CBLAS=1 TARGET=RISCV64_GENERIC HOSTCC=gcc USE_LOCKING=1 USE_THREAD=0 PREFIX="$(pwd)/OpenBLAS/install" install
112+
113+
mkdir -p clapack/BUILD && cd clapack/BUILD
114+
# clapack declares cmake_minimum_required(VERSION 2.6), which the image's CMake 4 refuses.
115+
cmake -DCMAKE_POLICY_VERSION_MINIMUM=3.5 ..
116+
make -j "$(nproc)" -C F2CLIBS
117+
make -j "$(nproc)" -C BLAS
118+
make -j "$(nproc)" -C SRC
119+
find . -name "*.a" | xargs cp -t ../../OpenBLAS/install/lib
120+
121+
cd /opt/kaldi/tools/openfst
122+
autoreconf -i
123+
CFLAGS="-g -O3" ./configure --prefix=/opt/kaldi/tools/openfst --enable-static --enable-shared \
124+
--enable-far --enable-ngram-fsts --enable-lookahead-fsts --with-pic --disable-bin
125+
make -j "$(nproc)"
126+
make install
127+
128+
cd /opt/kaldi/src
129+
./configure --mathlib=OPENBLAS_CLAPACK --shared --use-cuda=no
130+
sed -i 's: -O1 : -O3 :g' kaldi.mk
131+
make -j "$(nproc)" online2 lm rnnlm
132+
133+
cd /work/vosk-api/src
134+
KALDI_ROOT=/opt/kaldi OPENFST_ROOT=/opt/kaldi/tools/openfst \
135+
OPENBLAS_ROOT=/opt/kaldi/tools/OpenBLAS/install make -j "$(nproc)"
136+
137+
export PATH="/opt/python/cp312-cp312/bin:${PATH}"
138+
export PIP_EXTRA_INDEX_URL=https://pypi.riseproject.dev/simple/
139+
python -m pip install -q auditwheel cffi requests setuptools srt tqdm websockets wheel
140+
141+
# libvosk.so statically links all four, and upstream's wheels carry no licence at all.
142+
cd /work/vosk-api
143+
cp COPYING python/LICENSE
144+
cp /opt/kaldi/COPYING python/LICENSE.kaldi
145+
cp /opt/kaldi/tools/openfst/COPYING python/LICENSE.openfst
146+
cp /opt/kaldi/tools/OpenBLAS/LICENSE python/LICENSE.openblas
147+
cp /opt/kaldi/tools/clapack/COPYING python/LICENSE.clapack
148+
149+
VOSK_SOURCE=/work/vosk-api python -m pip wheel /work/vosk-api/python \
150+
--no-deps --no-build-isolation -w /work/dist
151+
auditwheel repair --plat manylinux_2_39_riscv64 -w /work/wheelhouse /work/dist/*.whl
152+
SCRIPT
153+
154+
- name: Upload build log
155+
if: failure()
156+
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
157+
with:
158+
name: vosk-${{ env.VOSK_VERSION }}-build-log
159+
path: build.log
160+
161+
- name: Check the wheel bundles libvosk.so and stays interpreter-agnostic
162+
run: |
163+
python3 - wheelhouse/*.whl <<'EOF'
164+
import sys, zipfile
165+
for whl in sys.argv[1:]:
166+
assert "-py3-none-" in whl and whl.endswith("manylinux_2_39_riscv64.whl"), whl
167+
names = zipfile.ZipFile(whl).namelist()
168+
assert "vosk/libvosk.so" in names, names
169+
assert not any(n.endswith(".so") and ".cpython-" in n for n in names), names
170+
# Everything but libstdc++ is linked statically, so auditwheel vendors nothing;
171+
# a vosk.libs/ here would mean the wheel ships a library with no licence text.
172+
assert not any(n.startswith("vosk.libs/") for n in names), names
173+
for want in ("LICENSE", "LICENSE.kaldi", "LICENSE.openfst", "LICENSE.openblas", "LICENSE.clapack"):
174+
assert any(n.endswith("/" + want) for n in names), (want, names)
175+
print(whl, "ok")
176+
EOF
177+
178+
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
179+
with:
180+
name: vosk-${{ env.VOSK_VERSION }}-py3-manylinux_riscv64
181+
path: wheelhouse/*.whl
182+
if-no-files-found: error
183+
184+
- name: Test wheel
185+
run: |
186+
docker run --rm -i --network=host \
187+
-v "${GITHUB_WORKSPACE}:/work" \
188+
-e PIP_EXTRA_INDEX_URL=https://pypi.riseproject.dev/simple/ \
189+
-e VOSK_MODEL \
190+
"${MANYLINUX_RISCV64_IMAGE}" \
191+
bash <<'SCRIPT'
192+
set -eux
193+
194+
cd /tmp
195+
for pytag in cp312-cp312 cp313-cp313 cp314-cp314 cp314-cp314t; do
196+
PYTHON_BIN="/opt/python/${pytag}/bin/python"
197+
"${PYTHON_BIN}" -m pip install -q /work/wheelhouse/*.whl
198+
"${PYTHON_BIN}" - /work/vosk-api/python/example/test.wav <<'PY'
199+
import json
200+
import os
201+
import sys
202+
import wave
203+
204+
from vosk import Model, KaldiRecognizer, SetLogLevel
205+
206+
SetLogLevel(-1)
207+
model = Model(model_name=os.environ["VOSK_MODEL"])
208+
wf = wave.open(sys.argv[1], "rb")
209+
rec = KaldiRecognizer(model, wf.getframerate())
210+
rec.SetWords(True)
211+
while True:
212+
data = wf.readframes(4000)
213+
if not data:
214+
break
215+
rec.AcceptWaveform(data)
216+
result = json.loads(rec.FinalResult())
217+
print(result["text"])
218+
assert "zero" in result["text"].split(), result
219+
assert len(result["result"]) >= 10, result
220+
PY
221+
done
222+
SCRIPT
223+
224+
publish:
225+
name: Publish vosk ${{ matrix.version }}
226+
needs: [setup, build_wheels]
227+
if: needs.setup.outputs.versions != '[]'
228+
strategy:
229+
fail-fast: false
230+
matrix:
231+
version: ${{ fromJSON(needs.setup.outputs.versions) }}
232+
permissions:
233+
contents: write
234+
pull-requests: write
235+
uses: $/.github/workflows/_publish-wheel.yml
236+
secrets:
237+
app-private-key: ${{ secrets.RISEPROJECT_APP_PRIVATE_KEY }}
238+
with:
239+
artifact-pattern: vosk-${{ matrix.version }}-py3-manylinux_riscv64

‎docs/packages/vosk.yaml‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package-name: vosk
2+
source-code: https://github.com/alphacep/vosk-api
3+
license: Apache-2.0
4+
versions:
5+
- version: 0.3.45

0 commit comments

Comments
 (0)