Skip to content

Claude/alpha voice android integration - #66

Merged
lalalune merged 5 commits into
mainfrom
claude/alpha-voice-android-integration
Oct 14, 2026
Merged

lalalune merged 5 commits into
mainfrom
claude/alpha-voice-android-integration

Conversation

@lalalune

Copy link
Copy Markdown
Member

Overview

Additional information

Requirements

lalalune and others added 5 commits October 13, 2026 23:00
convert_paradee_pt_to_gguf.py reads pytorch/text_side.pt and
pytorch/decoder.pt from sahilmahendrakar/Paradee-8M-v1.0 at the revision in
pins.json, after checking size and sha256 of both checkpoints, config.json
and tokenizer.json, and loads them with torch.load(weights_only=True).

- weight_norm pairs are folded with torch._weight_norm, so the GGUF weights
  equal the reference module's effective weights.
- Every state-dict key must be consumed (only the unused ALBERT pooler is
  skipped) and every width is checked against the hparams it writes.
- The GGUF carries general.architecture=paradee, all widths, both learned
  styles, the vocabulary (symbols + ids), the sample rate, the phase-lock
  parameters, the input pins and the converter's git blob sha.
- F32 by default (32 MB). The output is byte-reproducible; pins.json holds
  its sha256 and --check-output enforces it.

pins.json also pins the paradee source commit and the training scripts the
parity reference imports, the reference environment, the published samples
and the test fixtures.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The predictor, decoder and generator had Kokoro-82M's widths as literals
(hid 512 and style 128 in the predictor, 514/1090/1024/512 and style 128 in
the decoder, 512 -> 256 -> 128 in the generator, asr width 512). They now
come from the GGUF tensor shapes, so width-scaled students of Kokoro (such as
Paradee-8M) run on the same code:

- predictor_forward(ctx, PredictorConfig, ...) and
  decoder_forward(ctx, DecoderConfig, ...) take a tensor namespace and the
  student-only options: the asr_proj GELU MLP, the trained InstanceNorm
  affine inside AdaIN1d, torch.round durations, a separate predictor style,
  a double-precision harmonic source, a canonical source STFT (exact zeros
  below the DFT rounding floor), cancellation hooks and stage outputs.
- generator_forward(..., GeneratorConfig, ...) replaces the literals; the
  old entry points keep Kokoro's defaults.
- KokoroLayerOptions (opt-in, scoped): per-tap SGEMM convolutions on
  Accelerate, register-tiled NEON Conv1d/ConvTranspose1d on the portable
  path, and a polynomial Snake. test-kokoro-layer-options checks them
  against the default kernels.
- The iSTFT evaluates its basis once instead of per sample (same values,
  same sums).

Kokoro-82M is unchanged bit for bit: kokoro-tts output for three sentences
at speed 1.0 and 1.3, with Accelerate and with KOKORO_FORCE_GGML, and the
kokoro-stage-dump outputs compare equal byte for byte before and after.

The predictor still reads its style at ref_s + 512 rather than ref_s + 128
(kokoro/model.py uses ref_s[:, 128:]). That is a separate fix with its own
parity run; it is marked in kokoro_predictor_forward and left as it was.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ty gate

paradee_lib runs Paradee-8M v1.0 on the generalised tools/kokoro layers:
ALBERT 6x256 -> duration encoder (style 32) -> integer durations ->
F0/N; TextEncoder -> asr_proj (192 -> 512 -> 512, exact GELU); AdaIN decoder
(256, style 16) -> iSTFTNet generator (128 -> 64 -> 32) with the
deterministic source; then the phase lock.

paradee-phase-lock.cpp ports training/scripts/phase_lock.py lock(): STFT
1024/256 with reflect padding, bins 2-8 kHz, voiced frames (F0 > 60 Hz),
33-frame Hann smoothing of S*conj(E)/|E|, phase = angle(E) + angle(smoothed),
magnitude kept, out = s + iSTFT(change). Radix-2 FFT in double; no ONNX.

API (include/paradee.h): paradee_load_model, paradee_sample_rate,
paradee_phonemes_to_ids (adds the pads, rejects >510 symbols and symbols
outside the vocabulary), paradee_phonemes_to_symbol_ids (no pads or limit,
for chunkers), paradee_synthesize_ids (cancel polled between stages and in
the generator and lock loops), paradee_synthesize (struct form), and the
staged/decode/lock entry points the parity gate uses. paradee-tts writes a
WAV from misaki phonemes; paradee-stage-dump writes every stage.

LLAMA_BUILD_PARADEE (default ON, needs LLAMA_BUILD_KOKORO) and the
LLAMA_BUILD_MISAKI_G2P hook are added to the root and tools CMake, both ahead
of tools/omnivoice so the fused library can fold them in.

Parity gate: tools/dump_paradee_reference.py runs the pinned PyTorch
Paradee with a deterministic source on the misaki 0.9.4 phonemes of the
model card's samples/sentences.txt (committed as
tests/fixtures/sentences.misaki.json) and dumps every stage. It also writes
the self-contained lock fixture, and reports the log-mel distance to the
published seeded samples and the whisper.cpp WER (report only).

Tests:
- test-paradee-phase-lock (always runs): the native lock is within 3e-8 of
  phase_lock.lock() in float64 (gate 1e-4).
- test-paradee-api (PARADEE_GGUF): ids, vocabulary and length errors, input
  validation, determinism, speed, cancellation.
- test-paradee-parity (PARADEE_GGUF + PARADEE_REF_DIR), all 5 sentences:
  - integer durations are identical;
  - bert/d/dur/F0/N/asr are within 7e-6 x RMS;
  - source and decoder output, each fed the reference's inputs, are within
    3e-5 x RMS (gate 1e-3);
  - the lock alone is within 4e-9 of float64 phase_lock (gate 1e-4);
  - end-to-end waveform SNR is 58-76 dB (gate 35 dB).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Every change on this branch already reached develop-pin (and so main) in a
newer form through #64: Paradee hardening, Kokoro stage cancel from #45.
Keep main's tree.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@lalalune
lalalune merged commit 10aca6e into main Oct 14, 2026
0 of 3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant