aparté — souffleurs (déploiement navigateur, ONNX q4 + LoRA int8 hot-swap)

Format prêt à servir dans le navigateur (transformers.js / WebGPU) de l'architecture « souffleurs » : UN seul modèle de base ONNX q4 partagé + des adaptateurs LoRA échangeables à chaud (.data), tous au même rang → un seul base sert tous les rôles.

Métaphore : le souffleur de théâtre. Le caller (souffleur-chat) décide et route ; les exécuteurs (souffleur-pdf, -xlsx-docx, -sandbox) produisent l'artefact. Le hot-swap = le même acteur (base) change de souffleur selon la scène.

Versioning (détection de mise à jour)

Les souffleurs ont des noms de fichiers versionnés immuables (souffleur-<role>-<version>.data). La source de vérité des versions courantes = manifest.json (à la racine). Un client fetch ce petit fichier en no-store, compare les version à son cache, et ne re-télécharge que le .data changé. Détails d'intégration : voir HANDOFF-versioning-souffleurs.md dans le repo de lab. Version actuelle : chat 0.2.0 (le caller redonne du code + route write_file(pdf)), exécuteurs 0.1.0.

Contenu du repo

Fichier Rôle Taille
onnx/model_q4.onnx graphe base r128 (slots LoRA int8, DequantizeLinear inline) ~0.36 MB
onnx/model_q4.onnx_data poids base q4 (externes, partagés par tous les souffleurs) ~795 MB
config.json, generation_config.json, tokenizer*.json tokenizer + config (chat_template inclus) ~4.7 MB
adapters/souffleur-chat.data caller — routage + tool-calls 86 MB
adapters/souffleur-pdf.data exécuteur PDF (jsPDF) 86 MB
adapters/souffleur-xlsx-docx.data exécuteur tableur / doc 86 MB
adapters/souffleur-sandbox.data exécuteur sandbox JS 86 MB

Ajouter un rôle = déposer un .data de 86 MB de plus. Rien d'autre ne bouge.

Pourquoi 86 MB par souffleur (et pas 340)

  • Adaptateurs entraînés en LoRA r128 (les exécuteurs), souffleur-chat entraîné en r64 puis padé r128 (lignes de rang nulles) pour partager le même base.
  • Stockage .data en int8 symétrique par canal (quant + DequantizeLinear, compute FP32 restauré à l'exécution) → ÷4 vs fp32 : 340 MB → 86 MB, sans perte de qualité mesurée (voir plus bas).
  • Le gros poids (795 MB base) est partagé une seule fois entre tous les rôles.

Chargement (transformers.js 4.2.0, WebGPU)

Le graphe référence deux fichiers externes : les poids base (model_q4.onnx_data) et un placeholder adapter.data remappé vers le souffleur voulu. Hot-swap = même graphe, autre .data.

import { pipeline } from '@huggingface/transformers'; // 4.2.0

async function load(souffleur) {
  return pipeline('text-generation', 'onnx/base', {
    device: 'webgpu', dtype: 'q4', model_file_name: 'model',
    session_options: { externalData: [
      { path: 'model_q4.onnx_data', data: 'onnx/model_q4.onnx_data' },
      { path: 'adapter.data',       data: `adapters/${souffleur}.data` },
    ] },
  });
}
// caller -> décide ; puis hot-swap vers l'exécuteur choisi
let pipe = await load('souffleur-chat');   // routage
pipe     = await load('souffleur-pdf');    // exécution (swap ~3.8 s, base en cache)

Validation hot-swap (navigateur, WebGPU, q4 int8)

Chaîne caller → hot-swap → exécuteur testée de bout en bout :

  1. souffleur-chat sur « Crée une facture PDF … 450 EUR HT » → émet write_file(kind="pdf", task="Créer une facture professionnelle … Total TTC : 450 EUR … paiement à 30 jours.") (tool-call pythonic complet, ~17 tok/s).
  2. hot-swap → souffleur-pdf en ~3.8 s (base en cache, on ne recharge que le .data).
  3. souffleur-pdf sur l'intent → code jsPDF valide (new jsPDF(), en-tête setFillColor/rect, N° FAC-2024-089, doc.output('blob')), ~13 tok/s.

La quantif int8 ne dégrade pas la sortie (identique/plus riche que le fp32 sur le même prompt).

Contrat & prompt système

Format tool-call pythonic : <|tool_call_start|>[name(args)]<|tool_call_end|> (parsé AST). Le prompt système du caller = coeur sp-chat + List of tools: [JSON] + (si fichiers) Files available: [{id,name,type}]. Deux règles apprises et critiques :

  • Recopier file_id à l'identique, ne jamais l'inventer.
  • Toujours appeler l'outil compute pour tout calcul (jamais de calcul mental).

Base & entraînement

  • Base : LFM2.5-VL-1.6B strippé, TEXT-ONLY (pas de vision_config), model_type: lfm2. La vision se rebranche par hot-swap d'encodeur (hors de ce repo).
  • Entraînement : Unsloth SFT sur AMD Strix Halo (Radeon 8060S, gfx1151, ROCm, WSL).
  • Cibles LoRA : in_proj,k_proj,out_proj,q_proj,v_proj,w1,w2,w3 ; scaling = 1.0 (alpha=r).
  • Le caller v6 score 94 % sur l'éval interne (routage + tool-calls).

Format « source » (bf16)

Les adaptateurs bf16 d'origine (safetensors + adapter_config.json + chat_template) sont dans le dossier souffleurs/<nom>/v0.1/ du repo de lab — utile pour re-quantifier ou ré-entraîner. Ce repo-ci est le format de service (le plus léger).

Downloads last month
79
Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support

Model tree for maxituc/aparte-souffleurs

Adapter
(12)
this model