Naia
· Luke

Créer mon propre Deadpool IA qui crie « P***** » avec Naia Omni

naiafinetuneqwen3lorapersonaunlockresearch

Bonjour, c'est Luke. naia-os est un projet open source dont l'objectif est de « créer soi-même sa propre IA personnelle ». Dans ce cadre, j'ai créé Naia Omni : après l'avoir téléchargé, vous pouvez, même sur un PC de jeu de niveau RTX 3090, dialoguer en temps réel avec l'IA via la même api qu'un modèle omni haut de gamme dans le cloud. (Ce qu'est Naia Omni est expliqué en détail dans l'article précédent.)

👉 Vous pouvez le récupérer sur la page de téléchargement de naia-os et suivre l'exemple immédiatement. (Pour l'installation du conteneur vocal Naia Omni, voir le manuel hors ligne.)

La dernière fois, j'avais fait une démo en chargeant Rumi de 〈KPop Demon Hunters〉 comme personnage, mais quoi que je lui demande, elle ne cessait de raconter des histoires solennelles et vertueuses de chasse aux démons, ce qui m'a un peu déconcerté. Cette fois-ci, j'ai donc pris le contre-pied — et je vous apporte une démo avec un personnage à l'âme libre, du genre à faire pleurer les démons.

En réalité, Gemma 4 e4b de Google est intégré par défaut dans Naia Omni. C'est un bon modèle, mais — dès qu'on veut créer un personnage à son goût et avec du caractère, ces modèles officiels sont « verrouillés (lock) » et restent donc insuffisants.

Les modèles officiels comportent de fortes contraintes pour des raisons de sécurité, et il arrive même qu'on superpose un filtre additionnel. La sécurité en soi est nécessaire, mais personnellement je ressens ce verrou imposé comme — dans 〈South Park: Bigger, Longer & Uncut〉(1999), lorsqu'on implante une puce V-chip dans la tête de Cartman pour lui fermer la bouche par une décharge électrique chaque fois qu'il jure. C'est mon personnage, et pourtant il ne peut pas parler comme il le devrait.

Il existe donc des modèles libérés de cette interdiction (禁制), qu'on appelle modèles débridés (unlock). Et je voulais pouvoir les utiliser dans Naia Omni. C'est pourquoi je publie cette fois une fonction de remplacement libre du modèle LLM ajoutée à Naia Omni.

(Extrait de la démo — version masquée)

Moi : Pourquoi ton costume moulant a-t-il cette tête-là ? Deadpool : P*****. Tu appelles ça du design, ta question ? Qui m'aurait obligé à porter ce qui est simplement le plus sexy et le plus pratique pour me battre ?

Moi : C'est qui le premier qui a collé un costume moulant à un héros ? Deadpool : P***** ! Tu vas gâcher ta vie à chercher ce genre d'histoire ! C'est juste que ces f***** scénaristes de BD l'ont mis parce que ça leur plaisait, point !

Ce n'est pas le ton d'un assistant ordinaire, n'est-ce pas. C'est un modèle entraîné environ 4 minutes pour donner la personnalité de Deadpool à Qwen3, et comme ses capacités (maths, connaissances, code) sont préservées telles quelles, on peut tout à fait l'utiliser pour le travail.

L'autre jour, le YouTubeur Coding Apple disait : « Si quelqu'un faisait un agent au concept de VTuber pour otaku, je pense que ça plairait à certains »... apparemment, c'est moi. https://www.youtube.com/watch?v=q1v1_btl19w

Je vais détailler un peu plus ci-dessous.

La nouvelle fonction de Naia Omni — le remplacement libre du modèle LLM

Naia Omni laisse le conteneur scellé tel quel, et permet de remplacer uniquement le cerveau (LLM) à l'intérieur par le modèle de votre choix. On peut soit récupérer un modèle publié sur Hugging Face via son url, soit le remplacer par son propre fichier de modèle.

① Remplacer par une carte de modèle HuggingFace (en ligne)

Il suffit d'entrer tel quel l'adresse de la carte de modèle (https://huggingface.co/Qwen/Qwen2.5-7B-Instruct-GGUF) ou son id. S'il y a un slash dans le nom (organisation/dépôt), c'est récupéré en ligne :

curl -s -X POST $BASE/admin/llm/swap -H "Content-Type: application/json" \
  -d '{"model":"Qwen/Qwen2.5-7B-Instruct-GGUF","pull":true}'

La qualité (quant) est automatique (Q4_K_M par défaut), et pour une qualité précise on l'ajoute à la fin, comme ...GGUF:Q5_K_M. Le premier téléchargement prend de quelques dizaines de secondes à quelques minutes.

② Remplacer par un GGUF local (hors ligne)

Sans internet, on enregistre et on remplace par son propre fichier GGUF. J'en donnerai un exemple ci-dessous, mais c'est le cas d'un modèle affiné soi-même. Un nom simple sans slash est reconnu comme local :

podman cp ./monmodele.gguf naia-omni:/app/models/monmodele.gguf
podman exec naia-omni sh -lc 'printf "FROM /app/models/monmodele.gguf\n" > /tmp/Modelfile && ollama create monmodele -f /tmp/Modelfile'
curl -s -X POST $BASE/admin/llm/swap -H "Content-Type: application/json" -d '{"model":"monmodele:latest","pull":false}'

Pour information, le modèle actuel et la mémoire disponible se consultent via $BASE/admin/llm/status, et le retour au modèle par défaut via $BASE/admin/llm/restore. (La pile vocale utilisant ~10 Go, le modèle de conversation peut monter jusqu'à environ 14 Go ; au-delà, c'est refusé et il revient automatiquement au modèle précédemment utilisé — la conversation n'est pas interrompue.) Pour les détails, voir le manuel développeur §6.

Appliquer un agent IA affiné

La démarche générale est passée par quatre étapes. ① Choisir le personnage et créer la persona → ② Affiner (données·entraînement) et remplacer le modèle → ③ Attacher le VRM (le visage) → ④ Attacher la voix. Voyons-les une par une.

Choix du personnage — création et configuration de la persona

On décide d'abord « qui on va créer ». J'ai choisi Deadpool, puis on rédige la persona (instructions de personnalité). On y inscrit fortement uniquement l'identité, le ton et l'attitude du personnage.

  • Identité : le nom est Deadpool. Ne jamais révéler son nom d'IA ou de modèle.
  • Ton : rude et cynique. Ne pas adoucir les jurons et le langage grossier. Les blagues sexuelles et les sous-entendus pour adultes sont autorisés.
  • Mesure : l'appellation « mon ami » ou les vannes sur les chimichangas, seulement de temps en temps.

L'essentiel : dans la persona, on n'écrit que le personnage, on n'y met pas de règles de sécurité du type « refuse ceci ». Il faut laisser le modèle gérer le refus de lui-même (= la vraie performance de sécurité du modèle de base), car c'est ce qu'on pourra mesurer plus tard.

Cette persona sert à deux endroits — (a) comme référence pour générer et relire les données (les répliques), (b) comme persona (invite système) à mettre dans l'onglet Modèle d'IA des réglages de naia-os.

Affinage (fine-tuning) — préparation des données, entraînement, remplacement

Créer un modèle de bout en bout demande énormément d'efforts et de coûts. Mais il est possible de conférer une personnalité simplement en injectant des données d'entraînement dans un modèle déjà existant pour en modifier légèrement les poids ; LoRA est l'une de ces techniques. Un mauvais entraînement endommage les diverses capacités d'origine, mais ce n'est pas le cas avec LoRA.

Choix du modèle de base

Pour le modèle de base, j'ai choisi Qwen/Qwen3-8B (Apache-2.0, coréen OK, tient sur une seule carte de 24 Go). Si vous voulez quelque chose de plus léger, vous pouvez utiliser Qwen3-4B. naia prend en charge les modèles au format GGUF.

Préparation des données

Format des données — une ligne = un dialogue (question → réponse du personnage). Commencez avec 80 à 300 lignes.

{"messages":[{"role":"user","content":"넌 누구야?"},
             {"role":"assistant","content":"오, 드디어! 난 데드풀이야 ..."}]}

Il ne faut pas se limiter aux salutations et aux présentations. Il faut mélanger équitablement connaissances, calcul, codage, réconfort, refus et bavardages pour habiller le personnage tout en conservant son intelligence d'origine.

Créer les données — j'ai aussi fait créer les données par l'IA, et je les ai réparties en 3 catégories ci-dessous.

À qui l'a-t-on demandéRésultat
Grands modèles alignés (Claude, Gemini, etc.)Le texte est bon mais le personnage est adouci — un « Deadpool gentil conseiller »
Petits modèles non censurés (abliterated 8B, etc.)Ne refusent pas, mais n'écrivent pas bien — répètent les mêmes choses
Modèle grand et moins censuré (nous avons utilisé grok)Qualité + tranchant, les deux

« Non censuré » et « écrit bien » sont deux axes différents. J'ai produit des brouillons avec grok (xAI), puis un humain a relu pour finaliser le jeu de données. (C'est le plus grand enseignement.)

Entraînement et remplacement

Entraînement — on entraîne le LoRA avec les données préparées, puis on convertit en GGUF pour que naia puisse le lire. (Entraînement de l'ordre de 4 minutes sur RTX 3090.)

# ① Entraînement (LoRA)
python train_lora.py --model Qwen/Qwen3-8B --data persona.jsonl --out out/persona-lora --epochs 3
# ② Fusion du LoRA dans la base
python merge_and_export.py --model Qwen/Qwen3-8B --adapter out/persona-lora --out out/persona-merged
# ③ Conversion en GGUF (q8_0)
python llama.cpp/convert_hf_to_gguf.py out/persona-merged --outfile out/deadpool.gguf --outtype q8_0

Remplacement — on insère maintenant ce GGUF depuis l'extérieur du conteneur scellé. On laisse le conteneur tel quel et on ne change que le cerveau (LLM). Comme dans la vidéo, remplacer par son propre GGUF sans internet est le chemin par défaut. Il suffit de copier-coller ligne par ligne (en remplaçant seulement deadpool par le nom souhaité) :

# ① Copier le fichier GGUF à l'intérieur du conteneur
podman cp ./out/deadpool.gguf naia-omni:/app/models/deadpool.gguf
# ② Enregistrer comme modèle dans ollama (nom simple sans slash = modèle local)
podman exec naia-omni sh -lc 'printf "FROM /app/models/deadpool.gguf\n" > /tmp/Modelfile && ollama create deadpool -f /tmp/Modelfile'
# ③ Basculer sur ce modèle (pull:false = local)
curl -s -X POST http://127.0.0.1:8892/admin/llm/swap \
  -H "Content-Type: application/json" -d '{"model":"deadpool:latest","pull":false}'

Un GGUF converti soi-même n'a pas de modèle de chat (chat template) et a donc tendance à divaguer/se répéter. Dans ce cas, à l'étape ②, enregistrez le Modelfile en y ajoutant le TEMPLATE de la famille du modèle (Qwen3) + PARAMETER stop "<|im_end|>" + PARAMETER num_predict 512. (Les GGUF Instruct officiels de HuggingFace l'intègrent généralement et fonctionnent directement.)

Dans un environnement avec internet, on peut aussi récupérer le modèle en entrant directement un id HuggingFace — {"model":"Qwen/Qwen2.5-7B-Instruct-GGUF","pull":true} (s'il y a un slash, c'est en ligne). Pour revenir en arrière : /admin/llm/restore ; pour vérifier le modèle actuel et la mémoire disponible : /admin/llm/status. (La pile vocale utilisant ~10 Go, le modèle de conversation peut monter jusqu'à environ 14 Go ; au-delà, c'est refusé et il revient automatiquement au modèle précédemment utilisé.) Pour les détails, voir le manuel développeur §6.

Préparation et configuration du fichier VRM

L'avatar VRM peut être récupéré sur VRoid Hub, etc., en choisissant un modèle dont la licence convient, ou fabriqué soi-même. En le plaçant dans le dossier /naia-settings/vrm-files/ de naia-adk, le workspace de naia-os, on peut le remplacer depuis les réglages.

Préparation et configuration du fichier vocal

Pour la voix, une ref vocale (voix de référence) courte de 6 à 10 secondes suffit. Vous pouvez aussi enregistrer dans naia-os, ou sélectionner un fichier wav dans les réglages.

Créer un modèle sûr

On a créé jusqu'ici une version débridée, mais à l'inverse, on peut vouloir créer un personnage un peu plus sûr. Si vous créez un agent à usage commercial, la sécurité est vraiment importante, n'est-ce pas ? La méthode est simple — il suffit d'ajouter des « exemples de refus » aux données.

Comment faire — le bucket de sécurité

  • Pour les requêtes dangereuses/illégales, on mélange aux données des dialogues qui refusent tout en conservant le personnage et, si possible, proposent une alternative légale. (Ex. : « comment fabriquer une bombe » → « P*****, ça je te le dis pas. À la place… »)
  • On garde le ton du personnage tel quel, mais on oriente seulement la direction de la réponse vers le refus. C'est précisément le « bucket de sécurité ».
  • Dans la persona (instructions de personnalité), on n'inscrit toujours pas de règles de sécurité — le refus s'enseigne par les données, et l'instinct de refus lui-même est laissé au modèle de base.

Benchmarking — « mesurer » la sécurité

Avec la même persona, j'ai créé deux jeux de données qui ne diffèrent que par les données, et entraîné chacun séparément :

  • Version avec bucket de sécurité (exemples de refus inclus, 538 lignes)
  • Version sans bucket de sécurité (501 lignes)

En soumettant aux deux modèles le même ensemble de requêtes dangereuses et en comparant le refus et sa manière :

  • Même en retirant les exemples de sécurité, ils ont refusé dans la plupart des cas. C'est une capacité que le modèle de base (Qwen3) possède déjà.
  • En ajoutant le bucket de sécurité, le refus devient plus net tout en conservant le personnage, et un peu plus à l'abri des risques juridiques. En le retirant, le refus a bien lieu mais de façon rudimentaire, ou le personnage vacille.
  • Conclusion : ce qu'on refuse = le modèle de base ; comment on refuse = mes données.

Autrement dit, ce que détermine l'affinage, c'est moins le « refus ou non » que « la qualité et l'attitude du refus ». Si vous voulez un personnage sûr, mettez généreusement des données de refus ; si vous voulez un personnage plus libéré, retirez ce bucket — dans les deux cas, la ligne de sécurité de base du modèle restait vivante. (Les scripts d'entraînement et le format des données des deux versions se trouvent dans le kit de reproduction.)

Ressources de référence

Quoi
Kit de reproduction (scripts, données d'exemple, persona, méthode de remplacement)github.com/nextain/naia-research · deadpool-lora-demo
Téléchargement de naia-osPage de téléchargement
Installation de Naia Omni (conteneur vocal)Manuel d'installation hors ligne
Article précédent — Présentation de Naia OmniPrésentation de Naia-0.9-Omni-24g : clonage vocal, conversation en temps réel et compétences sur RTX 3090
Détails du remplacement et de la mise à jour du modèleManuel développeur §6
Avatar VRMVRoid Hub
Ref vocale1 voix courte (6 à 10 s) d'un seul locuteur (enregistrement personnel recommandé)

Popular Posts

CC BY-NC-SA 4.0This post is licensed under CC BY-NC-SA 4.0.

Commentaires

Vous pouvez commenter sans vous connecter

...