diff --git a/README.md b/README.md index 84d5b33..d3d8252 100644 --- a/README.md +++ b/README.md @@ -248,3 +248,9 @@ die 5080 nicht frei genug ist. Eine feste Auswahl fällt nicht still auf eine andere Karte zurück. Auch die Separator-Weboberfläche beachtet diese Einstellungen. Profileinstellungen werden im verschlüsselten Backup gespeichert. Die GPU-Prüfung ist eine Vorprüfung; ein tatsächlicher OOM wird weiterhin als Auftragsfehler angezeigt. + +Der YuE2-Test bietet eine maximale Länge in Sekunden (1,28–360 s). Bei der aktuellen +VAE-Konfiguration entsprechen 25 semantische Tokens einer Sekunde; die erweiterten +Token- und Sekundenfelder werden synchronisiert. Das Modell kann vor dem Limit enden. +Der Ergebnisplayer bleibt beim Status-Polling bestehen, damit die Wiedergabe nicht +alle 1,5 Sekunden zurückgesetzt wird. diff --git a/music-ui.js b/music-ui.js index 9f36dd5..1bf007a 100644 --- a/music-ui.js +++ b/music-ui.js @@ -1,10 +1,12 @@ window.MusicUI=(()=>{ const e=v=>String(v??'').replace(/[&<>"']/g,c=>({'&':'&','<':'<','>':'>','"':'"',"'":'''}[c])); async function api(path,data){const r=await fetch('/api/v1/'+path,data===undefined?{}:{method:'POST',headers:{'Content-Type':'application/json','X-Athena-Deck':'1'},body:JSON.stringify(data)});const x=await r.json();if(!r.ok)throw Error(x.error||'Musikanfrage fehlgeschlagen');return x;} - function html(){return '

Musik ausprobieren

YuE2 über audio.cpp. Englische Songtexte werden empfohlen. Ein kurzer Test beginnt mit höchstens 400 semantischen Tokens; dies ist keine feste Dauer in Sekunden.

Testparameter

RTX 5080 bevorzugt. Deck-Aufträge werden koordiniert. Nach der Anfrage wird das Modell entladen. Text und Stil werden nicht dauerhaft gespeichert.

';} - function bind(){const root=document.querySelector('#music-test'),el=id=>root.querySelector('#'+id);let ready=false,busy=false; - async function poll(){if(!root.isConnected)return;try{const s=await api('music');if(!root.isConnected)return;const j=s.job,running=j?.state==='running';el('music-state').textContent=(s.mode!=='music'?'Bitte in der Übersicht auf Musik umschalten.':j?.phase||'Profil wählen und Musikstil sowie Songtext eingeben.')+(running?' · '+Math.round((Date.now()/1000)-j.started_at)+' s':'');el('music-progress').innerHTML=running?'':'';el('music-start').disabled=busy||running||!ready||s.mode!=='music';el('music-cancel').disabled=!running;if(j?.state==='complete')el('music-result').innerHTML=`

Ergebnis · ${e(j.duration_seconds)} Sekunden

WAV herunterladen

`;if(j?.state==='failed')el('music-error').textContent=j.phase;}catch(x){if(root.isConnected)el('music-error').textContent=x.message;}if(root.isConnected)setTimeout(poll,1500);} + function html(){return '

Musik ausprobieren

YuE2 über audio.cpp. Englische Songtexte werden empfohlen. Die maximale Länge begrenzt den Test. YuE2 kann früher enden; eine exakt feste Titellänge ist damit nicht garantiert.

Bis etwa 16 Sekunden · 400 semantische Tokens. YuE2 verwendet hier ungefähr 25 Tokens pro Sekunde.

Erweiterte Testparameter

RTX 5080 bevorzugt. Deck-Aufträge werden koordiniert. Nach der Anfrage wird das Modell entladen. Text und Stil werden nicht dauerhaft gespeichert.

';} + function bind(){const root=document.querySelector('#music-test'),el=id=>root.querySelector('#'+id);let ready=false,busy=false,resultId=null; + async function poll(){if(!root.isConnected)return;try{const s=await api('music');if(!root.isConnected)return;const j=s.job,running=j?.state==='running';el('music-state').textContent=(s.mode!=='music'?'Bitte in der Übersicht auf Musik umschalten.':j?.phase||'Profil wählen und Musikstil sowie Songtext eingeben.')+(running?' · '+Math.round((Date.now()/1000)-j.started_at)+' s':'');el('music-progress').innerHTML=running?'':'';el('music-start').disabled=busy||running||!ready||s.mode!=='music';el('music-cancel').disabled=!running;if(!busy&&j?.state==='complete'&&j.id!==resultId){resultId=j.id;el('music-result').innerHTML=`

Ergebnis · ${e(j.duration_seconds)} Sekunden

WAV herunterladen

`;}if(j?.state==='failed')el('music-error').textContent=j.phase;}catch(x){if(root.isConnected)el('music-error').textContent=x.message;}if(root.isConnected)setTimeout(poll,1500);} + function updateLength(fromTokens=false){const tokens=fromTokens?Number(el('music-tokens').value):Math.round(Number(el('music-duration').value)*25);if(!fromTokens)el('music-tokens').value=tokens;else el('music-duration').value=(tokens/25).toFixed(2);el('music-length-hint').textContent=`Bis etwa ${(tokens/25).toFixed(2)} Sekunden · ${tokens} semantische Tokens. Das Modell kann früher enden.`;} + el('music-duration').step='0.04';el('music-duration').min='1.28';el('music-duration').oninput=()=>updateLength();el('music-tokens').oninput=()=>updateLength(true); api('profiles').then(s=>{if(!root.isConnected)return;const profiles=s.profiles.filter(p=>p.kind==='music'&&p.runnable);ready=profiles.length>0;el('music-profile').innerHTML=profiles.map(p=>``).join('')||'';}).catch(x=>el('music-error').textContent=x.message); - el('music-form').onsubmit=async event=>{event.preventDefault();busy=true;el('music-start').disabled=true;el('music-error').textContent='';el('music-result').replaceChildren();try{await api('music/start',{profile_id:el('music-profile').value,lyrics:el('music-lyrics').value,style:el('music-style').value,seed:Number(el('music-seed').value),max_tokens:Number(el('music-tokens').value),steps:Number(el('music-steps').value)});}catch(x){el('music-error').textContent=x.message;}finally{busy=false;}};el('music-cancel').onclick=()=>api('music/cancel',{}).catch(x=>el('music-error').textContent=x.message);poll();} + el('music-form').onsubmit=async event=>{event.preventDefault();busy=true;el('music-start').disabled=true;el('music-error').textContent='';el('music-result').replaceChildren();resultId=null;try{await api('music/start',{profile_id:el('music-profile').value,lyrics:el('music-lyrics').value,style:el('music-style').value,seed:Number(el('music-seed').value),max_tokens:Number(el('music-tokens').value),steps:Number(el('music-steps').value)});}catch(x){el('music-error').textContent=x.message;}finally{busy=false;}};el('music-cancel').onclick=()=>api('music/cancel',{}).catch(x=>el('music-error').textContent=x.message);poll();} return {html,bind}; })();