-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbark-cpp.spec
More file actions
384 lines (335 loc) · 11.1 KB
/
Copy pathbark-cpp.spec
File metadata and controls
384 lines (335 loc) · 11.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
# bark.cpp + encodec.cpp on the system ggml package (libggml +
# dlopen backends). Do not compile bundled ggml.
# Out-of-tree cmake/ninja can leave empty debugsourcefiles.list.
%undefine _debugsource_packages
%bcond_without examples
%if %{with examples}
%global build_examples ON
%else
%global build_examples OFF
%endif
# 1.0.0 + encodec sync (chore #199). No newer tag.
%global commit 5d5be84f089ab9ea53b7a793f088d3fbf7247495
%global encodec_commit 1cc279db4da979455651fbac1cbd151a2d121609
Summary: Suno Bark text-to-speech in C/C++ (bark.cpp)
Name: bark-cpp
Version: 1.0.0
Release: 4
License: MIT
Group: Sciences/Other
URL: https://github.com/PABannier/bark.cpp
Source0: https://github.com/PABannier/bark.cpp/archive/%{commit}/bark.cpp-%{commit}.tar.gz
# Vendored as encodec.cpp/ (git submodule). ggml/ is dropped — system ggml.
Source1: https://github.com/PABannier/encodec.cpp/archive/%{encodec_commit}/encodec.cpp-%{encodec_commit}.tar.gz
Patch0: 0001-system-ggml.patch
# Prefer -O3 over distro -Os for the inference hot path
%global optflags %{optflags} -O3
BuildRequires: cmake(ggml) >= 0.22.0
BuildRequires: git-core
Requires: %{mklibname ggml}%{?_isa} >= 0.22.0
Recommends: ggml-backend-blas%{?_isa}
Recommends: ggml-backend-vulkan%{?_isa}
Suggests: ggml-backend-opencl%{?_isa}
Suggests: ggml-backend-hip%{?_isa}
# ggml-config.cmake lists optional backends as hard deps
%global __requires_exclude cmake\\((hip|roc|mkl|intelsycl|cudatoolkit|CUDAToolkit|dnnl|DNNL|openvino|OpenVINO|sycl|SYCL).*
BuildSystem: cmake
BuildOption: -DCMAKE_C_COMPILER=clang
BuildOption: -DCMAKE_CXX_COMPILER=clang++
BuildOption: -DBUILD_SHARED_LIBS:BOOL=ON
BuildOption: -DBARK_USE_SYSTEM_GGML:BOOL=ON
BuildOption: -DENCODEC_USE_SYSTEM_GGML:BOOL=ON
BuildOption: -DBARK_BUILD_EXAMPLES=%{build_examples}
%description
bark.cpp runs Suno Bark text-to-speech (and ships encodec.cpp for the
neural codec). Tensor kernels come from the system ggml package;
optional accelerators are separate:
* ggml-backend-blas — OpenBLAS
* ggml-backend-vulkan — Vulkan
* ggml-backend-opencl — OpenCL
* ggml-backend-hip — AMD ROCm/HIP
Convert official Bark checkpoints with convert.py (needs torch) to
a single ggml_weights.bin. CLI tools are in %{name}-examples, the
HTTP server in %{name}-server.
%package devel
Summary: Development files for %{name}
Group: Development/C++
Requires: %{name}%{?_isa} = %{EVRD}
Requires: cmake(ggml)
%description devel
Headers, pkg-config and CMake package config for bark.cpp
(libbark) and encodec.cpp (libencodec). Requires system ggml
(cmake(ggml)).
%if %{with examples}
%package server
Summary: HTTP inference server for %{name}
Group: Servers
Requires: %{name}%{?_isa} = %{EVRD}
Recommends: bark-cpp-model-bark-small-q4_0
%description server
HTTP server (bark-server) for bark.cpp. POST JSON {"text":"..."}
to /bark and get a WAV back.
Config: %{_sysconfdir}/sysconfig/bark-server
Unit: bark.service (default 127.0.0.1:8083, not upstream 1337,
so it can run next to llama-server, whisper.service and
stable-diffusion.service)
systemctl enable --now bark.service
If MODEL is unset, the unit picks the first readable
ggml_weights.bin (or *.bin) under MODEL_DIRS
(/srv/ai then %{_datarootdir}/%{name}/models). Override with
MODEL=. There is no built-in API key. Do not bind HOST to a
public address without a reverse proxy.
curl -s http://127.0.0.1:8083/bark \
-H "Content-Type: application/json" \
-d '{"text":"This is an audio generated by bark.cpp"}' \
-o out.wav
%package examples
Summary: CLI tools and helpers for %{name}
Group: Sciences/Other
Requires: %{name}%{?_isa} = %{EVRD}
Recommends: bark-cpp-model-bark-small-q4_0
%description examples
CLI tools (bark-cli, bark-quantize, encodec-cli,
encodec-compress, encodec-decompress) and the convert.py /
download_weights.py helpers.
bark-cli -m /srv/ai/bark-small/ggml_weights.bin \
-p "This is an audio generated by bark.cpp" -o out.wav
# CPU only (skip Vulkan / HIP plugins):
bark-cli -ngl 0 -m /srv/ai/ggml_weights.bin -p "hello"
convert.py needs torch and huggingface-hub; it is not run at
build time. download_weights.py pulls the official Suno
checkpoints (network).
%endif
%prep
%setup -q -n bark.cpp-%{commit}
# Submodule checkout is empty in the GitHub archive.
rm -rf encodec.cpp
mkdir encodec.cpp
tar -xzf %{S:1} -C encodec.cpp --strip-components=1
rm -rf encodec.cpp/ggml encodec.cpp/.git encodec.cpp/.github
find . -name '.gitignore' -delete 2>/dev/null || true
%autopatch -p1
%if %{with examples}
%install -a
ln -sf bark-cli %{buildroot}%{_bindir}/bark
mkdir -p %{buildroot}%{_unitdir} %{buildroot}%{_sysconfdir}/sysconfig
mkdir -p %{buildroot}%{_libexecdir}/%{name}
cat >%{buildroot}%{_unitdir}/bark.service <<'UNIT'
[Unit]
Description=Text-to-speech HTTP server (bark.cpp)
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
# Wrapper sources the sysconfig (multiline MODEL_CANDIDATES).
# Do not use EnvironmentFile — systemd cannot parse a multiline list.
ExecStart=%{_libexecdir}/%{name}/bark-server-start
KillMode=process
Restart=on-failure
RestartSec=5s
# Unprivileged, no extra caps. Model file must be readable by this user
# (e.g. mode 0644 under /srv/ai — /home is hidden, see ProtectHome).
DynamicUser=yes
SupplementaryGroups=render video
UMask=0077
NoNewPrivileges=yes
CapabilityBoundingSet=
AmbientCapabilities=
RestrictSUIDSGID=yes
RestrictRealtime=yes
LockPersonality=yes
ProtectHostname=yes
ProtectClock=yes
ProtectKernelTunables=yes
ProtectKernelModules=yes
ProtectKernelLogs=yes
ProtectControlGroups=yes
ProtectProc=invisible
RestrictNamespaces=yes
RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6 AF_NETLINK
SystemCallArchitectures=native
RemoveIPC=yes
# /usr /boot /etc read-only; /home /root invisible. Private /tmp.
# Models: /srv/ai is visible read-only ("-" = skip if missing).
# Extra trees: drop-in ReadOnlyPaths=-/other/models
ProtectSystem=strict
ProtectHome=yes
PrivateTmp=yes
PrivateUsers=no
ReadOnlyPaths=-/srv/ai
# Mesa/Vulkan shader cache, HIP dumps. Server writes /tmp/bark_tmp.wav
# (PrivateTmp).
CacheDirectory=bark-server
Environment=XDG_CACHE_HOME=%{_localstatedir}/cache/bark-server
# GPU: DRM render node + KFD (ROCm). No MemoryDenyWriteExecute —
# Vulkan/HIP compile executable code.
DevicePolicy=closed
DeviceAllow=/dev/null rw
DeviceAllow=/dev/zero rw
DeviceAllow=/dev/urandom r
DeviceAllow=/dev/random r
DeviceAllow=char-drm rw
DeviceAllow=/dev/dri rw
DeviceAllow=/dev/kfd rw
[Install]
WantedBy=multi-user.target
UNIT
cat >%{buildroot}%{_libexecdir}/%{name}/bark-server-start <<'SH'
#!/bin/bash
# Resolve a Bark ggml_weights.bin and exec bark-server.
# Sourced config: /etc/sysconfig/bark-server
set -u
sysconfig=${BARK_SYSCONFIG:-/etc/sysconfig/bark-server}
# shellcheck source=/dev/null
[ -r "$sysconfig" ] && . "$sysconfig"
log() { printf 'bark-server: %s\n' "$*" >&2; }
readable() { [ -f "$1" ] && [ -r "$1" ]; }
# First readable path in a whitespace-separated list (globs allowed).
pick_from_candidates() {
local cand f
shopt -s nullglob
for cand in $1; do
case "$cand" in
\#*) continue ;;
esac
for f in $cand; do
if readable "$f"; then
printf '%s\n' "$f"
return 0
fi
done
done
return 1
}
# Prefer ggml_weights.bin, then any *.bin, in each MODEL_DIRS entry
# (including one-level subdirs such as bark-small/).
pick_from_dirs() {
local dir f
local -a dirs
read -r -a dirs <<< "$1"
shopt -s nullglob
for dir in "${dirs[@]}"; do
[ -z "$dir" ] && continue
[ -d "$dir" ] || continue
for f in \
"${dir%/}/ggml-bark.bin" \
"${dir%/}/ggml-bark-small.bin" \
"${dir%/}/ggml-bark-small-q8_0.bin" \
"${dir%/}/ggml-bark-small-q4_0.bin" \
"${dir%/}/ggml_weights.bin" \
"${dir%/}"/*/ggml_weights.bin \
"${dir%/}"/*.bin
do
if readable "$f"; then
printf '%s\n' "$f"
return 0
fi
done
done
return 1
}
model=
if [ -n "${MODEL:-}" ]; then
if readable "$MODEL"; then
model=$MODEL
else
log "MODEL=$MODEL is not a readable file"
exit 1
fi
elif [ -n "${MODEL_CANDIDATES:-}" ]; then
if ! model=$(pick_from_candidates "$MODEL_CANDIDATES"); then
log "none of MODEL_CANDIDATES is readable"
exit 1
fi
else
dirs=${MODEL_DIRS:-"/srv/ai /usr/share/bark-cpp/models"}
if ! model=$(pick_from_dirs "$dirs"); then
log "no ggml_weights.bin found under: $dirs"
log "drop a converted Bark model in /srv/ai or set MODEL="
exit 1
fi
fi
log "using $model"
if [ -n "${BARK_PRINT_MODEL:-}" ]; then
printf '%s\n' "$model"
exit 0
fi
cmd=(/usr/bin/bark-server --model "$model")
[ -n "${HOST:-}" ] && cmd+=(--address "$HOST")
[ -n "${PORT:-}" ] && cmd+=(--port "$PORT")
if [ -n "${BARK_OPTIONS:-}" ]; then
# Intentional split: BARK_OPTIONS is a flag string.
# shellcheck disable=SC2206
extra=( $BARK_OPTIONS )
cmd+=("${extra[@]}")
fi
exec "${cmd[@]}"
SH
chmod 0755 %{buildroot}%{_libexecdir}/%{name}/bark-server-start
cat >%{buildroot}%{_sysconfdir}/sysconfig/bark-server <<'CFG'
# Bark ggml weights (convert.py → ggml_weights.bin).
# The unit hides /home and /root (ProtectHome=yes). Packaged files
# under /usr/share/bark-cpp/models are visible (ProtectSystem=strict
# leaves /usr readable). /srv/ai is extra (ReadOnlyPaths=-/srv/ai; "-"
# means the unit still starts if that directory is absent). Files must
# be readable by the service (e.g. chmod 0644). Extra trees: drop-in
# ReadOnlyPaths=-/other/models
#
# Resolution, first match wins:
# 1. MODEL= exact path (error if missing)
# 2. MODEL_CANDIDATES whitespace-separated paths/globs
# 3. ggml_weights.bin, then */ggml_weights.bin, then *.bin
# under each MODEL_DIRS entry
#MODEL=/srv/ai/bark-small/ggml_weights.bin
#MODEL_CANDIDATES="/srv/ai/bark-small/ggml_weights.bin /srv/ai/ggml_weights.bin"
MODEL_DIRS="/srv/ai /usr/share/bark-cpp/models"
# bark-server has no --api-key. Anyone who can reach HOST:PORT can
# synthesise speech. Keep HOST on loopback or put a reverse proxy
# with auth in front.
HOST=127.0.0.1
# 8083 so this can run next to llama-server (8080), whisper (8081)
# and stable-diffusion (8082). Upstream default is 1337.
PORT=8083
# GPU is on by default (ggml backends: Vulkan, HIP/ROCm, …).
# CPU only: BARK_OPTIONS="-ngl 0"
# Thread count: BARK_OPTIONS="-t 8"
BARK_OPTIONS=
CFG
mkdir -p %{buildroot}%{_datarootdir}/%{name}/models
install -m 0644 convert.py download_weights.py requirements.txt \
%{buildroot}%{_datarootdir}/%{name}/
install -m 0644 encodec.cpp/convert.py \
%{buildroot}%{_datarootdir}/%{name}/encodec-convert.py
install -m 0644 README.md \
%{buildroot}%{_datarootdir}/%{name}/
%endif
%files
%license LICENSE
%{_libdir}/libbark.so.*
%{_libdir}/libencodec.so.*
%files devel
%doc README.md
%{_includedir}/bark.h
%{_includedir}/encodec.h
%{_libdir}/libbark.so
%{_libdir}/libencodec.so
%{_libdir}/cmake/bark/
%{_libdir}/cmake/encodec/
%{_libdir}/pkgconfig/bark.pc
%{_libdir}/pkgconfig/encodec.pc
%if %{with examples}
%files server
%{_bindir}/bark-server
%{_libexecdir}/%{name}/bark-server-start
%{_unitdir}/bark.service
%config(noreplace) %{_sysconfdir}/sysconfig/bark-server
%files examples
%{_bindir}/bark
%{_bindir}/bark-cli
%{_bindir}/bark-quantize
%{_bindir}/encodec-cli
%{_bindir}/encodec-compress
%{_bindir}/encodec-decompress
%exclude %{_bindir}/bark-server
%{_datarootdir}/%{name}/
%endif