Model reference · open weights

plapre-nano

Audio syvai Text→speech 1 build Open weights 2k dl/mo

plapre-nano is an open-weight audio or speech model from syvai. plapre-nano (BF16) weighs 240 MB; the smallest configuration that runs it is RTX 3060 12 GB.

For self-hosting, compare this build's requirements below with the GPU you plan to rent.

  • plapre-nano is a 335M parameter text-to-speech model developed by syvai for generating Danish audio.
  • It uses an autoregressive architecture based on SmolLM2 to convert text into 24kHz sound and supports speaker conditioning and voice cloning.
  • The model is released under the cc-by-4.0 license.

Summary of the syvai/plapre-nano model card, 2026-10-01

What it is

Released bysyvai
Released2026-02-14
Parameters335M
VRAM240 MB for the weights

What it runs on

Memory and cards for plapre-nano (BF16)

240 MBweights, file size
1.6 GBruntime overhead
CardOne streamMemory
RTX 3060 12 GBfits11.6 GB
RTX 4060 Ti 16 GBfits15.4 GB
RTX 3090 24 GBfits23.4 GB
RTX 4090 24 GBfits23.4 GB
RTX 5090 32 GBfits31.0 GB
L40S 48 GBfits44.0 GB
A100 80 GBfits78.2 GB
H100 80 GBfits78.1 GB
RTX PRO 6000 Blackwell 96 GBfits93.8 GB
DGX Spark (GB10) 128 GB unifiedfits107 GB
H200 141 GBfits138 GB
B200 180 GBfits176 GB

From the model card

What syvai says about plapre-nano

Read the model card

Danish multi-task text-to-speech. A 335M LlamaForCausalLM that autoregressively predicts Kanade 25 Hz audio tokens from Danish BPE text and decodes them to 24 kHz speech. A 128-d speaker embedding — extracted from any reference clip with the Kanade encoder — is projected and prepended to the sequence, so every generation is voiced.

What it can do

Two tasks:

taskin → out
generatetext → speech in a chosen voice
editan existing recording + new text → the same recording with words substituted, inserted or deleted; only the masked span is regenerated, the surrounding audio is untouched

Four controls that stack onto generate:

controleffect
voice-reference (cloning)speak in the voice of a reference clip (audio + its transcript)
contextcondition on the previous utterance (text + audio) so tone, energy and tempo continue naturally across turns
paceper-word duration targets (40 ms frames) — set the speaking rate, or ramp it within a sentence
pronunciationup to 10 (word, reference-audio) pairs that pin how names, loanwords or acronyms are pronounced

Combining them

Controls are composable — any subset stacks in one prompt, in this block order:

[SPK]  [pronunciation]  [voice-reference]  [context]   BPE  [pace]   …
combinationwhat you get
clone + pacea cloned voice at a pace you set
clone + pronunciationa cloned voice that says a name correctly
clone + contexta cloned voice continuing a conversation
context + pacea conversational reply at a controlled tempo
clone + context + pace + pronunciationall four at once
edit + pronunciationregenerate a span so the corrected word is pronounced right

Voice-reference is the only control that swaps the speaker embedding (to the reference clip's); the others keep the target voice. Edit composes with pronunciation only. All combinations are trained, not emergent.

How to use it

The easiest path is the plapre library, which wraps every task and combination:

from plapre import Plapre

tts = Plapre("syvai/plapre-nano-v2")

# plain TTS
tts.speak("Hej, hvordan har du det?", output="out.wav", split_sentences=True)

# clone a voice from any clip
tts.clone("Denne sætning har stemmen aldrig sagt.", reference_wav="voice.wav")

# cloned voice + set pace + pinned pronunciation, in one call
tts.clone(
    "Mette Frederiksen mødte Volodymyr Zelenskyj i København.",
    reference_wav="voice.wav",
    durations=[14, 22, 12, 24, 4, 18],              # one frame count per word
    pronunciations=[("Zelenskyj", "zelenskyj_ref.wav")],
)

# continue a conversation with matching prosody
tts.continue_context("Og det er derfor, vi handler nu.",
                     prev_text="Situationen har ændret sig markant.",
                     prev_wav="previous_line.wav", speaker_wav="voice.wav")

# edit a recording: replace words in place
tts.edit("… ny formulering her …", mask_start=40, mask_end=55,
         original_wav="clip.wav")

Manual inference (transformers)

import numpy as np, torch
from transformers import AutoModelForCausalLM, AutoTokenizer
from huggingface_hub import hf_hub_download

CKPT = "syvai/plapre-nano-v2"
tok = AutoTokenizer.from_pretrained(CKPT)
m = AutoModelForCausalLM.from_pretrained(CKPT, torch_dtype=torch.float32).eval()
spj = torch.nn.Linear(128, m.config.hidden_size)
spj.load_state_dict(torch.load(hf_hub_download(CKPT, "speaker_proj.pt"), map_location="cpu"))
spj.eval()

g = tok.convert_tokens_to_ids
STOPS = [g(""), tok.eos_token_id]           # stop on BOTH terminators
pre = [g("")] + tok.encode(text, add_special_tokens=False) + [g("")]

pe = m.get_input_embeddings()(torch.tensor(pre))
spk = spj(torch.tensor(np.asarray(speaker_embedding), dtype=torch.float32)).unsqueeze(0)
inp = torch.cat([spk, pe], 0).unsqueeze(0)
out = m.generate(inputs_embeds=inp,
                 attention_mask=torch.ones(inp.shape[:2], dtype=torch.long),
                 max_new_tokens=500, do_sample=True, temperature=0.7,
                 top_p=0.95, top_k=50, eos_token_id=STOPS,
                 pad_token_id=tok.eos_token_id)[0].tolist()
audio_base = g("")
content = []
for t in out:
    if audio_base <= t < audio_base + 12800:
        content.append(t - audio_base)
    elif content:
        break
# decode `content` with kanade_tokenizer (frothywater/kanade-25hz-clean) -> 24 kHz wav

Control-block prompt formats (reference audio caps, `` ids, edit masking/splicing) are implemented in plapre/tasks.py — pure token-layout builders you can read or reuse directly.

Inference requirements

  • Stop on both terminators: generated audio ends then — pass both ids as stop tokens (the library does this for you).
  • Run in fp32 (the training precision). Lower precision measurably increases end-of-utterance artifacts.
  • Use this repo's tokenizer (vocab 21224).
  • End sentences with terminal punctuation — append a "." if your text ends on a comma or nothing; the stop signal is strongest on sentence-final text.
  • Split long text into sentences and generate them as a batch; join with ~250 ms of silence. Speaking pace follows the voice: reference clips from calm speakers yield calm narration.
  • If serving with vLLM, use vllm>=0.15,<0.16 with enable_prompt_embeds=True — newer stacks measurably degrade generation quality on identical weights.
  • Text normalization: collapse whitespace and convert digits to Danish words (num2words, lang="da") before encoding.

Model details

Architecture335M LlamaForCausalLM (SmolLM2 layout, hidden 960, 32 layers) + 128→960 speaker projection (speaker_proj.pt)
Audio codecfrothywater/kanade-25hz-clean — 25 Hz content code

Quoted from the model card on Hugging Face. The full card is behind the Hugging Face link above.

© 2026 AxForge · EU-hosted AI infrastructure Pricing Docs Trust Privacy Terms