DEV Community

Jacques Gariépy
Jacques Gariépy

Posted on

Faire tourner Qwen 3.8–27B en local avec Unsloth et DeepSeek Harness sur une RTX 3090 (24 Go) sous Windows 11.

Par Jacques GariépyGuide technique, retour d'expérience, dépannage Windows pas-à-pas et utilisation Web & CLI.


Table des Matières

  1. Introduction & Architecture Globale
  2. Pourquoi ce Setup ? (RTX 3090 24 Go + UD-Q4_K_XL)
  3. Comment Obtenir & Générer vos Clés d'Accès
  4. Dépannage & Installation d'Unsloth Studio : Le Bug SSLKEYLOGFILE
  5. Installation & Compilation de DeepSeek Harness
  6. Démarrage du Serveur Local Haute Performance (llama.cpp CUDA 13)
  7. Configuration Automatique & Fichier .env
  8. Utilisation : Interface Web & Mode CLI (Style Claude Code)
  9. Résolution des Pièges & Erreurs Courantes sous Windows
  10. Benchmarks Réels sur RTX 3090
  11. Résumé des Commandes & Scripts Clés

1. Introduction & Architecture Globale

Faire tourner un agent autonome d'ingénierie logicielle directement sur sa machine locale (100% privé, sans frais d'API et à latence minimale) est devenu une réalité grâce à la convergence de trois briques technologiques de pointe :

  1. DeepSeek Harness (dsh) : Le framework open-source d'agents de DeepSeek conçu pour orchestrer des workflows complexes de développement logiciel (gestion de sessions, modes Plan/Exécution, sandbox système, sous-agents, exécution de terminaux et édition de code).
  2. Unsloth Engine (llama.cpp CUDA 13) : Le moteur d'inférence C++/CUDA ultra-optimisé intégrant FlashAttention-2 et la quantisation dynamique du cache KV.
  3. Qwen 3.8-27B en Quantisation Dynamique (UD-Q4_K_XL) : Les modèles de code open-source les plus performants, optimisés par Unsloth pour offrir une précision équivalente au 5-bit avec l'empreinte mémoire d'un 4-bit.

Diagramme d'Architecture

┌──────────────────────────────────────────────────────────────────────────────┐
│                            INTERFACES UTILISATEUR                            │
├──────────────────────────────────────┬───────────────────────────────────────┤
│       Interface Web (Navigateur)     │        Interface Console (CLI)        │
│        http://127.0.0.1:3080         │           Style Claude Code           │
└──────────────────┬───────────────────┴───────────────────┬───────────────────┘
                   │                                       │
                   │ (WebSocket / HTTP)                    │ (Console I/O)
                   ▼                                       ▼
┌──────────────────────────────────────────────────────────────────────────────┐
│              DEEPSEEK HARNESS RUNTIME (Node.js 22 / TypeScript)              │
│  • Orchestrateur d'Agents (Plan Mode / Act Mode)                             │
│  • Outils Système (Éditeur de fichiers, Git, Terminal local)                 │
│  • Adaptateur LLM (@deepseek-ai/dsh-llm-pi-ai)                               │
└──────────────────────────────────────┬───────────────────────────────────────┘
                                       │
                                       │ (API OpenAI Compatible / SSE Streams)
                                       │ http://127.0.0.1:8000/v1
                                       ▼
┌──────────────────────────────────────────────────────────────────────────────┐
│                    MOTEUR D'INFÉRENCE LOCAL (UNSLOTH)                        │
│                     llama-server.exe (CUDA 13.1)                             │
│  • FlashAttention-2 (--flash-attn on)                                        │
│  • KV Cache Quantifié 8-bit (--cache-type-k q8_0 --cache-type-v q8_0)        │
└──────────────────────────────────────┬───────────────────────────────────────┘
                                       │
                                       │ (100% Offload VRAM - 64 couches)
                                       ▼
┌──────────────────────────────────────────────────────────────────────────────┐
│                  CARTE GRAPHIQUE NVIDIA RTX 3090 (24 Go VRAM)                │
│  ├── Poids Modèle Qwen 27B UD-Q4_K_XL : ~17.5 Go                             │
│  ├── KV Cache Contexte 32k tokens      : ~5.0 Go                             │
│  └── VRAM Tampon CUDA Run-Time         : ~1.0 Go                             │
│  ═══════════════════════════════════════════════════════════════════════════ │
│  TOTAL VRAM UTILISÉE : ~23.5 Go / 24.0 Go (0% de swap sur la RAM lente !)     │
└──────────────────────────────────────────────────────────────────────────────┘
Enter fullscreen mode Exit fullscreen mode

2. Pourquoi ce Setup ? (RTX 3090 24 Go + UD-Q4_K_XL)

La RTX 3090 (24 Go VRAM) est la carte reine pour le self-hosting de modèles de 27 à 32 milliards de paramètres. Cependant, le choix du format de quantisation est crucial pour ne pas saturer la mémoire et conserver une fenêtre de contexte suffisante pour le développement (32k+ tokens).

Comparatif des Quantisations sur RTX 3090

Format de Quantisation Poids en VRAM (Modèle seul) VRAM résiduelle pour Contexte (KV) Contexte Max Stable Dégradation de Précision Recommandation
UD-Q4_K_XL (Unsloth Dynamic) ~17.5 Go ~6.5 Go 32k - 64k tokens < 0.5% Le Sweet Spot Absolu
UD-Q5_K_M ~20.8 Go ~3.2 Go ~8k - 16k tokens Négligeable Contexte trop limité pour gros projets
UD-Q6_K ~23.5 Go < 0.5 Go < 2k tokens 0% ❌ Risque immédiat d'OOM
Q4_K_M Standard ~17.1 Go ~6.9 Go 32k - 64k tokens ~2.5% Moins précis que l'Unsloth Dynamic

Qu'est-ce que l'Unsloth Dynamic Quant (UD) ?

Plutôt que d'appliquer 4 bits à l'intégralité du réseau de neurones, Unsloth Dynamic Quantization analyse la sensibilité de chaque couche :

  • Les matrices d'attention clés et les couches d'entrée/sortie sont upcastées en Q6_K ou Q8_0.
  • Les couches de calcul intermédiaire feed-forward moins sensibles restent en Q4_K.
  • Résultat : Un modèle 4-bit avec l'intelligence et la cohérence de code d'un modèle 5/6-bit.

3. Comment Obtenir & Générer vos Clés d'Accès

Pour télécharger les modèles optimisés ou authentifier les composants, deux types de clés peuvent être utilisées :

3.1 Clé d'API Unsloth (sk-unsloth-...)

  1. Installez et ouvrez l'application Unsloth Studio.
  2. Allez dans les paramètres de votre compte ou connectez-vous sur la plateforme Unsloth AI.
  3. Copiez votre clé d'API personnelle (préfixée par sk-unsloth-).

3.2 Token Hugging Face (hf_...)

Si vous téléchargez directement les modèles GGUF depuis le Hub Hugging Face :

  1. Connectez-vous sur HuggingFace.co.
  2. Rendez-vous dans Settings > Access Tokens (https://huggingface.co/settings/tokens).
  3. Cliquez sur New token, choisissez le rôle Read, et nommez-le (ex: unsloth-dsh).
  4. Copiez la clé générée (préfixée par hf_).

Ces clés sont à renseigner dans votre fichier .env (UNSLOTH_API_KEY ou HF_TOKEN).


4. Dépannage & Installation d'Unsloth Studio : Le Bug SSLKEYLOGFILE

Si vous installez Unsloth Studio sur Windows, vous pouvez rencontrer une erreur bloquante à l'étape 6 de l'assistant d'installation.

4.1 Symptôme

L'interface d'installation affiche :

Installation failed: llama.cpp prebuilt helper failed unexpectedly (exit code 1).
Enter fullscreen mode Exit fullscreen mode

Dans les fichiers de logs (%LOCALAPPDATA%\Unsloth Studio (Desktop)\install.ps1.log) :

PermissionError: [Errno 13] Permission denied: '\\?\Volume{...}\virtual_file.log'
Enter fullscreen mode Exit fullscreen mode

4.2 Anatomie du Bug

  1. Certains outils système, proxies d'entreprise ou utilitaires de capture réseau définissent une variable d'environnement globale nommée SSLKEYLOGFILE.
  2. Lorsque Python initialise la pile SSL native (ssl.create_default_context() et le module truststore d'Unsloth), il inspecte automatiquement os.environ["SSLKEYLOGFILE"].
  3. Si cette variable pointe vers un volume inaccessible, un shadow copy ou un disque virtuel démonté, la fonction open() interne de Python lève un PermissionError immédiat.
  4. Tout appel HTTPS échoue alors instantanément, empêchant le téléchargement du binaire CUDA llama.cpp.

4.3 La Solution Pas-à-Pas

Pour corriger définitivement le problème, nous assainissons l'environnement avant tout appel réseau :

Étape A : Modifier prebuilt_core.py

Ouvrez le fichier (en remplaçant par votre session utilisateur Windows) :
%USERPROFILE%\.unsloth\studio\unsloth_studio\Lib\site-packages\studio\prebuilt_core.py

Ajoutez la purge de la variable dès le début du fichier :

import os
# Fix critique: Neutraliser SSLKEYLOGFILE s'il pointe vers un volume inaccessible
os.environ.pop("SSLKEYLOGFILE", None)

import sys
import ssl
import urllib.request
# ... reste du fichier inchangé
Enter fullscreen mode Exit fullscreen mode

Étape B : Sécuriser les scripts PowerShell

Dans setup.ps1 et install.ps1 d'Unsloth Studio, ajoutez au tout début :

$env:SSLKEYLOGFILE = $null
Enter fullscreen mode Exit fullscreen mode

Étape C : Téléchargement et validation

Lancez ensuite la finalisation du setup :

powershell -ExecutionPolicy Bypass -File "$HOME\.unsloth\studio\unsloth_studio\Lib\site-packages\studio\setup.ps1"
Enter fullscreen mode Exit fullscreen mode

Les binaires CUDA 13 pour llama.cpp sont alors proprement extraits dans :
%USERPROFILE%\.unsloth\llama.cpp\build\bin\Release\llama-server.exe


5. Installation & Compilation de DeepSeek Harness

DeepSeek Harness est un monorepo TypeScript moderne articulé autour du framework de plugins Cordis.

5.1 Prérequis

  • Node.js >= 22.0.0
  • pnpm >= 9.0.0
  • Git

5.2 Installation Pas-à-Pas

Ouvrez un terminal PowerShell :

# 1. Cloner le dépôt officiel dans votre dossier source (ex: E:\source\deepseek-harness)
git clone https://github.com/deepseek-ai/deepseek-harness E:\source\deepseek-harness
cd E:\source\deepseek-harness

# 2. Installer l'ensemble des dépendances (y compris bindings natifs node-pty, koffi, esbuild)
pnpm install

# 3. Compiler l'ensemble des modules (Core, Client, UI et Web Frontend Vite)
pnpm run build
Enter fullscreen mode Exit fullscreen mode

6. Démarrage du Serveur Local Haute Performance (llama.cpp CUDA 13)

Nous avons automatisé le lancement d'Unsloth llama-server.exe avec les drapeaux d'optimisation optimaux pour la RTX 3090.

6.1 Le Script Dynamique start-unsloth-llama-server.ps1

Le script résout automatiquement les variables d'environnement (%USERPROFILE% et $HOME), nettoie les anciennes instances orphelines pour libérer la VRAM et applique les arguments CUDA optimaux :

powershell -ExecutionPolicy Bypass -File E:\source\deepseek-harness\start-unsloth-llama-server.ps1
Enter fullscreen mode Exit fullscreen mode

6.2 Explication des Arguments Critiques

  • -ngl 99 : Décharge 100% des 64 couches du modèle sur la VRAM de la RTX 3090.
  • --flash-attn on : Active FlashAttention-2 (réduction de 50% de la mémoire d'attention et accélération du traitement des prompts).
  • -c 32768 : Alloue une fenêtre de contexte de 32 768 tokens.
  • --cache-type-k q8_0 --cache-type-v q8_0 : Compresse le cache KV en 8-bit au lieu de 16-bit FP16. Cela économise ~4 Go de VRAM sur 32k tokens sans aucune baisse de qualité mesurable !
  • --hf-token : Permet d'authentifier les requêtes vers les modèles Hugging Face / Unsloth protégés par token.

7. Configuration Automatique & Fichier .env

Pour éviter tout chemin codé en dur, le fichier .env utilise la variable d'environnement système %USERPROFILE% qui s'adapte automatiquement à chaque utilisateur Windows (C:\Users\<VotreNom>) :

# ==============================================================================
# Configuration Environnement DeepSeek Harness & Unsloth Local Server
# ==============================================================================

# Clé d'API Unsloth ou Token Hugging Face
UNSLOTH_API_KEY=sk-unsloth-votre_cle_ici         # <-- À remplacer par votre clé
HF_TOKEN=hf_votre_token_huggingface_ici          # <-- À remplacer par votre token

# Emplacement dynamique du binaire (%USERPROFILE% est résolu automatiquement)
LLAMA_SERVER_PATH=%USERPROFILE%\.unsloth\llama.cpp\build\bin\Release\llama-server.exe

# Modèle (Chemin local .gguf ou identifiant Hugging Face)
LLAMA_MODEL_PATH=%USERPROFILE%\.cache\huggingface\hub\models--unsloth--Qwen3.8-27B-GGUF\snapshots\<hash>\Qwen3.8-27B-UD-Q4_K_XL.gguf
LLAMA_MODEL_HF=unsloth/Qwen3.8-27B-GGUF:UD-Q4_K_XL

# Paramètres réseau du serveur llama.cpp
LLAMA_HOST=127.0.0.1
LLAMA_PORT=8000
LLAMA_CONTEXT_SIZE=32768
LLAMA_THREADS=8
Enter fullscreen mode Exit fullscreen mode

Configuration Automatique Globale (~/.dsh/cordis.patch.yml & ~/.dsh/settings.yaml)

Pour que DeepSeek Harness (Web et CLI) sélectionne automatiquement votre moteur local sans réclamer de clé DEEPSEEK_API_KEY, les fichiers de configuration globale sont placés dans votre dossier utilisateur :

  • %USERPROFILE%\.dsh\cordis.patch.yml
  • %USERPROFILE%\.dsh\settings.yaml
- id: agent-default-model
  config:
    provider: unsloth-local
    model: unsloth/Qwen3.8-27B-GGUF:UD-Q4_K_XL

- id: llm-pi-ai
  config:
    providers:
      unsloth-local:
        displayName: "Unsloth Local Qwen"
        api: openai-completions
        baseURL: http://127.0.0.1:8000/v1
        apiKeyEnv: UNSLOTH_API_KEY
        models:
          - id: "unsloth/Qwen3.8-27B-GGUF:UD-Q4_K_XL"
            name: "Qwen 3.8 27B UD-Q4_K_XL"
            contextWindow: 32768
            maxTokens: 4096
Enter fullscreen mode Exit fullscreen mode

8. Utilisation : Interface Web & Mode CLI (Style Claude Code)

8.1 Option A : L'Interface Web Graphique

  1. Démarrer le serveur Web :
   powershell -ExecutionPolicy Bypass -File E:\source\deepseek-harness\start-deepseek-harness.ps1
Enter fullscreen mode Exit fullscreen mode
  1. Ouvrez http://127.0.0.1:3080/.
  2. Débloquer la saisie : Cliquez sur le bouton 📁 Choose workspace situé au-dessus de la barre de texte (ou sur l'icône + à gauche sous Workspaces) et choisissez le dossier de votre projet.
  3. Le champ de saisie s'active immédiatement ! Vous pouvez alterner entre :
    • Standard Mode : Exécution immédiate avec édition de fichiers et commandes bash/powershell.
    • Plan Mode : Analyse statique approfondie et proposition d'un plan complet pour validation préalable.

8.2 Option B : Le Mode CLI / Terminal (Style Claude Code)

Si vous préférez travailler directement dans votre console PowerShell sans ouvrir de navigateur web, utilisez le script CLI :

powershell -ExecutionPolicy Bypass -File E:\source\deepseek-harness\start-deepseek-cli.ps1 "Inspecte le projet et donne-moi un resume des scripts disponibles"
Enter fullscreen mode Exit fullscreen mode

Le harnais exécute la tâche en sous-processus, inspecte le code source en local sur la RTX 3090, et affiche la réponse directement dans votre terminal :

==========================================================
 Execution DeepSeek Harness CLI (Headless)
 Tache : Inspecte le projet et donne-moi un resume des scripts disponibles
==========================================================
J'ai inspecté scripts/ (~90 scripts) et les entrées package.json. Voici le résumé :

## Orchestration des gates
- run-gates.ts — point d'entrée unique de toutes les gates CI
- run-oxlint.ts — wrapper du linter (pnpm lint)
- clean.ts — nettoyage des sorties de build

## Vérifications statiques (verify-*)
- verify-doc-refs.ts, verify-doc-budgets.ts, verify-md-links.ts
- verify-package-invariants.ts, verify-built-package-invariants.mjs
- verify-cordis-config.ts, verify-export-jsdoc.ts
...
Enter fullscreen mode Exit fullscreen mode

9. Résolution des Pièges & Erreurs Courantes sous Windows

1. Pourquoi PowerShell affiche du texte rouge NativeCommandError ?

  • Explication : En C/C++ et Node, les logs d'information sont écrits sur le flux stderr (flux d'erreur standard). PowerShell intercepte par défaut tout flux stderr et l'affiche en rouge avec l'étiquette NativeCommandError, même si le programme fonctionne parfaitement.
  • Solution : Nos scripts PowerShell appellent directement le binaire Node et gèrent l'expansion dynamique des flux.

2. Erreur Error: dsh: .env sets DSH_HOST

  • Explication : Le chargeur de DeepSeek Harness applique une règle de sécurité stricte : les variables débutant par DSH_* ne doivent pas figurer dans le fichier .env statique car elles définissent le démarrage du runtime.
  • Solution : Dans le fichier .env, conservez uniquement les clés applicatives (UNSLOTH_API_KEY, HF_TOKEN, LLAMA_*).

3. Erreur duplicate loader entry id: llm-pi-ai

  • Explication : Dans Cordis, @deepseek-ai/dsh-llm-pi-ai est déjà déclaré dans le bundle de base. Utiliser une instruction insert crée un doublon d'identifiant.
  • Solution : Appliquer un patch direct sans insert : - id: llm-pi-ai avec la section config: providers: ....

4. Erreur dsh: MISSING_CREDENTIAL: llm-deepseek en CLI

  • Explication : Le preset d'agent par défaut cherche l'API en ligne de DeepSeek.
  • Solution : Configurer - id: agent-default-model dans ~/.dsh/cordis.patch.yml pour cibler unsloth-local.

5. Erreur dsh: PI_AI_ERROR: Context size has been exceeded

  • Explication : Par défaut, llama-server.exe initialise 4 slots parallèles (n_slots = 4). Si vous allouez -c 32768, le moteur divise le contexte en 4 sous-parties de seulement 8 192 tokens par slot. Dès que l'agent lit plusieurs gros fichiers d'un projet, il sature les 8k tokens du slot et lève cette erreur.
  • Solution : Ajouter l'argument --parallel 1 (ou -np 1) dans le script de démarrage pour dédier 100% des 32 768 tokens au slot unique de l'agent.

10. Benchmarks Réels sur RTX 3090

Test de complétion mesuré sur notre instance locale Qwen3.8-27B-UD-Q4_K_XL :

{
  "model": "Qwen3.8-27B-UD-Q4_K_XL.gguf",
  "timings": {
    "prompt_tokens_per_second": 125.37,
    "predicted_tokens_per_second": 38.19
  }
}
Enter fullscreen mode Exit fullscreen mode
  • Débit de lecture / analyse de code : ~125 tokens/seconde
  • Débit de génération de code : ~38 tokens/seconde
  • Occupation VRAM : ~23.5 Go (Poids du modèle 100% offloadés en GPU + KV Cache Q8_0 + FlashAttention-2).

11. Résumé des Commandes & Scripts Clés

Tâche Commande PowerShell
Démarrer le Moteur LLM Local powershell -ExecutionPolicy Bypass -File E:\source\deepseek-harness\start-unsloth-llama-server.ps1
Démarrer l'Interface Web powershell -ExecutionPolicy Bypass -File E:\source\deepseek-harness\start-deepseek-harness.ps1
Exécuter une Commande en CLI powershell -ExecutionPolicy Bypass -File E:\source\deepseek-harness\start-deepseek-cli.ps1 "votre instruction"
Vérifier l'état du serveur LLM curl.exe http://127.0.0.1:8000/v1/models
Vérifier l'état du serveur Web curl.exe -I http://127.0.0.1:3080/

Top comments (0)