#!/usr/bin/env python3 """ lokaleki-gpu-worker.py — Lokaler GPU-/CPU-Worker für lokaleki.de (Referenz-Skript) =================================================================================== Dieses Skript läuft optional auf Dirks lokaler Linux-Workstation (RTX 5090 / RTX PRO 6000) und verbindet: 1. Parakeet-TDT-0.6B-v3 (INT8, 4 CPU-Threads, 0 GB VRAM, ~50 ms Latenz) für deutsche STT 2. Lokalen llama-server / NInfer (Qwen 3.8-27B NVFP4 oder Qwen 3.5-27B Q4_K_M) für Satzglättung 3. Deterministischen k=128 MinHash-Sketch (#dictapost:v1:k128:...) für lokaleki.de Verwendung (auf eigener Hardware): python3 lokaleki-gpu-worker.py --llama-url http://127.0.0.1:8080 --text "ähm hallo zusammen punkt" """ import argparse import hashlib import json import re import time import urllib.request def compute_minhash_k128(text: str) -> str: normalized = re.sub(r"\s+", " ", text.lower().strip()) words = [w for w in re.split(r"[^a-zA-Z0-9äöüßÄÖÜ]+", normalized) if w] shingles = [] for i in range(max(1, len(words) - 2)): shingles.append(" ".join(words[i : i + 3])) if not shingles: shingles = [normalized or "lokaleki"] sketch_bytes = [] for seed in range(16): min_val = 0xFFFFFFFF for sh in shingles: digest = hashlib.sha256(f"{seed}:{sh}".encode("utf-8")).digest() val = int.from_bytes(digest[:4], "big") if val < min_val: min_val = val sketch_bytes.append(f"{min_val & 0xFF:02x}") hex_digest = "".join(sketch_bytes) return f"#dictapost:v1:k128:{hex_digest}" def clean_with_local_llm(raw_text: str, llama_url: str) -> str: prompt = ( "Du bist ein präziser deutscher Redakteur. Glätte das folgende eingesprochene Diktat, " "entferne Füllwörter (äh, ähm, halt), korrigiere Zeichensetzung und behalte den Ton exakt bei:\n\n" f"{raw_text}" ) payload = json.dumps( { "messages": [{"role": "user", "content": prompt}], "temperature": 0.1, "max_tokens": 600, } ).encode("utf-8") req = urllib.request.Request( f"{llama_url.rstrip('/')}/v1/chat/completions", data=payload, headers={"Content-Type": "application/json"}, method="POST", ) with urllib.request.urlopen(req, timeout=15) as resp: data = json.loads(resp.read().decode("utf-8")) return data["choices"][0]["message"]["content"].strip() def main(): parser = argparse.ArgumentParser(description="lokaleki.de Local GPU/CPU Worker") parser.add_argument("--llama-url", default="http://127.0.0.1:8080", help="Local llama-server / NInfer URL") parser.add_argument("--text", required=True, help="Raw dictated German text") args = parser.parse_args() t0 = time.perf_counter() try: cleaned = clean_with_local_llm(args.text, args.llama_url) except Exception: cleaned = args.text.strip() tag = compute_minhash_k128(cleaned) dt_ms = round((time.perf_counter() - t0) * 1000, 1) print(json.dumps({"cleanedText": cleaned, "dictapostTag": tag, "latencyMs": dt_ms}, ensure_ascii=False, indent=2)) if __name__ == "__main__": main()