6.5 KiB
name, description
| name | description |
|---|---|
| ryzenai-npu-oga-linux-spike | Run a vendor-compiled AMD Ryzen AI (XDNA2) ONNX-GenAI model on a Linux Strix Halo host from public artifacts: staging, rootless NPU device-access wall, container recipe, and the NuTTS-air speech-token contract. |
Run an AMD-precompiled XDNA2 model (OGA / onnxruntime-genai) on a Linux Strix Halo host (Dankclaw-class) without installing the vendor stack on the host.
Where the bits actually live (both public, no AMD account)
- Runtime tarball:
https://download.amd.com/opendownload/RyzenAI/1.8.0/ryzen_ai-1.8.0.tgz(~7.28 GiB). Verify with a ranged GET — first bytes1f 8b 08. - NPU driver/XRT zip:
https://download.amd.com/opendownload/RyzenAI/Driver/RAI_1.8_Linux_NPU_XRT.zip(90 MB). - Dead ends (404, do not re-probe):
download.amd.com/driver/linux/RAI_1.8_Linux_NPU_XRT.zip,.../opendownload/RyzenAI/ryzen_ai-1.8.0.tgz,www.xilinx.com/bin/public/openDownload?filename=...(301 → 404). The login-walled EULA form is not the gate; theopendownloadtree is the real file host.
Tarball has 30 top-level entries: cp312/linux_x86_64 wheels (onnxruntime_genai_ryzenai-0.14.0, onnxruntime_vitisai-1.27.0, vitis_mllib, flexml*, device_essentials_strx, model_generate, voe-1.8.0), plus deployment.tar.gz (contains lib/libonnxruntime-genai.so, lib/libonnxruntime_providers_ryzenai.so, AIE compiler libs), onnxruntime.tar.gz, quicktest.tar.gz (VitisAI-EP install validator), LLM.tar.gz (text-only OGA examples: run_model.py, tokenizer_factory.py), install_ryzen_ai.sh. voe-4.0-linux_x86_64.tar.gz is only vaip_config.json — no TTS xclbins. AMD ships no TTS runner and no TTS example.
Host rules
- Never
dpkg -ithe vendor XRT.dpkg-deb -x <deb> <dir>and bind-mount<dir>/opt/xilinx/xrtat the same path in the container. The plugin deb would install a DKMSamdxdnathat replaces the distro in-tree driver; the in-tree driver on Ubuntu 26.04 isamdxdna 0.7.0and already loadsamdnpu/17f0_11/npu_7.sbinat boot (dmesg | grep amdxdna). - Rootless containers cannot read
/dev/accel/accel0(root:render 0660): the host gid never enters the userns gid map, so--deviceyieldsnobody:nogroup. Verified failing 2026-10-19:--group-add keep-groups,--userns=keep-id,--userns=keep-id:gid=990(process gets gid 990, node still unreadable),--group-add render,--group-add gid:990(both error). Options: run rootful (sudo podman, separate storage → rebuild the image rootful, ~1 min), or add a world-writable udev rule foraccel0(the fleet already does exactly this forkfd/renderD*in99-comfyui-gpu-access.rules, whose header explains why: systemd user-unit spawns carry no supplementary groups). - Rootless image build trap: the vendor installer's
tar -xfpreserves recorded uids (95777 etc.) and aborts underset -ewithCannot change ownership ... Invalid argument, silently skipping thedeployment/onnxruntimeextraction. Patch it in the Containerfile:sed -i 's/tar -xf/tar --no-same-owner -xf/g' install_ryzen_ai.sh. - Installer usage:
./install_ryzen_ai.sh -a yes -p /opt/rai -c /opt/rai(python 3.12 required; basepython:3.12-slim; needslinux-libc-dev zip pciutils patch libgomp1). It builds a venv from the local wheels, reinstallsonnxruntime-vitisaithen--no-deps onnxruntime-genai-ryzenai, installsrequirements_extras.txt(transformers 4.57.6), patchesbin/activate(setsRYZEN_AI_INSTALLATION_PATH=$VIRTUAL_ENV+LD_LIBRARY_PATHinto site-packages), and untarsLLM/deployment/onnxruntime/voe/quicktestinto the cpp path.
HF artifact staging
- Gated (401 on API, 403 on git) for a plain account:
neuphonic/neucodec(the only NeuCodec encoder),neuphonic/neucodec-onnx-decoder,neuphonic/neucodec-onnx-decoder-int8,neuphonic/neutts-air.amd/neutts-air_rai_1.8.0_npu_4Kis public. Public mirrors of the codec exist (eugenehp/neucodechas the full 1.16 GBpytorch_model.bin) — treat a mirror of a gated release as a licensing decision for the operator, not a workaround to take silently. github.com/neuphonic/neuttsis public and shipssamples/{dave,emily,greta,jo}.{pt,txt,wav}= pre-encoded reference codes + transcripts → a spike needs zero gated bytes.- Auth without leaking the token into
ps: build a 600-perm credential file with a shell builtin and point git at it —umask 077; printf 'https://oauth2:%s@huggingface.co\n' "$(cat ~/.cache/huggingface/token)" > ~/.git-credentials-hfthengit -c credential.helper="store --file ~/.git-credentials-hf" clone .... Nevergit clone https://oauth2:$TOKEN@....
NuTTS-air on XDNA2 (the model-side contract)
- The package is an OGA model dir:
genai_config.json(type: qwen2, 24 layers, hidden 896, 14 heads / 2 KV, ctx 32768,provider_options: [{"RyzenAI": {"hybrid_opt_token_backend": "npu"}}]), plusdd_metastate_*AIE artifacts andmodel.onnx+model.onnx.data. - Speech tokens live in the text vocab:
<|speech_0|>= id 151671 (10 001 codes), with<|TEXT_PROMPT_START|>151666,<|TEXT_PROMPT_END|>151667,<|TEXT_REPLACE|>151665,<|SPEECH_REPLACE|>151668,<|SPEECH_GENERATION_START|>151669,<|SPEECH_GENERATION_END|>151670. Generation is a plainog.Generatorloop; the graph's owneos_token_idis[151645, 151643], so pass 151670 as an extra eos or stop on it manually. - Real-time line = 50 speech tokens/s (
sample_rate=24000,hop_length=480). Judge any NPU/iGPU TTS number against 50. - Build the prompt by importing the vendor function, never by copying the template:
sys.path.insert(0, <neutts repo>); from neutts.neutts import NeuTTS, thenNeuTTS._apply_chat_template(SimpleNamespace(tokenizer=hf_tok, input_format="text"), ref_codes, ref_text, text, None)— works on a duck-typedself, so no backbone/codec load. Template:user\n<|TEXT_REPLACE|>\nassistant\n<|SPEECH_REPLACE|>; spliceTEXT_PROMPT_START + encode(f"{ref_text} {text}") + TEXT_PROMPT_ENDat TEXT_REPLACE, then truncate at SPEECH_REPLACE and append[SPEECH_GENERATION_START] + encode("".join(f"<|speech_{i}|>")). - Voice identity = reference codes + transcript (request-time conditioning). No trained artifact exists to preserve; packs holding only
reference.wavrequire the gated encoder once, offline.
Status caveat
Measured on 2026-10-19 up to and including: staged artifacts, image build, device-access matrix, prompt contract. The token-rate measurement (does the vendor userspace drive the in-tree 0.7.0 driver, and does it clear 50 tok/s) is not captured here — re-measure, never trust a remembered rate.