Add profile presets and min-p controls, embeddings and VoxCPM workers
This commit is contained in:
1 parent
74dd2ed8ba
commit
a7b30b62d2
32 files changed
+615
-64
No files matched your search
@@ -14,6 +14,7 @@ from tts_runtime import TTSRuntime
|
||||
from stt import STT,read_upload
|
||||
from audio_policy import AudioPolicy
|
||||
from tts_test import TTSTests
|
||||
from voxcpm_test import VoxCPMTests
|
||||
from profiles import Profiles
|
||||
from capacity import assess, overview
|
||||
from runtime import Runtime
|
||||
@@ -104,8 +105,14 @@ class Server(ThreadingHTTPServer):
|
||||
raise RuntimeError('Serverzugang muss vor dem Start eingerichtet werden.')
|
||||
self.worker=LlamaWorker(self.catalog.root.parent/'llama-worker',self.catalog,self.runtime)
|
||||
self.scheduler=Scheduler(self.worker)
|
||||
self.voxcpm_tests=VoxCPMTests(self.catalog.root.parent/'voice-tests',self.profiles,self.voxcpm_runtime)
|
||||
self.voxcpm_tests.acquire=lambda wait=False:self.scheduler.image_reservation(wait,kind='voice')
|
||||
self.separator_runtime=SeparatorRuntime(self.catalog.root.parent/'separator-runtime')
|
||||
self.separator_tests=SeparatorTests(self.catalog.root.parent/'separator-tests',self.separator_runtime,self.scheduler)
|
||||
from embeddings import Embeddings
|
||||
import tempfile
|
||||
self.embeddings=Embeddings(tempfile.mkdtemp(prefix='deck-embeddings-'),self.catalog,self.worker)
|
||||
self.profiles.embedding_blockers=self.embeddings.blockers
|
||||
self.profiles.chat_blockers=self.worker.blockers
|
||||
self.image_tests.acquire=self.scheduler.image_reservation
|
||||
self.prompt_enhancer.acquire=self.scheduler.image_reservation
|
||||
@@ -114,12 +121,14 @@ class Server(ThreadingHTTPServer):
|
||||
self.stt=STT(self.profiles,self.catalog,self.runtime)
|
||||
self.profiles.stt_blockers=self.stt.blockers
|
||||
self.endpoint=Endpoint(self.catalog.root.parent,self.profiles,self.worker,self.scheduler,self.image_tests,self.credentials,self.server_port)
|
||||
self.endpoint.embeddings=self.embeddings
|
||||
self.endpoint.tts=self.tts_tests
|
||||
self.endpoint.voxcpm=self.voxcpm_tests
|
||||
self.endpoint.stt=self.stt
|
||||
self.chat_tests=ChatTests(self.profiles,self.worker,self.scheduler)
|
||||
self.auto_tests=AutoTests(self.catalog.root.parent/'auto-tests.json',self.profiles,self.worker,self.scheduler)
|
||||
def stop_gpu_work():
|
||||
self.separator_tests.stop();self.music.stop();self.auto_tests.stop();self.chat_tests.stop();self.image_tests.stop();self.prompt_enhancer.stop_preview();self.tts_tests.stop();self.worker.stop()
|
||||
self.voxcpm_tests.stop();self.separator_tests.stop();self.music.stop();self.auto_tests.stop();self.chat_tests.stop();self.image_tests.stop();self.prompt_enhancer.stop_preview();self.tts_tests.stop();self.worker.stop()
|
||||
from video_original import VideoRuntimes
|
||||
from ltx_original_runtime import LTXOriginalRuntime
|
||||
from audio_cpp_runtime import AudioCppRuntime
|
||||
@@ -306,7 +315,7 @@ class Handler(BaseHTTPRequestHandler):
|
||||
video_runtime = (self.server.video.original_runtime
|
||||
if self.server.video.runtime_kind() == 'original'
|
||||
else self.server.video.runtime)
|
||||
return {'stt':chat,'chat':chat,
|
||||
return {'embeddings':chat,'stt':chat,'chat':chat,
|
||||
'image':self.server.image_runtime.status().get('installed',False),
|
||||
'audio':self.server.tts_runtime.status().get('installed',False),
|
||||
'video':video_runtime.status().get('installed',False),
|
||||
@@ -327,7 +336,7 @@ class Handler(BaseHTTPRequestHandler):
|
||||
return self.respond({'error':'Anmeldung erforderlich.'},401)
|
||||
if not self.authenticated() and self.path == '/':
|
||||
return self.respond((ROOT/'login.html').read_bytes(), mime='text/html; charset=utf-8')
|
||||
routes = {'/voxcpm-ui.js':('voxcpm-ui.js','text/javascript'),'/separator-ui.js':('separator-ui.js','text/javascript'),'/music-ui.js':('music-ui.js','text/javascript'),'/audio-cpp-ui.js':('audio-cpp-ui.js','text/javascript'),'/ltx-original-ui.js':('ltx-original-ui.js','text/javascript'),'/backup-ui.js':('backup-ui.js','text/javascript'),'/dashboard-ui.js':('dashboard-ui.js','text/javascript'),'/dashboard.css':('dashboard.css','text/css'),'/themes.css':('themes.css','text/css'),'/video-ui.js':('video-ui.js','text/javascript'),'/stt-ui.js':('stt-ui.js','text/javascript'),'/tts-ui.js':('tts-ui.js','text/javascript'),'/auto-test-ui.js':('auto-test-ui.js','text/javascript'),'/chat-test-ui.js':('chat-test-ui.js','text/javascript'),'/endpoint-ui.js':('endpoint-ui.js','text/javascript'),'/docker-ui.js': ('docker-ui.js','text/javascript'), '/': ('index.html', 'text/html; charset=utf-8'), '/app.js': ('app.js', 'text/javascript'), '/style.css': ('style.css', 'text/css'), '/network-ui.js': ('network-ui.js', 'text/javascript'), '/access-ui.js': ('access-ui.js', 'text/javascript'), '/studio.js': ('studio.js', 'text/javascript'), '/catalog-ui.js': ('catalog-ui.js','text/javascript'), '/runtime-ui.js': ('runtime-ui.js','text/javascript'), '/profiles-ui.js': ('profiles-ui.js','text/javascript'), '/image-test-ui.js': ('image-test-ui.js','text/javascript')}
|
||||
routes = {'/voice-ui.js':('voice-ui.js','text/javascript'),'/voxcpm-ui.js':('voxcpm-ui.js','text/javascript'),'/separator-ui.js':('separator-ui.js','text/javascript'),'/music-ui.js':('music-ui.js','text/javascript'),'/audio-cpp-ui.js':('audio-cpp-ui.js','text/javascript'),'/ltx-original-ui.js':('ltx-original-ui.js','text/javascript'),'/backup-ui.js':('backup-ui.js','text/javascript'),'/dashboard-ui.js':('dashboard-ui.js','text/javascript'),'/dashboard.css':('dashboard.css','text/css'),'/themes.css':('themes.css','text/css'),'/video-ui.js':('video-ui.js','text/javascript'),'/stt-ui.js':('stt-ui.js','text/javascript'),'/tts-ui.js':('tts-ui.js','text/javascript'),'/auto-test-ui.js':('auto-test-ui.js','text/javascript'),'/chat-test-ui.js':('chat-test-ui.js','text/javascript'),'/endpoint-ui.js':('endpoint-ui.js','text/javascript'),'/docker-ui.js': ('docker-ui.js','text/javascript'), '/': ('index.html', 'text/html; charset=utf-8'), '/app.js': ('app.js', 'text/javascript'), '/style.css': ('style.css', 'text/css'), '/network-ui.js': ('network-ui.js', 'text/javascript'), '/access-ui.js': ('access-ui.js', 'text/javascript'), '/studio.js': ('studio.js', 'text/javascript'), '/catalog-ui.js': ('catalog-ui.js','text/javascript'), '/runtime-ui.js': ('runtime-ui.js','text/javascript'), '/profiles-ui.js': ('profiles-ui.js','text/javascript'), '/image-test-ui.js': ('image-test-ui.js','text/javascript')}
|
||||
if self.path in routes:
|
||||
name, mime = routes[self.path]
|
||||
return self.respond((ROOT/name).read_bytes(), mime=mime)
|
||||
@@ -341,6 +350,10 @@ class Handler(BaseHTTPRequestHandler):
|
||||
if self.path == '/api/v1/endpoint':return self.respond(self.server.endpoint.status())
|
||||
if self.path == '/api/v1/docker':return self.respond(self.server.docker.status())
|
||||
if self.path == '/api/v1/stt':return self.respond(self.server.stt.status())
|
||||
if self.path == '/api/v1/voice':return self.respond(self.server.voxcpm_tests.status())
|
||||
if urlsplit(self.path).path == '/api/v1/voice/audio':
|
||||
try:return self.respond(self.server.voxcpm_tests.audio(parse_qs(urlsplit(self.path).query).get('id',[''])[0]),mime='audio/wav')
|
||||
except (ValueError,OSError) as exc:return self.respond({'error':str(exc)},400)
|
||||
if self.path == '/api/v1/tts':return self.respond(self.server.tts_tests.status())
|
||||
if self.path == '/api/v1/audio-policy':return self.respond(self.server.audio_policy.status())
|
||||
if urlsplit(self.path).path == '/api/v1/tts/audio':
|
||||
@@ -623,6 +636,21 @@ class Handler(BaseHTTPRequestHandler):
|
||||
if set(data)-{'profile_id','lyrics','style','seed','max_tokens','steps'} or not {'profile_id','lyrics','style'}<=set(data):raise ValueError('Ungültige Musikfelder.')
|
||||
return self.respond(self.server.music.start(**data))
|
||||
except ValueError as exc:return self.respond({'error':str(exc)},400)
|
||||
if self.path in ('/api/v1/voice/start','/api/v1/voice/cancel'):
|
||||
try:
|
||||
if self.path.endswith('/cancel'):
|
||||
if self.read_json():raise ValueError('Keine Abbruchparameter erwartet.')
|
||||
return self.respond(self.server.voxcpm_tests.stop())
|
||||
if self.headers.get('Content-Type','').startswith('multipart/form-data'):
|
||||
fields,audio=read_upload(self,validate=False,allowed_fields=('profile_id','text','device','cfg','steps','seed'),max_field=4096)
|
||||
fields['reference']=audio
|
||||
for key in ('steps','seed'):
|
||||
if key in fields:fields[key]=int(fields[key])
|
||||
if 'cfg' in fields:fields['cfg']=float(fields['cfg'])
|
||||
else:fields=self.read_json()
|
||||
if set(fields)-{'profile_id','text','device','cfg','steps','seed','reference'} or not {'profile_id','text'}<=set(fields):raise ValueError('Ungültige VoxCPM2-Anfrage.')
|
||||
return self.respond(self.server.voxcpm_tests.start(**fields))
|
||||
except (ValueError,OSError) as exc:return self.respond({'error':str(exc)},400)
|
||||
if self.path in ('/api/v1/tts/install','/api/v1/tts/install-cancel','/api/v1/tts/assign','/api/v1/tts/start','/api/v1/tts/cancel'):
|
||||
try:
|
||||
data=self.read_json();t=self.server.tts_tests
|
||||
@@ -683,7 +711,9 @@ class Handler(BaseHTTPRequestHandler):
|
||||
if self.path == '/api/v1/profiles/delete':
|
||||
try:
|
||||
data=self.read_json()
|
||||
with self.server.image_tests.lock, self.server.tts_tests.lock, self.server.stt.lock:
|
||||
with self.server.image_tests.lock, self.server.tts_tests.lock, self.server.stt.lock, self.server.voxcpm_tests.lock:
|
||||
voice_job=self.server.voxcpm_tests.job
|
||||
if voice_job and voice_job.get('state')=='running' and voice_job.get('profile_id')==data.get('id'):raise ValueError('Stimmprofil wird gerade ausgeführt. Zuerst Auftrag abbrechen.')
|
||||
stt_job=self.server.stt.job
|
||||
if stt_job and stt_job.get("state")=="running" and stt_job.get("profile_id")==data.get("id"):raise ValueError("Dieses STT-Profil wird gerade ausgeführt. Zuerst den Auftrag beenden.")
|
||||
tts_job=self.server.tts_tests.job
|
||||
@@ -696,6 +726,10 @@ class Handler(BaseHTTPRequestHandler):
|
||||
return self.respond(result)
|
||||
except ValueError as exc:return self.respond({'error':str(exc)},400)
|
||||
except OSError:return self.respond({'error':'Profil konnte nicht gelöscht werden.'},503)
|
||||
if self.path == '/api/v1/profiles/preset':
|
||||
try:return self.respond(self.server.profiles.preset(self.read_json()))
|
||||
except ValueError as exc:return self.respond({'error':str(exc)},400)
|
||||
except OSError:return self.respond({'error':'Preset konnte nicht gespeichert werden.'},503)
|
||||
if self.path == '/api/v1/profiles/save':
|
||||
try:return self.respond(self.server.profiles.save(self.read_json()))
|
||||
except ValueError as exc:return self.respond({'error':str(exc)},400)
|
||||
@@ -760,7 +794,7 @@ def main():
|
||||
server.video.close()
|
||||
server.endpoint.close()
|
||||
server.stt.stop()
|
||||
server.tts_tests.stop()
|
||||
server.voxcpm_tests.stop();server.tts_tests.stop()
|
||||
server.tts_runtime.stop();server.voxcpm_runtime.stop()
|
||||
server.image_runtime.stop()
|
||||
server.ltx_original_runtime.stop()
|
||||
|
||||
Reference in new issue
Block a user