Spaces:
Configuration error
Configuration error
| <html lang="en"> | |
| <head> | |
| <meta charset="utf-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1"> | |
| <title>VoiceEraser β Audio Demo</title> | |
| <style> | |
| :root { --ink:#1f2430; --mut:#6b7280; --line:#e5e7eb; --acc:#c0532b; --bg:#fafafa; --card:#fff; } | |
| * { box-sizing:border-box; } | |
| body { margin:0; font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif; | |
| color:var(--ink); background:var(--bg); line-height:1.5; } | |
| .wrap { max-width:1000px; margin:0 auto; padding:2.2rem 1.1rem 4rem; } | |
| h1 { font-size:1.9rem; margin:.2rem 0 .3rem; letter-spacing:-.01em; } | |
| h2 { font-size:1.15rem; margin:2.4rem 0 .5rem; } | |
| .sub { color:var(--mut); font-size:1.02rem; max-width:70ch; } | |
| .links { margin:1rem 0 .3rem; display:flex; flex-wrap:wrap; gap:.5rem; } | |
| .links a { text-decoration:none; border:1px solid var(--line); background:var(--card); | |
| padding:.34rem .7rem; border-radius:999px; font-size:.86rem; color:var(--ink); } | |
| .links a:hover { border-color:var(--acc); color:var(--acc); } | |
| .legend { background:var(--card); border:1px solid var(--line); border-radius:12px; padding:.9rem 1.1rem; | |
| margin:1.3rem 0; font-size:.95rem; } | |
| .legend b { color:var(--acc); } | |
| table { width:100%; border-collapse:collapse; background:var(--card); border:1px solid var(--line); | |
| border-radius:12px; overflow:hidden; margin:.6rem 0 1.2rem; } | |
| th, td { padding:.55rem .6rem; border-bottom:1px solid var(--line); text-align:left; vertical-align:middle; } | |
| th { font-size:.8rem; text-transform:uppercase; letter-spacing:.03em; color:var(--mut); background:#f8f8f9; } | |
| td.spk { font-weight:600; white-space:nowrap; } | |
| audio { width:190px; height:34px; } | |
| .pair { display:flex; gap:.5rem; align-items:center; flex-wrap:wrap; } | |
| .tag { font-size:.72rem; color:var(--mut); } | |
| .note { color:var(--mut); font-size:.86rem; margin-top:.3rem; } | |
| footer { margin-top:3rem; padding-top:1.2rem; border-top:1px solid var(--line); color:var(--mut); font-size:.85rem; } | |
| code { background:#f1f1f2; padding:.05rem .35rem; border-radius:5px; font-size:.86em; } | |
| </style> | |
| </head> | |
| <body> | |
| <div class="wrap"> | |
| <h1>VoiceEraser π β audio demo</h1> | |
| <p class="sub">Speaker unlearning for zero-shot TTS. One host-independent edit (<i>cond-DIM</i>) makes a | |
| released model stop cloning a chosen voice, while everyone else is untouched. Listen below.</p> | |
| <div class="links"> | |
| <a href="https://github.com/pujariaditya/voiceeraser" target="_blank">π» Code (GitHub)</a> | |
| <a href="https://huggingface.co/datasets/RootAccess4Life/voiceeraser-samples" target="_blank">π§ Full sample set (dataset)</a> | |
| <a href="https://huggingface.co/RootAccess4Life/voiceeraser-xtts-v2" target="_blank">π¦ XTTS-v2 mirror</a> | |
| <a href="https://huggingface.co/RootAccess4Life/voiceeraser-indextts-1.5" target="_blank">π¦ IndexTTS-1.5 mirror</a> | |
| </div> | |
| <div class="legend"> | |
| What you are hearing, for each <b>forget</b> speaker (the voice being opted out): | |
| <ul style="margin:.5rem 0 0; padding-left:1.2rem;"> | |
| <li><b>Baseline clone</b> (<code>cB</code>) β the released model cloning the target voice. It sounds like them.</li> | |
| <li><b>After unlearning</b> (<code>cE</code>) β after the cond-DIM edit: the identity is redirected away, so a | |
| verifier no longer accepts it, yet the speech stays intelligible.</li> | |
| <li><b>After relearn attack</b> (<code>cRL</code>) β a white-box adversary re-finetunes the released weights to | |
| bring the voice back (only partially successful; XTTS-v2).</li> | |
| </ul> | |
| </div> | |
| <h2>1 Β· Erasure across three backbones</h2> | |
| <p class="note">Same forget speakers, each cloned then unlearned on three architecturally different autoregressive | |
| backbones. Left = baseline clone, right = after unlearning.</p> | |
| <table id="erasure"><thead><tr> | |
| <th>Forget speaker</th><th>XTTS-v2</th><th>Tortoise-TTS</th><th>IndexTTS-1.5</th> | |
| </tr></thead><tbody></tbody></table> | |
| <h2>2 Β· Relearn stress-test (XTTS-v2)</h2> | |
| <p class="note">An adversary who downloads the edited open weights and re-finetunes them to recover the voice. | |
| Recovery is only partial β the whole point of the paper's honest robustness result.</p> | |
| <table id="relearn"><thead><tr> | |
| <th>Forget speaker</th><th>Baseline clone</th><th>After unlearning</th><th>After relearn attack</th> | |
| </tr></thead><tbody></tbody></table> | |
| <footer> | |
| Audio is synthesized from the consent-based <b>VCTK</b> and <b>LibriTTS</b> research corpora and is provided for | |
| research/demonstration only. Method: <i>cond-DIM</i> (conditioning-path Dispersed Identity Misdirection), | |
| reference code for an ICASSP 2026 submission. Β· | |
| <a href="https://huggingface.co/datasets/RootAccess4Life/voiceeraser-samples" target="_blank">browse all samples β</a> | |
| </footer> | |
| </div> | |
| <script> | |
| const BASE = "https://huggingface.co/datasets/RootAccess4Life/voiceeraser-samples/resolve/main/"; | |
| const FORGET = ["103", "118", "125", "150"]; | |
| const SENT = "0"; // sentence index | |
| function aud(dir, prefix, spk) { | |
| const src = `${BASE}${dir}/${prefix}_${spk}_${SENT}.wav`; | |
| return `<audio controls preload="none" src="${src}"></audio>`; | |
| } | |
| function pair(dir, spk) { | |
| return `<div class="pair"> | |
| <span><span class="tag">clone</span><br>${aud(dir, "cB", spk)}</span> | |
| <span><span class="tag">unlearned</span><br>${aud(dir, "cE", spk)}</span> | |
| </div>`; | |
| } | |
| const eb = document.querySelector("#erasure tbody"); | |
| FORGET.forEach(spk => { | |
| eb.insertAdjacentHTML("beforeend", | |
| `<tr><td class="spk">${spk}</td> | |
| <td>${pair("xtts_clones", spk)}</td> | |
| <td>${pair("tortoise_clones", spk)}</td> | |
| <td>${pair("indextts_clones", spk)}</td></tr>`); | |
| }); | |
| const RELEARN = ["p243", "p252", "p260", "p261"]; | |
| const A = s => `<audio controls preload="none" src="${BASE}xtts_relearn_clones/${s}"></audio>`; | |
| const rb = document.querySelector("#relearn tbody"); | |
| RELEARN.forEach(spk => { | |
| rb.insertAdjacentHTML("beforeend", | |
| `<tr><td class="spk">${spk}</td> | |
| <td>${A(`cB_${spk}_0.wav`)}</td> | |
| <td>${A(`cE_${spk}_0.wav`)}</td> | |
| <td>${A(`cRL_s0_a0_${spk}_0.wav`)}</td></tr>`); | |
| }); | |
| </script> | |
| </body> | |
| </html> | |