Files
Athena-Deck/execution_setup.py
T

89 lines
9.3 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""Read-only, conservative mapping to Deck's maintained execution adapters."""
from catalog import file_role
from stt import supported as stt_supported
from profiles import image_recipe, video_recipe
from tts_runtime import REPO, REVISION
def _assess(model, installed, profile=None):
kind=model.get('kind'); filename=model.get('file',''); repo=model.get('repo','')
meta=model.get('runtime_metadata') if isinstance(model.get('runtime_metadata'),dict) else {}
architecture=meta.get('architecture') if isinstance(meta.get('architecture'),str) else None
result=dict(state='unsupported',label='Noch nicht unterstützt',runtime=None,installed=False,route=None,components=[],family=architecture or 'Unbekannt',evidence='Hub-Metadaten' if architecture else 'Keine ausreichenden Metadaten',message='Für dieses Modell ist in Deck noch kein geprüfter Ausführungsweg hinterlegt. Herunterladen und Aufbewahren ist möglich; eine Installation allein genügt nicht.')
if not file_role(filename)['profile_eligible']:
result.update(state='component',label='Zusatzdatei',message='Diese Datei wird einem kompatiblen Modellprofil zugeordnet und benötigt keine eigene Laufzeit.')
return result
if kind=='stt' and stt_supported(model):
result['family']='Qwen3-ASR 0.6B'
result.update(runtime='llama.cpp · Qwen3-ASR auf CPU',route='#stt-runtime',components=['Passender Audio-Projektor (unter Einrichten herunterladen)'])
elif kind=='image' and image_recipe(model):
result['family']='FLUX.2 Klein 9B' if 'FLUX' in filename.upper() else 'Qwen Image 2.1'
result.update(runtime='ComfyUI + ComfyUI-GGUF',route='#image-runtime',components=[x['label'] for x in image_recipe(model).values()])
elif kind=='audio' and repo==REPO and filename=='model.safetensors' and model.get('revision')==REVISION:
result['family']='Qwen3-TTS CustomVoice'
result.update(runtime='Qwen3-TTS CustomVoice',route='#tts-runtime',components=['Vollständiges Modellpaket und Sprach-Tokenizer (im Einrichtungsassistenten enthalten)'])
elif kind=='chat' and filename.lower().endswith('.gguf'):
result.update(runtime='llama.cpp',route='#runtime',state='check',label='Kompatibilität beim Laden prüfen',message='llama.cpp ist der mögliche Ausführungsweg für dieses Chat-GGUF. Architektur und gewählte Optionen müssen vom installierten Build unterstützt werden. Der Testchat prüft die tatsächliche Ausführung.')
elif kind=='image' and filename.lower().endswith(('.safetensors','.gguf')) and (meta.get('pipeline_tag') in ('text-to-image','image-to-image') or meta.get('library_name') in ('diffusers','comfyui')):
result.update(state='workflow_missing',label='Bildfamilie erkannt · Workflow fehlt',runtime='ComfyUI (vorhandene Bildlaufzeit prüfen)',installed=bool(installed.get('image')),route='#image-runtime',message='Hub-Metadaten ordnen die Datei einer Bildpipeline zu. Deck hat bereits eine gemeinsame Bildlaufzeit; ein neuer Build ist nicht automatisch nötig. Für diese Modellvariante fehlen noch ein geprüfter ComfyUI-Workflow und die genaue Komponentenliste. Bis dahin kann sie nicht gestartet werden.')
if not architecture:result['family']='Bildpipeline laut Hugging Face'
elif kind=='stt':
result.update(message='Für diese STT-Datei fehlt die Anbindung. Die geprüfte llama.cpp-Variante von Qwen3-ASR kann unter Einrichten zusätzlich geladen und ausdrücklich einem Profil zugeordnet werden.',alternative=dict(route='#stt-runtime',label='Unterstützte STT-Alternative einrichten (Modellwechsel)'))
elif kind=='audio':
result.update(message='Dieses TTS-Modell wird noch nicht ausgeführt. Deck unterstützt derzeit die festgelegte Qwen3-TTS-CustomVoice-Variante mit eingebauten Stimmen. MLX, Base mit Referenzstimme und andere TTS-Architekturen benötigen andere Anbindungen.',alternative=dict(route='#tts-runtime',label='Unterstützte TTS-Alternative ansehen (Modellwechsel)'))
if video_recipe(model):
result['family']='LTX 2.5'
result.update(runtime='LTX Original oder ComfyUI · LTX 2.5',state='runtime_missing',label='Komponenten und Video-Laufzeit einrichten',route='#video',components=[x['label'] for x in video_recipe(model).values()],message='Im Bereich Video LTX Original für LTX DeskWEB oder die vorhandene ComfyUI-Laufzeit wählen. Gewichte und passende Komponenten derselben Quellversion werden wiederverwendet.')
if not result['runtime']:return result
result['installed']=bool(installed.get(kind))
if kind!='chat' and result['state']!='workflow_missing':
result.update(state='setup',label='Unterstützt – Einrichtung prüfen',message='Die Laufzeit wird für kompatible Modelle gemeinsam genutzt. Modellabhängige Komponenten werden dem jeweiligen Profil zugeordnet.')
if not result['installed'] and result['state']!='workflow_missing':
result.update(state='runtime_missing',label='Passende Laufzeit fehlt')
if profile:
result['blockers']=profile.get('blockers',[])
if profile.get('runnable'):
result.update(state='ready',label='Ausführbar – Laufzeit eingerichtet')
elif result['installed']:
result.update(state='profile_incomplete',label='Profil prüfen – Voraussetzungen fehlen')
return result
def assess(model, installed, profile=None):
result=_assess(model,installed,profile)
result['candidates']=[]
if result['state']=='component':return result
kind=model.get('kind');repo=model.get('repo','').lower();name=model.get('file','').lower()
meta=model.get('runtime_metadata') or {};family=str(meta.get('architecture') or '').lower()
def add(id,label,key,route,reason,maintained=True):
result['candidates'].append(dict(id=id,label=label,installed=bool(installed.get(key)),route=route,installation_available=maintained,evidence=reason))
if result.get('runtime'):
add('current',result['runtime'],kind,result['route'],'Vorhandene Deck-Zuordnung')
if kind=='music' and repo=='audio-cpp/yue2-3b-gguf' and name.startswith('yue2-3b-') and name.endswith('.gguf'):
result.update(family='YuE2',evidence='audio-cpp/Yue2-3B-GGUF · Hauptmodell',state='adapter_missing',label='YuE2 erkannt · Deck-Worker fehlt',message='Passende Laufzeit: audio.cpp. Sie kann einmalig heruntergeladen und gebaut werden. Zur Generierung fehlen noch der Deck-Musikworker und die Ladypoly-Anbindung. Installation allein schaltet dieses Modell nicht frei.',components=['YuE2-VAE GGUF','Modell-/Generierungskonfiguration, VAE-Konfiguration und Qwen-Tokenizer (sidecars)'])
if installed.get('music_worker'):
result.update(state='setup',label='YuE2-Musikworker verfügbar · Komponenten prüfen',message='audio.cpp-Laufzeit und benötigte Komponenten einrichten. Danach Musik → Testen verwenden oder Profil am Musik-API-Endpunkt freigeben.',runtime='audio.cpp',installed=bool(installed.get('audio_cpp')),route='#music')
if profile:
result.update(state='ready' if profile.get('runnable') else 'profile_incomplete',label='Ausführbar · audio.cpp-Musikworker' if profile.get('runnable') else 'Musikprofil einrichten',message='YuE2 wird mit den zugeordneten Komponenten über audio.cpp ausgeführt. Testen im Musikbereich; Ergebnisse als WAV. Ladypoly-WebUI ist separat.',blockers=profile.get('blockers',[]))
add('audio_cpp','audio.cpp','audio_cpp','#audio-cpp-runtime','Geprüfte GGUF-Quelle für die YuE2-Modellfamilie')
elif kind=='music' and ('yue2' in repo or 'yue2' in family):
result.update(family='YuE2',evidence='Repository-/Architekturhinweis; Ausführung ungeprüft')
add('yue2','YuE2 Python / PyTorch','yue2',None,'Originale YuE2-Pipeline; Originalgewichte erforderlich',False)
if kind in ('audio','stt','music','voice') and not result['candidates']:
if 'audio-cpp/' in repo and name.endswith('.gguf'):
add('audio_cpp','audio.cpp','audio_cpp','#audio-cpp-runtime','audio-cpp-Repository; konkrete Familie und Zusatzdateien noch prüfen')
elif meta.get('library_name')=='transformers':
add('transformers','Hugging Face Transformers / PyTorch','transformers',None,'Hub nennt Transformers; modellabhängiger Worker erforderlich',False)
if kind=='voice' and any(token in (repo+' '+name+' '+family) for token in ('roformer','demucs')):
add('separator','Audio Separator','separator','#separator-runtime','Trennmodell-Hinweis; exakte Datei und Konfiguration müssen zum unterstützten Paket passen')
result['candidate_message']='Unter Audio Separator sind geprüfte Modellpakete mit Konfiguration verfügbar. Beliebige CoreML-, ONNX- oder Safetensors-Abwandlungen sind nicht automatisch kompatibel.'
if kind=='video' and not result['candidates'] and meta.get('library_name')=='diffusers':
add('diffusers','Diffusers / PyTorch','diffusers',None,'Hub nennt Diffusers; passende Video-Pipeline noch prüfen',False)
if not result['candidates']:
# Category-level options are explicit research hints, never compatibility claims.
options={'chat':('llama.cpp','chat','#runtime'), 'image':('ComfyUI','image','#image-runtime'), 'video':('ComfyUI','image','#image-runtime'), 'audio':('audio.cpp','audio_cpp','#audio-cpp-runtime'), 'stt':('audio.cpp','audio_cpp','#audio-cpp-runtime'), 'music':('audio.cpp','audio_cpp','#audio-cpp-runtime'), 'voice':('audio.cpp','audio_cpp','#audio-cpp-runtime')}
if kind in options:
label,key,route=options[kind]
add('category',label,key,route,'Option für diese Kategorie; Kompatibilität mit dieser unbekannten Modellfamilie NICHT bestätigt')
result['candidate_message']='Keine passende Laufzeit zuverlässig ermittelt. Modellkarte und Architektur müssen geprüft werden; keine automatische Installation auf Verdacht.'
return result