gizai:flashhead
SoulX FlashHead lite, a talking head from one picture and speech, as its reference package and giz's worker run it.
The picture is cut around its face (MediaPipe's detector, gizai:video) and scaled to 512 x 512; LTX-Video 0.9's VAE (gizai:ltx) codes it, repeated over 33 frames, to a reference latent of 5 frames of 16 x 16. The speech goes in slices of 24 frames (15360 samples at 16 kHz). For each slice, the last 8 s of speech go through wav2vec 2.0 base (gizai:wav2vec), its 12 layers' states taken at 200 frames, and 5 states around each of the slice's 33 frames make 5 latent frames of 32 audio tokens. A Wan-style transformer (30 blocks of 1536, 12 heads, its rotary over frame, row and column) predicts the flow of the noisy latent, whose first latent frames are the motion of the slice before, in 4 steps; the VAE decodes 33 frames, their colors match the picture's (Lab means and deviations), and the last 9 are coded again as the next slice's motion. Each slice gives its last 24 frames.
import * as Flashhead from "gizai:flashhead";Types
FlashHead
type FlashHead = { gpu: Gpu; blocks: Vec<Block>; patch: N.Linear; head: N.Linear; headMods: Vec<Tensor>; proj1: N.Linear; proj1vf: N.Linear; proj2: N.Linear; proj3: N.Linear; projNorm: Vec<Tensor>; cos: Tensor; sin: Tensor; ones: Tensor; zeros: Tensor; map: Tensor; w2v: W2.Encoder; vae: L.VideoVae; encoder: L.VideoEncoder09; faces: V.Faces; work: Scratch; }The model where it runs.
gpu:M10.Gpublocks:Vec<M23.Block>patch:M33.Linearhead:M33.LinearheadMods:Vec<M40.Tensor>— At each step: the output norm's shift and scale ([2, 1536] F32).proj1:M33.Linearproj1vf:M33.Linearproj2:M33.Linearproj3:M33.LinearprojNorm:Vec<M40.Tensor>cos:M40.Tensor— The rotary's angles at each row, [1280, 768] F32 (pair d of a head at column h 64 + d).sin:M40.Tensorones:M40.Tensorzeros:M40.Tensormap:M40.Tensorw2v:M45.Encodervae:M30.VideoVaeencoder:M30.VideoEncoder09faces:M44.Faceswork:M23.Scratch
Settings
type Settings = { seed: i64; motion: f64; }Settings of a job: the seed, the motion scale (1: the model's own; less keeps the face nearer the picture).
seed:i64motion:f64
Functions
load
function load(sys: System, folder: string, gpu: Gpu): FlashHead throws stringFlashHead lite of folder (Model_Lite, VAE_LTX, wav2vec2-base-960h, face_detection_full_range_sparse.tflite) on
gpu.
Effects: fail, read, write, console, io.
speechOf
function speechOf(sys: System, ffmpeg: string, path: string): Vec<f32> throws W.FailureThe speech of a file at 16 kHz, its channels averaged (ffmpeg decodes it).
Effects: fail, read, write, io.
serve
function serve(sys: System, folder: string, place: Hosting.Place): i64 throws stringServes FlashHead lite of folder as giz's worker at place: video.talking-head jobs. The kernels build and tune on
one slice of silence at the load, not in the first request (8 s more).
Effects: fail, read, write, console, io.
Methods
FlashHead.picture
function FlashHead.picture(self: FlashHead, image: Image.Image, crop: bool, ratio: f64): Vec<f32> throws stringThe picture the model takes, as the reference makes it: RGB planes ([3, 512, 512]) of bytes as F32 in [0, 1].
With crop, the square around the first face (its width times ratio, centered across, its top half a side's
0.55 above the face's center, moved inside the picture), scaled by Pillow's BICUBIC; then (or without) scaled by
Pillow's BILINEAR to cover 512 x 512 and cut at the center.
Effects: fail, read, write, console, io.
FlashHead.talk
function FlashHead.talk(self: FlashHead, picture: Vec<f32>, speech: Vec<f32>, s: Settings, out: mut V.H264, total: i64, alive: (step: i64, total: i64) => bool): void throws stringThe frames of a talking head of picture (FlashHead.picture's planes) saying speech (16 kHz mono), pushed to
out slice by slice until it has total; alive false stops.
Effects: fail, read, write, console, io.
FlashHead.video
function FlashHead.video(self: FlashHead, sys: System, ffmpeg: string, picture: Vec<f32>, speech: Vec<f32>, s: Settings, alive: (step: i64, total: i64) => bool): bytes throws stringAn MP4 of the talking head of picture saying speech (16 kHz mono): H.264 at 25 fps, a frame for each 1 / 25 s
of speech, and the speech as AAC.
Effects: fail, read, write, console, io.
Constants
MODEL
const MODEL = "soulx-flashhead-lite"The model id and operation of giz's worker.
OPERATION
const OPERATION = "video.talking-head"FPS
const FPS = 25The frames a second, and the speech's samples a second.
RATE
const RATE = 16000