alt.freeweights.speech / moss-va-sft3-burst-stop-dpo-lora
From: laion <huggingface.co/laion>Newsgroups: alt.freeweights.speechSubject:

moss-va-sft3-burst-stop-dpo-lora

Date: 2026-11-15Commit: ac6dccdSigned: 2DC28CC7B26A283B ✓

Text to speech model. Safetensors weights, 688 MB in all. Published by laion under Apache-2.0.

speech688MBmoss-va-sft3-burst-stop-dpo-lorasafetensorspermissive
FactsParamsnot statedSize688 MBFormatssafetensorsTasktext to speechLicenseApache-2.0From sourcepermissive
$ fw get laion/moss-va-sft3-burst-stop-dpo-lora
# manifest sha256 462a01e20c3a… · 688 MB · 12 files
$ fw verify ./moss-va-sft3-burst-stop-dpo-lora laion/moss-va-sft3-burst-stop-dpo-lora
From sourceHosted (signed)laion/moss-va-sft3-burst-stop-dpo-loraLast check: 2026-11-15 05:30 UTC

Get help: custom fine-tune or private deploy. We review your setup before we quote.

Adapter of moss-tts-local-transformer-4.55b-voice-acting-v2-sft3.

Works with

Overview

Size
688 MB
Weights
688 MB (safetensors)
Parameters
not stated
Formats
safetensors
Task
text to speech
License
Apache-2.0 (permissive)
Files
12, each with a sha256
Publisher
laion
Added
2026-11-15
Section
alt.freeweights.speech
Lineage

Original release from the publisher.

Base model: laion/moss-tts-local-transformer-4.55b-voice-acting-v2-sft3

Where these bytes come from
Publisher at the pinned commit→You

Sources are tried in order. A file counts only when its size and sha256 match the manifest. Sources are checked when you ask for them, not on a timer.

Sources
BadgeHostLast checkResult
From sourcehuggingface.co2026-11-15 05:30 UTCpassed

Model card

From the publisher at commit ac6dccd. Shown as plain text with links; images open at the publisher.

MOSS VA SFT3 — vocal-burst realisation + stop/no-improvisation DPO LoRA (rank 16)#

Teaches two things the model gets wrong: realising the vocal burst that was actually asked for (a scream where a scream was written, not a laugh and not silence), and stopping when the line is finished instead of mumbling on past it.

Unlike the earlier quality adapters in this line, this one is not a null result. On 317 held-out preference pairs, pooled accuracy goes 0.707 → 0.943, and every one of the eight task families improves.

⚠️ Do not merge this adapter into the base weights#

merge_and_unload(), merge_adapter(), or any offline "bake the LoRA into the checkpoint" script will destroy the model irrecoverably.

This adapter targets audio_lm_heads.0 … audio_lm_heads.11 and text_lm_head — 12 of its 23 target modules. Those output heads are weight-tied to the input embeddings: tie_weights() makes audio_lm_heads[i].weight and audio_embeddings[i].weight the same tensor, one allocation with two names. A merge adds B @ A · (α/r) into the head and therefore writes the same delta into the embedding table. The model then reads its own inputs through a matrix shifted by an output-side correction. It does not fail loudly — it degrades into noise, inside the checkpoint you just saved, with the original values gone.

Verify it yourself:

m = base.model if hasattr(base, "model") else base
print(m.audio_lm_heads[0].weight.data_ptr() == m.audio_embeddings[0].weight.data_ptr())
# True -> same storage

Load with PEFT and leave it unmerged. This is acoustically identical to a merge: an unmerged LoRA computes Wx + (B @ A)x · (α/r), a merged one (W + B @ A · (α/r))x — the same arithmetic in a different order. You give up a little inference speed and keep adjustable strength, stackability and the ability to switch it off.

What it was trained on, in plain language#

14,932 preference pairs. Each pair is the same recording twice — one version the model should prefer, one it should not — so it cannot learn "prefer a different voice" or "prefer a calmer delivery". Four arms:

Vocal bursts (30 %). Chosen = the original clip with its burst intact. Rejected, in three kinds:

kindshare of the burst armwhat the negative is
swap39.5 %a different burst class from the same speaker, similar length — a laugh where a scream belongs
silence35.1 %the burst replaced by silence, faded in and out so total duration is unchanged
excise25.4 %the burst cut out entirely (duration shortens)

The swap kind is the point. With silence-only negatives the model can cheat: it only has to detect whether a burst is present, never which one. Making swap the largest kind forces it to identify the class.

Stopping (25 %). Three ways of teaching the model to fall silent:

  • truncated prompt — the script is cut a word or two early and the audio is cut and faded at the same point; rejected is the original, which keeps talking past the prompt.
  • two-sentence fade — only the first sentence is in the prompt and the second is faded to silence in the chosen audio. The stated duration is the FULL original length, so the model learns to say the first sentence at its natural pace and then produce silence — not to stretch it across the whole budget. Verified: 410/410 renders have exactly one speech segment whose sum equals the full original duration.
  • appended noise — chosen is the clean original; rejected has a random fragment from another take by the same speaker appended, so the negative is "kept going" rather than "was cut".

Quality (25 %) and speed (20 %) are carried over from the earlier corpora as controls, so the run can show it is not damaging what already worked.

Results#

Scored forward-only through every kept checkpoint on the same 317 held-out pairs — one record per pair per checkpoint, 5,706 records. That makes every comparison paired, with each pair its own control, rather than a marginal accuracy on a few dozen pairs.

task familyninitstep112step336step616step896
stop: two sentences310.2580.8710.9680.9681.000
stop: truncated310.6130.9351.0001.0001.000
stop: appended noise220.6360.9551.0001.0001.000
burst: wrong class (swap)320.6250.6880.7190.7810.844
burst: replaced by silence270.4070.4810.6670.8150.815
burst: excised240.4580.5830.6250.5420.667
quality (control)950.9790.9791.0000.9791.000
speed (control)550.8730.9450.9641.0001.000
pooled3170.7070.8550.9050.9180.943
The single most important finding#

Improvising past the end of a line was not merely unlearned — it was learned backwards. The starting adapter scores 0.258 on the two-sentence stop task: 8 right, 23 wrong. It actively prefers the take that keeps talking. After 112 steps it is at 0.871, and 1.000 by the end.

This would have been invisible in the pooled number: 31 pairs out of 317 moving from 0.258 to 1.000 shifts the pooled accuracy by 0.08, inside its own noise. Only the per-family paired scoring found it.

The two arms learn on completely different schedules#

All three stop families are finished by step 280. burst_silence is still below its starting value at step 224 (0.481 vs 0.407), first becomes significant at step 336, and peaks at step 784. A checkpoint chosen on the stop arm alone would be chosen roughly 500 steps too early.

burst_excise is the family this corpus did not solve (0.458 → 0.667). By construction: it is the only burst kind whose two sides differ in length, so it overlaps the speed-stretch task and the model can decide it on duration instead of on the burst.

Which checkpoint to use#

A range, not a single point: step336 … step896.

  • step336 — the first checkpoint where all eight families are at or above the starting adapter on the paired logit and the burst arm has begun to move.
  • step896 — the largest paired gains in the ladder and the best pooled accuracy (0.9432).

Deliberately not best-by-val_loss (step 840) and not best-by-pooled-accuracy (step 616). step902 is a 6-step tail and the only late reversal in the run — use 896, not final.

Nobody has listened to any of these yet. Every number above is preference accuracy on held-out pairs. A listening test should compare four conditions — the starting adapter (ratelora_dpo_mix_r16/step245) plus step336, step616 and step896 — with two separate judgements per clip, "is this the burst that was asked for" and "does it stop", kept apart from any audio-quality rating.

A caveat about rew_chosen#

In LoRA mode the trainer's reference policy is peft.disable_adapter(), which disables all adapters — so rew_chosen is measured against bare SFT3, not against this run's starting point. It was flat (3.29–3.49) across all 902 steps while rew_rejected fell from +0.295 to −3.87, so all margin came from pushing the rejected side down. Read rew_chosen > 0 as "better than bare SFT3", which is a weak guardrail, not a strong one.

How it was trained#

baselaion/moss-tts-local-transformer-4.55b-voice-acting-v2-sft3
initialised fromlaion/moss-va-sft3-quality-speed-dpo-lora @ step245
datads_mix_dpo_bs, 14,932 pairs — bursts 25.0 % / stop 25.0 % / quality 30.0 % / speed 20.0 %
objectiveDPO, β 30, length-normalised, NLL anchor 0.013
schedule902 updates, lr 1e-6, 10 % warmup, 4 pairs per device × 4 GPUs
hardware4 GPUs, ~40 min
adapterLoRA rank 16, α 32 — so the scaling w below multiplies α/r = 2.0

Inference#

import torch
from transformers import AutoConfig, AutoModel, AutoProcessor
from peft import PeftModel

BASE = "laion/moss-tts-local-transformer-4.55b-voice-acting-v2-sft3"
dev = "cuda:0"

proc = AutoProcessor.from_pretrained(BASE, trust_remote_code=True)
proc.audio_tokenizer = proc.audio_tokenizer.to(dev).eval()
cfg  = AutoConfig.from_pretrained(BASE, trust_remote_code=True)
base = AutoModel.from_pretrained(BASE, trust_remote_code=True,
                                 dtype=torch.bfloat16,
                                 attn_implementation="sdpa").to(dev).eval()

model = PeftModel.from_pretrained(base, "laion/moss-va-sft3-burst-stop-dpo-lora",
                                  adapter_name="bs").to(dev).eval()
# do NOT call model.merge_and_unload()

batch = proc([[{"role": "user", "content": prompt, "audio_codes_list": []}]],
             mode="generation")
out = model.generate(input_ids=batch["input_ids"].to(dev),
                     attention_mask=batch["attention_mask"].to(dev).to(torch.bool),
                     max_new_tokens=340, do_sample=True,
                     temperature=1.0, top_p=0.95, top_k=25)

A different checkpoint:

model = PeftModel.from_pretrained(base, "laion/moss-va-sft3-burst-stop-dpo-lora",
                                  subfolder="checkpoints/step336", adapter_name="bs")

Adapter strength (base scaling is α/r = 2.0; all measurements used w = 1.0):

def set_weight(model, name, w):
    for module in model.modules():
        sc = getattr(module, "scaling", None)
        if isinstance(sc, dict) and name in sc:
            if not hasattr(module, "_base_scaling"):
                module._base_scaling = {}
            module._base_scaling.setdefault(name, sc[name])
            sc[name] = module._base_scaling[name] * float(w)

set_weight(model, "bs", 1.0)

Prompt format#

Trained under prompt format hash 090c4ca315519a57 (inherited through the adapter chain). A duration-only script is byte-identical to the project's standard 073aeb09dc923376, so ordinary prompts work unchanged.

Checkpoints#

checkpoints/step{112,336,616,896} — the four reported above. The root copy is step896. All 18 checkpoints exist internally; these are the ones with published numbers.

Files

12 files · 688 MBWeights 688 MB (safetensors). Sizes and sha256 from the signed manifest.
Hide all 12 files with their sha256
FileSizesha256
.gitattributes1.52 KB11ad7efa24975ee4b0c3c3a38ed18737f0658a5f75a0a96787b576a78a023361
README.md11.3 KB0e8b304c07a07a28bbed818b7aa1a44d44db65822db2e43860cee2b7c3a45158
adapter_config.json1.66 KBacb4f5f5b40ab798fa679bd2835353a398b5f8ade408325ebd9a113745643abb
adapter_model.safetensors138 MBf03bf9d652575da9a38470485fb15469a2b21a85e5dc70bda7ac20b90f192c05
checkpoints/step112/adapter_config.json1.66 KBacb4f5f5b40ab798fa679bd2835353a398b5f8ade408325ebd9a113745643abb
checkpoints/step112/adapter_model.safetensors138 MB54028800e47162669569d8324e6159cac98e24364fd9b48d63a32047ec8a3d51
checkpoints/step336/adapter_config.json1.66 KBacb4f5f5b40ab798fa679bd2835353a398b5f8ade408325ebd9a113745643abb
checkpoints/step336/adapter_model.safetensors138 MB92e1db512b0ed2d8e9c39c7d80249d4a82b2a8d020ec5325082d7cafd9aa6445
checkpoints/step616/adapter_config.json1.66 KBacb4f5f5b40ab798fa679bd2835353a398b5f8ade408325ebd9a113745643abb
checkpoints/step616/adapter_model.safetensors138 MB593e24fe5cdab61ca296915774702566451fe8d9f49ce15604abe469a7b15678
checkpoints/step896/adapter_config.json1.66 KBacb4f5f5b40ab798fa679bd2835353a398b5f8ade408325ebd9a113745643abb
checkpoints/step896/adapter_model.safetensors138 MBf03bf9d652575da9a38470485fb15469a2b21a85e5dc70bda7ac20b90f192c05
VersionsEach time the pinned upstream commit or file list changed in this repo. Newest first.
Upstream commitDateContents
ac6dccd183 pinned now2026-11-15 05:30 UTC12 files · 688 MB

Use it

$ fw get laion/moss-va-sft3-burst-stop-dpo-lora
# manifest sha256 462a01e20c3a… · 688 MB · 12 files
$ fw verify ./moss-va-sft3-burst-stop-dpo-lora laion/moss-va-sft3-burst-stop-dpo-lora
fw.pyChecks the signature and every sha256, tries each source in order, resumes.
$ python3 fw.py get https://freeweights.allternit.com/manifests/laion/moss-va-sft3-burst-stop-dpo-lora.json --dir ./moss-va-sft3-burst-stop-dpo-lora $ python3 fw.py verify ./moss-va-sft3-burst-stop-dpo-lora ./laion__moss-va-sft3-burst-stop-dpo-lora.json
hfThe Hugging Face CLI with one setting. Same repo id.
$ HF_ENDPOINT=https://freeweights.allternit.com hf download laion/moss-va-sft3-burst-stop-dpo-lora --revision ac6dccd183f81012c3aaf8ec22a22601e49c3863 --local-dir ./moss-va-sft3-burst-stop-dpo-lora

License

Name
Apache License 2.0
Id
Apache-2.0
Class
Permissive
Redistribution
yes
Listing
Hosted (signed)
Decided
License as declared by the publisher. No person read it. 2026-11-15
Text in
README.md
Text sha256
0e8b304c07a07a28bbed818b7aa1a44d44db65822db2e43860cee2b7c3a45158
Terms gate
No extra terms beyond the license.

Read the license text

Licenses are checked against the license table. A custom license passes only after a person reads it.

Provenance

From: laion <huggingface.co/laion>Newsgroups: alt.freeweights.speechSubject: moss-va-sft3-burst-stop-dpo-loraDate: 2026-11-15Commit: ac6dccdSigned: 2DC28CC7B26A283B ✓
Upstream
laion/moss-va-sft3-burst-stop-dpo-lora
Pinned commit
ac6dccd183f81012c3aaf8ec22a22601e49c3863
Manifest
moss-va-sft3-burst-stop-dpo-lora.json · .minisig
Manifest sha256
462a01e20c3af48a9af52958dd3e535a6874004c34b4c62b82ff95c63ce07c89
Signature
minisign, Ed25519, key 2DC28CC7B26A283B
Created
2026-11-15 05:30 UTC
Generator
freeweights-manifest/0.1.0
Takedowns
None.

How to verify

$ curl -O https://freeweights.allternit.com/manifests/laion/moss-va-sft3-burst-stop-dpo-lora.json $ curl -O https://freeweights.allternit.com/manifests/laion/moss-va-sft3-burst-stop-dpo-lora.json.minisig $ minisign -Vm moss-va-sft3-burst-stop-dpo-lora.json -P RWQ7KGqyx4zCLXtUFOqvfv8L3g+8fpKJ1FsuxPyOYMF+4KufbUxKq1Oq $ shasum -a 256 <file> # compare with the Files tab

A manifest whose signature fails must be rejected. A file whose size or sha256 does not match must be discarded. Verify a download

Model tree

No model in the catalog names this one as its parent.

Get it
Download
$ HF_ENDPOINT=https://freeweights.allternit.com hf download laion/moss-va-sft3-burst-stop-dpo-lora
Open in Freeweights Studio

Pull, verify and run it in the Allternit app on Desktop, web or phone.

Signed manifest
minisign, key 2DC28CC7B26A283B. moss-va-sft3-burst-stop-dpo-lora.json. Provenance. Takedown history: none.
From: MIT <huggingface.co/MIT>Subject: ast-finetuned-audioset-10-10-0.4593
From: onnx-community <huggingface.co/onnx-community>Subject: ast-finetuned-audioset-10-10-0.4593-ONNX
From: Edge0 <huggingface.co/Edge0>Subject: Audio8-TTS-Preview-0.6b
From: Edge0 <huggingface.co/Edge0>Subject: Audio8-TTS-Realistic-Air
From: facebook <huggingface.co/facebook>Subject: audiobox-aesthetics
From: mlx-community <huggingface.co/mlx-community>Subject: chatterbox-4bit