Architecture

Modèles

Comment Cradle gère les modèles GGUF locaux — catalogue, téléchargement, compatibilité matérielle, cycle de vie du runner et budget mémoire.

Cradle exécute les modèles localement via node-llama-cpp (llama.cpp). Après le téléchargement d'un modèle, l'inférence a lieu entièrement sur l'hôte — pas d'endpoint cloud, pas de runtime Python dans le processus principal.

Rôles des modèles

Chaque entrée de catalogue a un role qui décide comment le runner est utilisé :

RôleUtilisé par
classifierClassifieur de risque niveau 2 (sortie JSON structurée par schéma)
generalAgents avec rôle general, business, marketing, seo, other
codingAgents avec rôle coding
embeddingIngestion et retrieval RAG

Le fournisseur de runner choisit automatiquement le bon modèle :

  • acquireClassifier — premier classifier, puis le plus petit modèle non-embedding si aucun classifieur n'est configuré.
  • acquireForAgent(id) — le modelId exact enregistré sur l'agent.
  • acquireEmbedder — uniquement les modèles embedding.

Catalogue intégré

Cradle embarque assets/models-catalog.json couvrant les modèles de chat, de code et d'embedding. Quelques entrées représentatives :

IDRôleTailleRAM approx.Contexte
qwen3-0.6b-q4classifier430 MB2 GB4K
qwen3-1.7b-q4general1,1 GB3 GB8K
qwen3-8b-q4general4,9 GB10 GB16K
qwen3-14b-q4general8,4 GB16 GB16K
qwen3-coder-7b-q4coding4,7 GB10 GB16K
qwen3-embedding-0.6b-q8embedding680 MB2 GB8K
bge-m3-q4embedding580 MB2 GB8K

Les sources suivent les conventions GGUF HuggingFace (unsloth/…-GGUF, bartowski/…-GGUF, Qwen/…-GGUF, CompendiumLabs/bge-m3-gguf).

Compatibilité matérielle

Avant de tirer un modèle, Cradle vérifie s'il tient sur l'hôte. Le verdict est affiché dans la page Modèles et dans cradle models list :

cradle models list
# ● fits comfortably  qwen3-8b-q4  needs ~10.0 GB; 18 GB total
# ● tight             qwen3-14b-q4 needs ~16.0 GB; 18 GB total
# ● won't run         llama-3.3-70b-q4 needs ~48 GB; 18 GB total

cradle models check <catalogId> affiche le calcul complet (poids + cache KV + marge). Le vérificateur vit dans src/core/models/hardware-checker.ts.

Téléchargement et reprise

Les fichiers de modèle sont téléchargés dans le répertoire de données utilisateur :

  • Application de bureau : ~/Library/Application Support/Cradle/models/<id>.gguf
  • Serveur : ~/.cradle/models/<id>.gguf

Les téléchargements supportent la reprise via des fichiers .part et les en-têtes Range: bytes=X-, l'annulation via AbortController, la vérification SHA-256 optionnelle, et les broadcasts de progression toutes les 300 ms.

Interface du runner

type RunnerConfig = {
  contextSize?: number
  gpuLayers?: number | 'auto'
  mode?: 'chat' | 'embedding'
}

interface ModelRunner {
  load(modelPath, modelId, config): Promise<void>
  generate(prompt, opts?): AsyncIterable<string>
  generateStructured<T>(prompt, schema, opts?): Promise<T>
  embed(texts: string[]): Promise<number[][]>
  unload(): Promise<void>
  status(): RunnerStatus
}

LlamaCppRunner est la première implémentation. Elle wrapppe node-llama-cpp v3 avec des binaires précompilés pour Metal, CUDA et Vulkan. Un modèle se charge exactement dans un mode à la fois — passer du chat à l'embedding (ou l'inverse) décharge et recharge le modèle.

Gestion mémoire

Le registre de modèles garde les runners chargés dans une map indexée par l'ID de la ligne modèle :

  • Le budget par défaut est de 60 % de la RAM totale du système.
  • L'éviction LRU décharge le runner le moins récemment utilisé quand le budget est dépassé.
  • last_used_at est mis à jour à chaque acquire().
  • shutdownRegistry() dispose proprement de chaque runner à la sortie.

Les petits modèles (classifieur + embedder) sont bon marché à garder chargés ensemble. Les modèles d'agent plus gros sont chargés paresseusement à la première requête.

Modèles personnalisés

Vous pouvez ajouter un modèle personnalisé via la page Modèles ou en éditant userData/models-catalog-custom.json :

[{
  "id": "my-domain-slug",
  "name": "My domain model",
  "role": "general",
  "sizeMb": 3000,
  "url": "https://huggingface.co/.../model-Q4_K_M.gguf",
  "sha256": null,
  "recommendedRamGb": 6,
  "contextSize": 8192,
  "description": "..."
}]

Les entrées personnalisées fusionnent avec le catalogue intégré. Un id correspondant remplace l'entrée intégrée.

Modèles recommandés

cradle models list --recommended affiche une liste top-25 rafraîchie hebdomadairement depuis le OpenLLM Leaderboard, chacun avec le même verdict de compatibilité. C'est une fonctionnalité pilotée par l'opérateur : la liste est récupérée et mise en cache, jamais téléchargée automatiquement.