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

moss-va-sft3-dpo-lora-p2

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

Text to speech model. Safetensors weights, 550 MB in all. Published by laion under CC-BY-4.0.

speech550MBmoss-va-sft3-dpo-lora-p2safetensorspermissive
FactsParamsnot statedSize550 MBFormatssafetensorsTasktext to speechLicenseCC-BY-4.0From sourcepermissive
$ fw get laion/moss-va-sft3-dpo-lora-p2
# manifest sha256 6846edd27391… · 550 MB · 4 files
$ fw verify ./moss-va-sft3-dpo-lora-p2 laion/moss-va-sft3-dpo-lora-p2
From sourceHosted (signed)laion/moss-va-sft3-dpo-lora-p2Last check: 2026-11-15 05:29 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
550 MB
Weights
550 MB (safetensors)
Parameters
not stated
Formats
safetensors
Task
text to speech
License
CC-BY-4.0 (permissive)
Files
4, 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:29 UTCpassed

Model card

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

Preference-tuning adapter for MOSS voice-acting v2 SFT-3 — contrastive pair families#

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

merge_and_unload(), merge_adapter(), and any offline "bake the LoRA into the checkpoint" script will destroy the model irrecoverably. This is not a performance caveat. Read this before you write a deployment script.

Why#

This adapter targets audio_lm_heads.0 … audio_lm_heads.11 and text_lm_head — 12 of its 23 target modules. In this architecture those output heads are weight-tied to the input embeddings: tie_weights() sets

audio_lm_heads[i].weight  IS  audio_embeddings[i].weight     # the same tensor, not a copy
text_lm_head.weight       IS  transformer.embed_tokens.weight

They are one allocation with two names. So when a merge adds B @ A * (alpha/r) into the head weight, it writes that delta straight into the embedding table at the same time. The model then reads its own inputs through a matrix that has been shifted by an output-side correction. Generation does not fail loudly — it degrades into noise or into a fixed babble, and the damage is inside the checkpoint you just saved. There is nothing to unmerge afterwards, because the original values are gone.

Verify it yourself in three lines#

Do not take our word for it:

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, merging corrupts the embeddings
What to do instead#

Load with PEFT and leave the adapter unmerged. Set its strength through the scaling factor:

from peft import PeftModel

model = PeftModel.from_pretrained(base, "<this repo>", adapter_name="a").to(dev).eval()
# do NOT call model.merge_and_unload()

def set_weight(model, name, w):
    """Scale one named adapter's contribution.  alpha/r is its own base scaling."""
    for module in model.modules():
        scaling = getattr(module, "scaling", None)
        if isinstance(scaling, dict) and name in scaling:
            if not hasattr(module, "_base_scaling"):
                module._base_scaling = {}
            module._base_scaling.setdefault(name, scaling[name])
            scaling[name] = module._base_scaling[name] * float(w)

set_weight(model, "a", 1.0)
model.base_model.set_adapter(["a"])      # several adapters can be active at once

This sounds identical to a merge. An unmerged LoRA computes Wx + (B @ A)x * (alpha/r), which is exactly what the merged weight W + B @ A * (alpha/r) would compute — the same arithmetic, in a different order. You give up a small amount of inference speed and you keep the ability to change the weight, stack several adapters, or turn one off. Nothing about the sound changes.

If you are stacking adapters#

Set each one's scaling separately and activate them together with model.base_model.set_adapter([...]). Note that stacking is not free: in our own measurements a deep stack held audio quality but destroyed intelligibility (word error 0.063 → 0.554). Add adapters deliberately and measure.

If you maintain code that merges#

A regex over module names is not enough — the reliable test is identity of storage. Group the modules by weight.data_ptr() and refuse to merge into any group with more than one member. lora_bank.py in LAION-AI/Humaneness-Voice-Demo-Server does this and asserts on the merge path.


A rank-64 LoRA (alpha 128) trained with DPO on top of laion/moss-tts-local-transformer-4.55b-voice-acting-v2-sft3, which is itself a supervised fine-tune of laion/moss-tts-local-transformer-4.55b-voice-acting-v2.

This is the best checkpoint this project has measured. It supersedes laion/moss-va-sft3-dpo-lora, which holds the previous best (the CFG-only corpus). All rows below come from the same 80-prompt, generation-based evaluation, on identical prompts and the same corrected percentile scale.

modelrewardWERemotion pctqualityburstburst hit rate
SFT-3, no adapter0.45840.09870.34940.91270.35640.666
+ DPO, corpus v10.46680.11170.35180.91080.39730.694
+ DPO, corpus v2 (step 3216)0.46870.10940.34010.92110.39290.709
+ DPO, CFG corpus (step 4912)0.47080.09500.33730.92350.42710.772
this adapter (step 5022)0.47570.09770.35410.92080.41800.762
this adapter, step 39060.47440.09160.34780.92310.41060.762

Two things are worth noting. Its word error rate is better than the supervised baseline's (0.0977 against 0.0987), which no preference-tuned model in this line managed before the CFG corpus — earlier DPO runs always paid for their gains in intelligibility. And its emotion percentile is the highest of any preference-tuned model here (0.3541), which is what the two new pair families were built to achieve.

What it was trained on#

2,696,421 preference pairs. 86.3 % is the CFG corpus that produced the previous best; 13.7 % is new, in two families:

familyrowswhat varies between chosen and rejected
p2_emox309,128the emotion only. Same speaker, durations within 10 %, and both clips are intense — one on the emotion the instruction names, one on a different one. Turning intensity up is worth nothing; only conditioning on the instruction is. Each pair is emitted twice with the roles flipped.
p2_len (cut)29,564the duration only. Same speaker, same text, same emotion; the rejected side is the same clip truncated to 50–75 % of its frames.
p2_len (ext)29,825as above, but the rejected side runs 125–150 % long.

The emotion of a clip is always taken from its measured value (a 40-head emotion model scored on that exact waveform), never from the prompt that generated it.

The text field differs between the families by design. p2_emox pairs two different recordings under one prompt, so the words are replaced by ... — otherwise the preference would be decidable from the text alone. p2_len pairs one recording against itself at two lengths, so the words are shared and the full timed script stays in the prompt: the timing tags are exactly what the rejected side violates.

How to use it#

from transformers import AutoProcessor, AutoModel
from peft import PeftModel

BASE = "laion/moss-tts-local-transformer-4.55b-voice-acting-v2-sft3"
proc  = AutoProcessor.from_pretrained(BASE, trust_remote_code=True)
model = AutoModel.from_pretrained(BASE, trust_remote_code=True,
                                  dtype="bfloat16", attn_implementation="sdpa")
model = PeftModel.from_pretrained(model, "laion/moss-va-sft3-dpo-lora-p2").eval().cuda()

prompt = """<user_inst>
- Reference(s):
None
- Instruction:
GENERAL: A young adult feminine voice, warm and conversational; reads as amusement; 6.0s, EN.
SCRIPT:
[0.4 seconds pause] (intensely amused: letting it out / not hiding it, warm and open,
unguarded; bright, relaxed) [2.4 seconds duration] You are not going to believe this.
[0.3 seconds pause] (breathy giggle, 0.4 seconds) [0.2 seconds pause] (still intensely amused)
[2.3 seconds duration] He actually wore it to the wedding.
- Tokens:
75
- Quality:
None
- Sound Event:
None
- Ambient Sound:
None
- Language:
English
- Text:
[0.4 seconds pause] (intensely amused: letting it out / not hiding it, warm and open,
unguarded; bright, relaxed) [2.4 seconds duration] You are not going to believe this.
[0.3 seconds pause] (breathy giggle, 0.4 seconds) [0.2 seconds pause] (still intensely amused)
[2.3 seconds duration] He actually wore it to the wedding.
</user_inst>"""

b = proc([[{"role": "user", "content": prompt, "audio_codes_list": []}]], mode="generation")
out = model.generate(input_ids=b["input_ids"].cuda(), attention_mask=b["attention_mask"].cuda(),
                     max_new_frames=340, do_sample=True, audio_temperature=1.0,
                     audio_top_p=0.95, audio_top_k=50)
The prompt format#

The audio tokenizer runs at 12.5 frames per second, so Tokens: is seconds × 12.5 — 6.0 s is 75. Four kinds of tag appear in the script, told apart by their brackets:

tagmeaning
[3.9 seconds duration]the next sentence must take this long; stands before it, one per segment
[0.8 seconds pause]silence, for every gap of 0.2 s or more, including before the first word and after the last
(contented sigh, 0.2 seconds)a vocal burst: round brackets with a duration
(clearly amused, warm and open)a delivery direction: round brackets without a duration

The numbers should add up to the token budget. Realistic burst lengths are short — median 0.28 s in the training data, 90th percentile 0.48 s.

Limitations#

  • Emotional intensity is still far below what the prompt asks for. Asked for percentile 0.90–0.98 of a named emotion, this model reaches 0.354 on the corrected scale. Every objective tried against this — GRPO, plain DPO, CFG-DPO, and these contrastive families — has moved it only slightly. The one approach that has moved it more is training on more extreme data; see the per-emotion adapters at laion/moss-va-sft3-emotion-loras.
  • Timing is the solved part: median duration error 0.08 s, essentially every clip within 0.5 s of the length its own script adds up to.
  • The adapter ships unmerged and should stay that way. audio_lm_heads.N.weight and audio_embeddings.N.weight are the same tensor (tie_weights()), so merging the head delta also rewrites the embedding and corrupts the model — measured, both tensors changing by exactly 6.103515625e-05 while the text embedding did not change at all.

Evaluation#

Listening pages, all on identical prompts:

Files

4 files · 550 MBWeights 550 MB (safetensors). Sizes and sha256 from the signed manifest.
Hide all 4 files with their sha256
FileSizesha256
.gitattributes1.52 KB11ad7efa24975ee4b0c3c3a38ed18737f0658a5f75a0a96787b576a78a023361
README.md11.1 KBa4767e82cf91aa1f82cfe66a0b1c514caaf56da74463390cec55cdfb2ec010dc
adapter_config.json1.57 KB96ab46b8dade34c109bf8d39d25cbc6208f495cf6a815c328c7bc1578934571b
adapter_model.safetensors550 MBeae5ee0e1f851561c16ac035fc992f8378f77f6234f698de99ed4aeb0f2e23ee
VersionsEach time the pinned upstream commit or file list changed in this repo. Newest first.
Upstream commitDateContents
cb209828dd pinned now2026-11-15 05:29 UTC4 files · 550 MB

Use it

$ fw get laion/moss-va-sft3-dpo-lora-p2
# manifest sha256 6846edd27391… · 550 MB · 4 files
$ fw verify ./moss-va-sft3-dpo-lora-p2 laion/moss-va-sft3-dpo-lora-p2
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-dpo-lora-p2.json --dir ./moss-va-sft3-dpo-lora-p2 $ python3 fw.py verify ./moss-va-sft3-dpo-lora-p2 ./laion__moss-va-sft3-dpo-lora-p2.json
hfThe Hugging Face CLI with one setting. Same repo id.
$ HF_ENDPOINT=https://freeweights.allternit.com hf download laion/moss-va-sft3-dpo-lora-p2 --revision cb209828dd227ad37e2d68855a1c553f35decea8 --local-dir ./moss-va-sft3-dpo-lora-p2

License

Name
Creative Commons Attribution 4.0
Id
CC-BY-4.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
a4767e82cf91aa1f82cfe66a0b1c514caaf56da74463390cec55cdfb2ec010dc
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-dpo-lora-p2Date: 2026-11-15Commit: cb20982Signed: 2DC28CC7B26A283B ✓
Upstream
laion/moss-va-sft3-dpo-lora-p2
Pinned commit
cb209828dd227ad37e2d68855a1c553f35decea8
Manifest
moss-va-sft3-dpo-lora-p2.json · .minisig
Manifest sha256
6846edd2739104f51b3e68618346c605ce7d8c504c3a8ac659ff6b27ae6e2cf8
Signature
minisign, Ed25519, key 2DC28CC7B26A283B
Created
2026-11-15 05:29 UTC
Generator
freeweights-manifest/0.1.0
Takedowns
None.

How to verify

$ curl -O https://freeweights.allternit.com/manifests/laion/moss-va-sft3-dpo-lora-p2.json $ curl -O https://freeweights.allternit.com/manifests/laion/moss-va-sft3-dpo-lora-p2.json.minisig $ minisign -Vm moss-va-sft3-dpo-lora-p2.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-dpo-lora-p2
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-dpo-lora-p2.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