voice_audio_multi/docs/models/soulx_flashhead.md
Fabio c36510c21e
Some checks failed
Linux Build / Linux cpu (push) Has been cancelled
Linux Build / Linux cpu-clang (push) Has been cancelled
Linux Build / Linux vulkan (push) Has been cancelled
mac-build / macOS CPU (push) Has been cancelled
Nix Build / Nix (cpu) (push) Has been cancelled
Nix Build / Nix (vulkan) (push) Has been cancelled
windows-build / Windows CPU (push) Has been cancelled
Initial import: audio.cpp with Orange Pi documentation
2026-11-04 19:05:22 +01:00

169 lines
7.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# SoulX-FlashHead
> [!IMPORTANT]
> **cuDNN is strongly recommended for Lite on CUDA:** about **2× faster warm
> inference** with roughly half the peak VRAM in the RTX 5090 Q8 measurement
> (**9,152 → 5,168 MiB; 44% less VRAM**).
> **Prebuilt binaries do not include cuDNN support.** Build from source with
> cuDNN and `-DGGML_CUDA_CUDNN_CONV3D=ON`, then select
> `--session-option 'soulx_flashhead.exec_plan={"vae":{"impl":"cudnn"}}'`.
SoulX-FlashHead generates portrait video from a reference image and speech audio.
The family uses a shared audio-conditioned DiT with variant-specific video VAEs:
Lite uses LTX and Pro uses Wan. Only Lite GGUF weights are provided.
Upstream: [Soul-AILab/SoulX-FlashHead](https://github.com/Soul-AILab/SoulX-FlashHead).
## Download Lite
GGUF packages: [audio-cpp/SoulX-FlashHead-GGUF](https://huggingface.co/audio-cpp/SoulX-FlashHead-GGUF).
Q8 is the default package; BF16 is also available. Both include all required weights and configuration.
```bash
hf download audio-cpp/SoulX-FlashHead-GGUF SoulX-FlashHead-Lite-Q8_0.gguf \
--local-dir models/SoulX-FlashHead-GGUF
```
## Convert Lite
Download `Model_Lite/` and `VAE_LTX/` from
[Soul-AILab/SoulX-FlashHead-1_3B](https://huggingface.co/Soul-AILab/SoulX-FlashHead-1_3B),
and the model and configuration files from
[facebook/wav2vec2-base-960h](https://huggingface.co/facebook/wav2vec2-base-960h).
```bash
python tools/community_models/soulx_flashhead/convert_gguf.py \
--source /path/to/SoulX-FlashHead-1_3B \
--audio-encoder /path/to/wav2vec2-base-960h \
--type bf16 \
--output /path/to/SoulX-FlashHead-GGUF/SoulX-FlashHead-Lite-BF16.gguf
```
The GGUF contains the DiT, video VAE, speech encoder, configuration and model
contract. No Python runtime or original checkpoint files are needed for C++ inference.
## Generate
```bash
build/debug/bin/audiocpp_cli \
--family soulx_flashhead --task gen \
--model /path/to/SoulX-FlashHead-Lite-Q8_0.gguf \
--backend cuda --threads 8 \
--audio /path/to/speech.wav \
--request-option reference_image_file=/path/to/portrait.png \
--out-dir outputs/flashhead \
--log --log-file outputs/flashhead/run.log
```
Use `--mode streaming` to supply audio incrementally. Streaming input must be
mono 16 kHz. Lite emits 24 frames per audio block at 25 FPS, carrying nine motion
frames between blocks. The audio encoder uses an eight-second sliding window.
A partial final audio block is padded with silence, matching upstream.
Output artifacts contain RGB24 frames with width, height, frame count, frame rate
and chunk index metadata. Streaming consumers can display each chunk as it arrives.
| Request option | Default | Meaning |
|---|---:|---|
| `reference_image_file` | required | Reference portrait; resized and center-cropped. |
| `height`, `width` | 512 | Frame size; divisible by the variant's VAE spatial stride. |
| `num_inference_steps` | 4 | Denoising steps for distilled checkpoints. |
| `seed` | 42 | Generation seed. |
| `color_correction_strength` | 1 | Match the portrait's color statistics; zero disables correction. |
| `audio_guidance_scale` | 3 | Audio guidance for non-distilled checkpoints; unused by Lite/Pro. |
Encode the artifacts as an MP4, optionally muxing the source speech:
```bash
python tools/community_models/soulx_flashhead/render_video.py \
--input outputs/flashhead --audio /path/to/speech.wav \
--output outputs/flashhead/video.mp4
```
## Variant boundaries
The DiT reads channel counts, transformer dimensions, patch size and temporal/spatial
VAE strides from the embedded configuration. Lite selects the LTX VAE; Pro and the
non-distilled architecture select the shared Wan VAE modules. Non-distilled weights
use Euler updates with `audio_guidance_scale` (default 3); distilled checkpoints use
the upstream re-noising update. Only Lite GGUFs are provided. Pro has also been executed from normalized source
weights. Its Wan VAE passes the forced-latent RGB comparison against upstream.
The unreleased non-distilled checkpoint has not been validated and is not an
advertised package.
The converter accepts `--variant lite|pro|pretrained`; its default is Lite.
Use `--prepare-only` with an output directory to normalize a source checkpoint
without creating a GGUF. The directory can be loaded directly by this family:
```bash
python tools/community_models/soulx_flashhead/convert_gguf.py \
--source /path/to/SoulX-FlashHead-1_3B \
--audio-encoder /path/to/wav2vec2-base-960h \
--variant pro --prepare-only --output /path/to/FlashHead-Pro-normalized
```
Use that directory as `--model` in the generation command above.
Lite uses the session-owned LTX video VAE runtime, which caches its encode/decode
graphs and shares their scratch arena. Video stays on the backend through color
correction and motion encoding; RGB frames are copied to the host for delivery.
CUDA attention uses SageAttention2 when the build and device support its head
dimensions, otherwise Flash Attention.
Enable the optional native cuDNN Conv3D path for Lite CUDA builds:
```bash
cmake -S . -B build/debug -DCMAKE_BUILD_TYPE=Debug \
-DENGINE_ENABLE_CUDA=ON -DGGML_CUDA_CUDNN_CONV3D=ON \
-DCUDNN_ROOT=/path/to/cudnn
cmake --build build/debug --parallel 8
```
When explicitly selected through the execution plan below, this requires cuDNN
headers and libraries. Native Lite convolutions use F16 operands,
F32 accumulation, and F16 output storage; channel bias is added in F32 to the
F16 convolution result before the final F16 cast. Residual storage is also F16.
Normalization accumulates in F32 with F16 output on the native path. DiT
intermediates, color processing, and public VAE inputs/outputs use F32. These paths avoid reproducing every Python BF16 intermediate rounding;
small numerical differences are expected.
## Server streaming
Configure a streaming entry and start `audiocpp_server` with that config:
```json
{
"host": "127.0.0.1",
"port": 8080,
"backend": "cuda",
"threads": 8,
"lazy_load": true,
"models": [{
"id": "flashhead",
"family": "soulx_flashhead",
"path": "/path/to/SoulX-FlashHead-Lite-Q8_0.gguf",
"task": "gen",
"mode": "streaming"
}]
}
```
```bash
curl -N http://127.0.0.1:8080/v1/tasks/stream \
-H 'Content-Type: application/json' \
-d '{"model":"flashhead","stream_format":"sse","include_artifacts":true,"request":{"audio":"/path/to/speech-16k-mono.wav","options":{"reference_image_file":"/path/to/portrait.png"}}}'
```
Each `task.stream.event` carries video chunks in `event.artifacts`. Decode the
artifact's Base64 `payload` as RGB24 using its width, height, frames and FPS
metadata. `chunk_index` gives the order. Chunks arrive during generation;
`task.stream.done` ends the request and does not repeat their payloads. For a
complete non-streaming result, configure an `offline` entry and use
`/v1/tasks/run` instead. A streaming entry delivers video through stream events;
`/v1/tasks/run` does not collect those events into its response.
Select the generic VAE with an omitted execution plan or explicitly with
`--session-option 'soulx_flashhead.exec_plan={"vae":{"impl":"ggml"}}'`.
For Lite on CUDA, select the optional cuDNN implementation with
`--session-option 'soulx_flashhead.exec_plan={"vae":{"impl":"cudnn"}}'`.
This requires the cuDNN Conv3D build option above; an unavailable implementation
is rejected rather than silently substituted.