GitHub avatar

Fox's Blog

Luna Protocol: Why I fine-tuned a 1.5B model on 50k Discord samples and why few-shot priming changed everything

A smaller model trained on less data can outperform a bigger one -- if you know how to prime it. Here is why Luna Protocol switched from a 3B Hermes to a 1.5B Qwen fine-tune, and why few-shot priming became the real game-changer.

Luna Protocol: Why I fine-tuned a 1.5B model on 50k Discord samples and why few-shot priming changed everything

In the first article, I built a Discord bot that simulates a human being -- sleep, typos, hesitations, forgetfulness, spontaneous messages. The behavioral system was solid. The LLM behind it was a 3B Hermes model, quantized to Q8_0, eating 3GB of VRAM.

It worked. But it was overkill.

A Discord bot does not need a 3B parameter model to say "nm just chillin, u". What it needs is style consistency -- the ability to match a specific conversational tone, message after message, without drifting into corporate assistant mode. And it turns out, a smaller model trained on less data, primed with a few examples, does that better than a bigger model brute-forcing its way through a system prompt.

This article is about the official Luna Protocol models: why they exist, why they are 1.5B instead of 3B, why 50k training samples instead of 7.3M, and why few-shot priming went from a nice-to-have to the core of the whole approach.


The problem with the 3B model

The original setup used Discord-Micae-Hermes-3-3B.Q8_0.gguf -- a 3B parameter model fine-tuned on Discord data. It produced good responses, but:

Metric Hermes-3-3B Q8_0 Target
VRAM usage ~3 GB < 1 GB
Token generation ~30 tok/s ~60+ tok/s
Model file size ~3.2 GB < 1 GB
Cold start time ~8s ~3s

For a bot running 24/7 on a modest server, 3GB of VRAM is a lot. And the generation speed -- while fine for occasional messages -- felt sluggish during burst responses or when multiple channels were active.

The question was: can we get the same Discord-Dialogues style with half the parameters?


The fine-tuning decision: why 50k, not 7.3M

The Discord-Dialogues dataset contains 7.3M exchanges and 17M turns. It is a massive corpus of real Discord conversations. The obvious approach would be to train on the full dataset.

I did the opposite. I trained on 50,000 samples -- less than 1% of the available data.

Here is why: the size of the training set directly affects how much the model overfits to its training distribution.

A model trained on 7.3M examples learns a very specific statistical distribution of conversations. It becomes excellent at reproducing that distribution, but it also becomes rigid -- it has less flexibility to adapt to new patterns provided at inference time.

A model trained on 50k examples learns the general tone and register of Discord conversations (informal, short-form, abbreviations, lowercase), but it retains enough flexibility to be steered by in-context examples. The few-shot examples do not fight against a massive learned distribution -- they complement a lighter one.

This is the core insight: limited training data makes few-shot priming more efficient.


The model: technical details

The Luna Protocol model is a QLoRA fine-tune of Qwen2.5-1.5B-Instruct:

Parameter Value
Base model unsloth/Qwen2.5-1.5B-Instruct-bnb-4bit
Method QLoRA (4-bit)
LoRA rank r=16, lora_alpha=16
Target modules q/k/v/o_proj, gate/up/down_proj
Trainable params 18,464,768 / 1,562,179,072 (1.18%)
Training data ~50,000 examples (Discord-Dialogues subset)
Filter 8-512 tokens per sample
Epochs 2-3
Hardware Kaggle T4
Framework Unsloth

The dataset is a preprocessed fork of Discord-Dialogues, filtered to contain only clean user/assistant turns -- no system messages, no metadata, no bot commands. This is important for later.

Available quantizations

File Quantization Size Notes
Luna-Protocol-1.5B-Fine-Tuned-Qwen2.5.Q2_K.gguf Q2_K 676 MB Noticeably degraded -- not recommended
Luna-Protocol-1.5B-Fine-Tuned-Qwen2.5.Q4_K_M.gguf Q4_K_M 986 MB Good size/quality balance (recommended)
Luna-Protocol-1.5B-Fine-Tuned-Qwen2.5.Q8_0.gguf Q8_0 1.65 GB Best style fidelity

The recommended model is Q4_K_M -- under 1GB, fast, and preserves the conversational style well. Q2_K degrades too much on a model this small. Q8_0 is the best quality but uses 68% more memory.


The few-shot priming breakthrough

Here is the part that changed everything.

The HuggingFace model card has a warning:

With a bare prompt and no priming, this model tends to fall back on Qwen's default assistant tone. A short few-shot prime makes a large difference.

This is not a bug -- it is a direct consequence of how the training data was structured.

Why system prompts alone do not work

The Discord-Dialogues training data contains only user/assistant turns. There are no system-role examples in the training set. The model was never trained to follow system prompts as style directives.

When you give it a system prompt like "Your name is Luna, talk casually", it hears the instruction but does not have a strong learned pattern for how to translate that into output. It falls back to Qwen's default: helpful, structured, slightly formal.

Why few-shot examples work

When you inject example conversations in the same ChatML format the model was trained on (using the user/assistant turn structure), something clicks. The model recognizes the pattern from its training data and aligns its output to match.

Here is what a few-shot prime looks like in practice:

few_shot_examples:
  - user: "yo whats good"
    assistant: "nm just chillin, u"
  - user: "bored af"
    assistant: "lol same energy fr"
  - user: "hey how are you"
    assistant: "im doing pretty good tbh, just vibing"

These examples are injected after the system prompt and before the real conversation. The model sees them as part of the conversation history, not as instructions. This is a critical distinction -- it is not being told to be casual, it is being shown what casual looks like.

Before and after

Without few-shot priming (bare system prompt):

User: yo whats good
Bot: Hello! I am doing well, thank you for asking. How can I assist you today?

With few-shot priming (3 examples):

User: yo whats good
Bot: nm just chillin, u

The difference is stark. The model does not just produce different words -- it adopts the entire register: lowercase, abbreviations, casual tone, short responses. It matches the style of the examples, not the style of Qwen's training data.


Memory and speed: the concrete numbers

The switch from Hermes-3-3B to Luna-Protocol-1.5B delivers measurable gains:

Metric Hermes-3-3B Q8_0 Luna-Protocol Q4_K_M Improvement
VRAM usage ~3 GB ~986 MB 67% less
Model file size ~3.2 GB ~986 MB 69% smaller
Token generation ~30 tok/s ~60+ tok/s 2x faster
Cold start ~8s ~3s 62% faster
Context window 8192 8192 Same

Why the speed gain is real

Smaller models are not just "less slow" -- they are fundamentally faster for inference. With 1.5B parameters instead of 3B:

  • Fewer matrix multiplications per token: the attention layers, FFN layers, and output projection all scale linearly with parameter count
  • Better cache utilization: the smaller model fits more of its weights in L2/L3 cache
  • Lower memory bandwidth pressure: fewer bytes to read from VRAM per token

On a modest CPU-only setup (2 cores, no GPU), the 1.5B model generates tokens at roughly 2x the speed of the 3B model. This is the difference between "feels like a bot" and "feels like a person typing".

Prompt caching amplifies the advantage

Luna Protocol uses llama-server with prompt caching enabled (--cache-reuse 256). This means:

  1. The first message in a session pays the full prompt processing cost (system prompt + few-shot examples + user message)
  2. Subsequent messages only process the new tokens -- the cached prefix is reused
  3. With 5 few-shot examples (~50-150 tokens), the overhead is negligible after the first request

The few-shot examples are effectively "free" after the first message in a session. The model gets style guidance at zero marginal cost.


The implementation: how it works in code

The few-shot system in Luna Protocol is clean and minimal. Three files handle everything:

1. Configuration (config.yml)

few_shot_enabled: true
few_shot_examples:
  - user: "yo whats good"
    assistant: "nm just chillin, u"
  - user: "bored af"
    assistant: "lol same energy fr"
  - user: "hey how are you"
    assistant: "im doing pretty good tbh, just vibing"
  - user: "whats up"
    assistant: "yooo not much, what about you"
  - user: "how was your day"
    assistant: "it was alright, nothing crazy happened lol"

Config is hot-reloadable. Change the examples, save, and the bot picks up the new style immediately -- no restart needed.

2. Formatting and injection (src/core/few-shot.ts)

The formatFewShotExamples() function converts the YAML examples into ChatML message objects:

export function formatFewShotExamples(
  examples: FewShotExample[],
  username = "user"
): Array<{ role: "user" | "assistant"; content: string }> {
  const messages = [];
  for (const example of examples) {
    messages.push({ role: "user", content: `${username}: ${example.user}` });
    messages.push({ role: "assistant", content: example.assistant });
  }
  return messages;
}

The injectFewShotIntoConversation() function places them right after the system prompt:

export function injectFewShotIntoConversation(
  messages: Message[],
  fewShotMessages: Message[]
): Message[] {
  const systemMessage = messages[0];
  const userMessages = messages.slice(1);
  return [systemMessage, ...fewShotMessages, ...userMessages];
}

3. Integration (src/core/llm-client.ts)

Before every LLM call, the few-shot examples are injected if enabled:

let finalMessages = messages;
if (FEW_SHOT_ENABLED && FEW_SHOT_EXAMPLES.length > 0) {
  const fewShotMessages = formatFewShotExamples(FEW_SHOT_EXAMPLES);
  finalMessages = injectFewShotIntoConversation(messages, fewShotMessages);
}

The model receives: [system_prompt] + [few_shot_examples] + [conversation_history]


Keeping the Discord-Dialogues style

The original Discord-Dialogues dataset has a very specific conversational signature:

  • Short messages: average 32.8 tokens per turn
  • Informal register: abbreviations, lowercase, no punctuation
  • Rapid back-and-forth: multiple short exchanges rather than long monologues
  • Natural imperfections: typos, "lol", "fr", "ngl", "tbh"

The Luna-Protocol model preserves this style through two mechanisms:

1. Fine-tuning shifts the base distribution

The 50k training samples teach the model the statistical fingerprint of Discord conversations. It learns that responses are typically short, lowercase, and informal. This shifts the model's default output away from Qwen's helpful-assistant mode.

2. Few-shot priming locks it in

The few-shot examples reinforce the exact patterns the model learned during fine-tuning. They act as a style anchor -- even if the model drifts slightly toward formal tone during a long conversation, the examples in context keep pulling it back.

The combination is more powerful than either mechanism alone:

  • Fine-tuning without few-shot: the model is generally casual but inconsistent
  • Few-shot without fine-tuning: the model tries to follow examples but keeps reverting to assistant mode
  • Fine-tuning + few-shot: the model is consistently in character

The philosophy: smaller model, smarter prompting

The conventional wisdom in LLM deployment is "bigger is better". More parameters, more training data, more VRAM. Luna Protocol takes the opposite approach:

  • 1.5B instead of 3B: half the parameters, half the memory, twice the speed
  • 50k samples instead of 7.3M: less training data, more flexibility for in-context learning
  • Few-shot priming instead of system prompts: show the model what you want, do not just tell it

This is not just a technical optimization -- it is a design philosophy. A Discord bot does not need to be a general-purpose assistant. It needs to say "nm just chillin, u" consistently, quickly, and without eating your server's entire VRAM budget.

The result: a bot that runs on a $5/month VPS, generates tokens fast enough to feel like real-time typing, and maintains a consistent personality through a combination of fine-tuning and few-shot priming that is greater than the sum of its parts.


Setup

Download the model

npm run download-model
# Downloads Luna-Protocol-1.5B-Fine-Tuned-Qwen2.5.Q4_K_M.gguf

Or manually from HuggingFace.

Configure

# config.yml
llama_model_path: "./models/Luna-Protocol-1.5B-Fine-Tuned-Qwen2.5.Q4_K_M.gguf"
few_shot_enabled: true
few_shot_examples:
  - user: "yo whats good"
    assistant: "nm just chillin, u"
  - user: "bored af"
    assistant: "lol same energy fr"
  - user: "hey how are you"
    assistant: "im doing pretty good tbh, just vibing"

Run

npm run dev                    # dev (hot reload)
npm run build && npm start     # production
./start.sh                     # PM2 (production with llama-server)

Conclusion

The Luna Protocol models prove that for style-specific conversational AI, less is more. A 1.5B model trained on 50k carefully chosen samples, primed with a few examples, outperforms a 3B model trained on millions of examples -- at a fraction of the memory cost and twice the generation speed.

Few-shot priming is not just a nice-to-have for small models. It is the mechanism that makes them viable for real-time conversational applications. The examples do not just "help" -- they fundamentally change how the model behaves, by matching the exact format it was trained on.

The code is open source, the model is on HuggingFace, and the dataset is public. If you want to build a conversational bot that feels human, the recipe is: small model, limited fine-tuning, strong few-shot priming.

Resource Link
GitHub repository fox3000foxy/luna-protocol-project
Model (HuggingFace) fox3000foxy/Luna-Protocol-1.5B-Discord-Dialogues
Dataset Discord-Dialogues
First article Luna Protocol: I created an autonomous Discord bot

Luna Protocol : pourquoi j'ai fine-tuné un modèle de 1,5 milliard de paramètres sur 50k échantillons Discord, et pourquoi le few-shot priming a tout changé

Un modèle plus petit entraîné sur moins de données peut surpasser un modèle plus gros -- à condition de savoir bien l'amorcer. Voici pourquoi Luna Protocol est passé d'un Hermes 3B à un fine-tune Qwen 1,5B, et pourquoi le few-shot priming est devenu le vrai facteur de progrès.

Luna Protocol : pourquoi j'ai fine-tuné un modèle de 1,5 milliard de paramètres sur 50k échantillons Discord, et pourquoi le few-shot priming a tout changé

Dans le premier article, j'ai construit un bot Discord qui simule un être humain -- sommeil, fautes de frappe, hésitations, oublis, messages spontanés. Le système comportemental tenait la route. Le LLM derrière tout ça était un modèle Hermes de 3 milliards de paramètres, quantifié en Q8_0, consommant 3 Go de VRAM.

Ça fonctionnait. Mais c'était surdimensionné.

Un bot Discord n'a pas besoin d'un modèle de 3 milliards de paramètres pour dire « nm just chillin, u ». Ce dont il a besoin, c'est de cohérence stylistique -- la capacité à conserver un ton conversationnel précis, message après message, sans dériver vers un mode « assistant corporate ». Et il s'avère qu'un modèle plus petit, entraîné sur moins de données et amorcé avec quelques exemples, y parvient mieux qu'un modèle plus gros qui force le passage via un simple prompt système.

Cet article porte sur les modèles officiels de Luna Protocol : pourquoi ils existent, pourquoi 1,5B plutôt que 3B, pourquoi 50k échantillons d'entraînement plutôt que 7,3M, et pourquoi le few-shot priming est passé du statut de « bonus sympa » à celui de cœur de toute l'approche.


Le problème avec le modèle 3B

La configuration d'origine utilisait Discord-Micae-Hermes-3-3B.Q8_0.gguf -- un modèle de 3 milliards de paramètres fine-tuné sur des données Discord. Il produisait de bonnes réponses, mais :

Métrique Hermes-3-3B Q8_0 Objectif
Utilisation VRAM ~3 Go < 1 Go
Génération de tokens ~30 tok/s ~60+ tok/s
Taille du fichier modèle ~3,2 Go < 1 Go
Temps de démarrage à froid ~8s ~3s

Pour un bot tournant 24/7 sur un serveur modeste, 3 Go de VRAM, c'est beaucoup. Et la vitesse de génération -- correcte pour des messages occasionnels -- semblait poussive lors de réponses en rafale ou avec plusieurs canaux actifs.

La question était : peut-on obtenir le même style Discord-Dialogues avec deux fois moins de paramètres ?


La décision de fine-tuning : pourquoi 50k, pas 7,3M

Le jeu de données Discord-Dialogues contient 7,3M d'échanges et 17M de tours de parole. C'est un corpus massif de vraies conversations Discord. L'approche évidente aurait été d'entraîner sur la totalité du jeu de données.

J'ai fait l'inverse. J'ai entraîné sur 50 000 échantillons -- moins de 1 % des données disponibles.

Voici pourquoi : la taille du jeu d'entraînement affecte directement le degré de surapprentissage du modèle vis-à-vis de sa distribution d'entraînement.

Un modèle entraîné sur 7,3M d'exemples apprend une distribution statistique très spécifique des conversations. Il devient excellent pour reproduire cette distribution, mais il devient aussi rigide -- il a moins de marge pour s'adapter à de nouveaux motifs fournis au moment de l'inférence.

Un modèle entraîné sur 50k exemples apprend le ton et le registre général des conversations Discord (informel, court, abréviations, minuscules), mais il conserve assez de flexibilité pour être piloté par des exemples en contexte. Les exemples few-shot ne luttent pas contre une distribution massive déjà apprise -- ils viennent compléter une distribution plus légère.

C'est l'intuition centrale : des données d'entraînement limitées rendent le few-shot priming plus efficace.


Le modèle : détails techniques

Le modèle Luna Protocol est un fine-tune QLoRA de Qwen2.5-1.5B-Instruct :

Paramètre Valeur
Modèle de base unsloth/Qwen2.5-1.5B-Instruct-bnb-4bit
Méthode QLoRA (4-bit)
Rang LoRA r=16, lora_alpha=16
Modules ciblés q/k/v/o_proj, gate/up/down_proj
Paramètres entraînables 18 464 768 / 1 562 179 072 (1,18 %)
Données d'entraînement ~50 000 exemples (sous-ensemble de Discord-Dialogues)
Filtre 8-512 tokens par échantillon
Époques 2-3
Matériel Kaggle T4
Framework Unsloth

Le jeu de données est un fork prétraité de Discord-Dialogues, filtré pour ne conserver que des tours user/assistant propres -- pas de messages système, pas de métadonnées, pas de commandes de bot. C'est important pour la suite.

Quantifications disponibles

Fichier Quantification Taille Remarques
Luna-Protocol-1.5B-Fine-Tuned-Qwen2.5.Q2_K.gguf Q2_K 676 Mo Nettement dégradé -- déconseillé
Luna-Protocol-1.5B-Fine-Tuned-Qwen2.5.Q4_K_M.gguf Q4_K_M 986 Mo Bon compromis taille/qualité (recommandé)
Luna-Protocol-1.5B-Fine-Tuned-Qwen2.5.Q8_0.gguf Q8_0 1,65 Go Meilleure fidélité stylistique

Le modèle recommandé est Q4_K_M -- moins d'1 Go, rapide, et il préserve bien le style conversationnel. Le Q2_K se dégrade trop pour un modèle de cette taille. Le Q8_0 offre la meilleure qualité mais consomme 68 % de mémoire en plus.


La percée du few-shot priming

Voici la partie qui a tout changé.

La fiche du modèle sur HuggingFace comporte un avertissement :

Avec un prompt nu et sans amorçage, ce modèle a tendance à retomber dans le ton par défaut « assistant » de Qwen. Un court amorçage few-shot fait une grande différence.

Ce n'est pas un bug -- c'est une conséquence directe de la façon dont les données d'entraînement ont été structurées.

Pourquoi les prompts système seuls ne fonctionnent pas

Les données d'entraînement Discord-Dialogues ne contiennent que des tours user/assistant. Il n'y a aucun exemple de rôle système dans le jeu d'entraînement. Le modèle n'a jamais été entraîné à suivre des prompts système comme directives de style.

Quand on lui donne un prompt système du type « Tu t'appelles Luna, parle de façon décontractée », il entend l'instruction mais n'a pas de motif appris solide pour la traduire en sortie. Il retombe alors sur le comportement par défaut de Qwen : serviable, structuré, légèrement formel.

Pourquoi les exemples few-shot fonctionnent

Quand on injecte des exemples de conversation dans le même format ChatML que celui utilisé à l'entraînement (avec la structure de tours user/assistant), quelque chose se déclenche. Le modèle reconnaît le motif issu de son entraînement et aligne sa sortie en conséquence.

Voici à quoi ressemble un amorçage few-shot en pratique :

few_shot_examples:
  - user: "yo whats good"
    assistant: "nm just chillin, u"
  - user: "bored af"
    assistant: "lol same energy fr"
  - user: "hey how are you"
    assistant: "im doing pretty good tbh, just vibing"

Ces exemples sont injectés après le prompt système et avant la vraie conversation. Le modèle les perçoit comme faisant partie de l'historique de conversation, pas comme des instructions. C'est une distinction essentielle -- on ne lui dit pas d'être décontracté, on lui montre à quoi ça ressemble.

Avant / après

Sans amorçage few-shot (prompt système nu) :

User: yo whats good
Bot: Hello! I am doing well, thank you for asking. How can I assist you today?

Avec amorçage few-shot (3 exemples) :

User: yo whats good
Bot: nm just chillin, u

La différence est flagrante. Le modèle ne produit pas juste des mots différents -- il adopte tout le registre : minuscules, abréviations, ton décontracté, réponses courtes. Il calque le style des exemples, pas celui des données d'entraînement de Qwen.


Mémoire et vitesse : les chiffres concrets

Le passage de Hermes-3-3B à Luna-Protocol-1.5B apporte des gains mesurables :

Métrique Hermes-3-3B Q8_0 Luna-Protocol Q4_K_M Amélioration
Utilisation VRAM ~3 Go ~986 Mo 67 % de moins
Taille du fichier modèle ~3,2 Go ~986 Mo 69 % plus petit
Génération de tokens ~30 tok/s ~60+ tok/s 2x plus rapide
Démarrage à froid ~8s ~3s 62 % plus rapide
Fenêtre de contexte 8192 8192 Identique

Pourquoi le gain de vitesse est réel

Les modèles plus petits ne sont pas juste « un peu moins lents » -- ils sont fondamentalement plus rapides en inférence. Avec 1,5B de paramètres au lieu de 3B :

  • Moins de multiplications matricielles par token : les couches d'attention, les couches FFN et la projection de sortie évoluent toutes linéairement avec le nombre de paramètres
  • Meilleure utilisation du cache : le modèle plus petit fait tenir davantage de ses poids dans le cache L2/L3
  • Moins de pression sur la bande passante mémoire : moins d'octets à lire depuis la VRAM par token

Sur une configuration modeste, CPU seul (2 cœurs, pas de GPU), le modèle 1,5B génère des tokens à environ 2 fois la vitesse du modèle 3B. C'est la différence entre « ça sent le bot » et « on dirait une vraie personne en train de taper ».

Le cache de prompt amplifie l'avantage

Luna Protocol utilise llama-server avec le cache de prompt activé (--cache-reuse 256). Cela signifie que :

  1. Le premier message d'une session paie le coût complet du traitement du prompt (prompt système + exemples few-shot + message utilisateur)
  2. Les messages suivants ne traitent que les nouveaux tokens -- le préfixe mis en cache est réutilisé
  3. Avec 5 exemples few-shot (~50-150 tokens), le surcoût devient négligeable après la première requête

Les exemples few-shot deviennent en pratique « gratuits » après le premier message d'une session. Le modèle bénéficie d'un guidage de style à coût marginal nul.


L'implémentation : comment ça fonctionne en code

Le système few-shot de Luna Protocol est propre et minimal. Trois fichiers gèrent tout.

1. Configuration (config.yml)

few_shot_enabled: true
few_shot_examples:
  - user: "yo whats good"
    assistant: "nm just chillin, u"
  - user: "bored af"
    assistant: "lol same energy fr"
  - user: "hey how are you"
    assistant: "im doing pretty good tbh, just vibing"
  - user: "whats up"
    assistant: "yooo not much, what about you"
  - user: "how was your day"
    assistant: "it was alright, nothing crazy happened lol"

La configuration est rechargeable à chaud. On modifie les exemples, on enregistre, et le bot adopte immédiatement le nouveau style -- sans redémarrage.

2. Formatage et injection (src/core/few-shot.ts)

La fonction formatFewShotExamples() convertit les exemples YAML en objets de message ChatML :

export function formatFewShotExamples(
  examples: FewShotExample[],
  username = "user"
): Array<{ role: "user" | "assistant"; content: string }> {
  const messages = [];
  for (const example of examples) {
    messages.push({ role: "user", content: `${username}: ${example.user}` });
    messages.push({ role: "assistant", content: example.assistant });
  }
  return messages;
}

La fonction injectFewShotIntoConversation() les place juste après le prompt système :

export function injectFewShotIntoConversation(
  messages: Message[],
  fewShotMessages: Message[]
): Message[] {
  const systemMessage = messages[0];
  const userMessages = messages.slice(1);
  return [systemMessage, ...fewShotMessages, ...userMessages];
}

3. Intégration (src/core/llm-client.ts)

Avant chaque appel au LLM, les exemples few-shot sont injectés s'ils sont activés :

let finalMessages = messages;
if (FEW_SHOT_ENABLED && FEW_SHOT_EXAMPLES.length > 0) {
  const fewShotMessages = formatFewShotExamples(FEW_SHOT_EXAMPLES);
  finalMessages = injectFewShotIntoConversation(messages, fewShotMessages);
}

Le modèle reçoit : [prompt_système] + [exemples_few_shot] + [historique_de_conversation]


Conserver le style Discord-Dialogues

Le jeu de données Discord-Dialogues d'origine a une signature conversationnelle très spécifique :

  • Messages courts : 32,8 tokens en moyenne par tour
  • Registre informel : abréviations, minuscules, absence de ponctuation
  • Échanges rapides : plusieurs échanges courts plutôt que de longs monologues
  • Imperfections naturelles : fautes de frappe, « lol », « fr », « ngl », « tbh »

Le modèle Luna Protocol préserve ce style grâce à deux mécanismes :

1. Le fine-tuning déplace la distribution de base

Les 50k échantillons d'entraînement enseignent au modèle l'empreinte statistique des conversations Discord. Il apprend que les réponses sont typiquement courtes, en minuscules et informelles. Cela éloigne la sortie par défaut du modèle du mode « assistant serviable » de Qwen.

2. Le few-shot priming verrouille le résultat

Les exemples few-shot renforcent exactement les motifs appris pendant le fine-tuning. Ils agissent comme un ancrage stylistique -- même si le modèle dérive légèrement vers un ton plus formel au cours d'une longue conversation, les exemples présents dans le contexte le ramènent en arrière.

La combinaison est plus puissante que chaque mécanisme pris isolément :

  • Fine-tuning sans few-shot : le modèle est globalement décontracté mais inconsistant
  • Few-shot sans fine-tuning : le modèle essaie de suivre les exemples mais retombe sans cesse en mode assistant
  • Fine-tuning + few-shot : le modèle reste constamment dans le personnage

La philosophie : modèle plus petit, prompting plus malin

La sagesse conventionnelle en déploiement de LLM dit « plus gros, c'est mieux ». Plus de paramètres, plus de données d'entraînement, plus de VRAM. Luna Protocol prend le chemin inverse :

  • 1,5B au lieu de 3B : moitié moins de paramètres, moitié moins de mémoire, deux fois plus rapide
  • 50k échantillons au lieu de 7,3M : moins de données d'entraînement, plus de flexibilité pour l'apprentissage en contexte
  • Few-shot priming au lieu de prompts système : montrer au modèle ce qu'on veut, pas juste le lui dire

Ce n'est pas qu'une simple optimisation technique -- c'est un choix de conception. Un bot Discord n'a pas besoin d'être un assistant généraliste. Il doit dire « nm just chillin, u » de façon cohérente, rapide, et sans engloutir tout le budget VRAM du serveur.

Résultat : un bot qui tourne sur un VPS à 5 $/mois, génère des tokens assez vite pour donner l'impression d'une frappe en temps réel, et maintient une personnalité cohérente grâce à une combinaison de fine-tuning et de few-shot priming qui vaut plus que la somme de ses parties.


Mise en place

Télécharger le modèle

npm run download-model
# Télécharge Luna-Protocol-1.5B-Fine-Tuned-Qwen2.5.Q4_K_M.gguf

Ou manuellement depuis HuggingFace.

Configurer

# config.yml
llama_model_path: "./models/Luna-Protocol-1.5B-Fine-Tuned-Qwen2.5.Q4_K_M.gguf"
few_shot_enabled: true
few_shot_examples:
  - user: "yo whats good"
    assistant: "nm just chillin, u"
  - user: "bored af"
    assistant: "lol same energy fr"
  - user: "hey how are you"
    assistant: "im doing pretty good tbh, just vibing"

Lancer

npm run dev                    # dev (rechargement à chaud)
npm run build && npm start     # production
./start.sh                     # PM2 (production avec llama-server)

Conclusion

Les modèles Luna Protocol prouvent que pour une IA conversationnelle axée sur le style, moins, c'est mieux. Un modèle de 1,5B entraîné sur 50k échantillons soigneusement choisis, amorcé avec quelques exemples, surpasse un modèle de 3B entraîné sur des millions d'exemples -- pour une fraction du coût en mémoire et une vitesse de génération deux fois supérieure.

Le few-shot priming n'est pas qu'un simple plus pour les petits modèles. C'est le mécanisme qui les rend viables pour des applications conversationnelles en temps réel. Les exemples ne se contentent pas d'« aider » -- ils changent fondamentalement le comportement du modèle, en calquant exactement le format sur lequel il a été entraîné.

Le code est open source, le modèle est sur HuggingFace, et le jeu de données est public. Si vous voulez construire un bot conversationnel qui donne l'impression d'être humain, la recette est : petit modèle, fine-tuning limité, amorçage few-shot solide.

Ressource Lien
Dépôt GitHub fox3000foxy/luna-protocol-project
Modèle (HuggingFace) fox3000foxy/Luna-Protocol-1.5B-Discord-Dialogues
Jeu de données Discord-Dialogues
Premier article Luna Protocol : j'ai créé un bot Discord autonome

Luna Protocol:为什么我用5万条Discord样本微调了一个1.5B模型,让少样本提示成为秘密武器

一个在更少数据上训练的小模型可以胜过更大的模型----只要你知道如何提示它。本文讲述了Luna Protocol为何从3B Hermes转向1.5B Qwen微调模型,以及为什么少样本提示成为了真正的游戏规则改变者。

Luna Protocol:为什么我用5万条Discord样本微调了一个1.5B模型,让少样本提示成为秘密武器

在第一篇文章中,我构建了一个模拟真人的Discord机器人----包括睡眠、打字错误、犹豫、健忘和自发消息。行为系统很扎实。其背后的LLM是一个3B参数的Hermes模型,量化为Q8_0,占用3GB显存。

它能用。但杀鸡用了牛刀。

一个Discord机器人不需要3B参数的模型来说一句"nm just chillin, u"。它需要的是风格一致性----在每条消息中保持特定的对话语气,不偏离到企业助手模式。事实证明,一个在更少数据上训练的小模型,加上几个示例的提示,比一个靠系统提示蛮力输出的更大模型做得更好。

本文介绍Luna Protocol的官方模型:它们为什么存在,为什么是1.5B而不是3B,为什么用5万条训练样本而不是730万条,以及为什么少样本提示从锦上添花变成了整个方法的核心。


3B模型的问题

原始配置使用了Discord-Micae-Hermes-3-3B.Q8_0.gguf----一个在Discord数据上微调的3B参数模型。它能产生不错的回复,但是:

指标 Hermes-3-3B Q8_0 目标
显存占用 ~3 GB < 1 GB
Token生成速度 ~30 tok/s ~60+ tok/s
模型文件大小 ~3.2 GB < 1 GB
冷启动时间 ~8s ~3s

对于一个在普通服务器上全天候运行的机器人来说,3GB显存太多了。而且生成速度----虽然对偶尔的消息来说还行----在突发响应或多个频道活跃时显得迟缓。

问题是:我们能否用一半的参数获得同样的Discord-Dialogues风格?


微调决策:为什么是5万条,而不是730万条

Discord-Dialogues数据集包含730万次对话和1700万个轮次。这是一个庞大的真实Discord对话语料库。显而易见的做法是在整个数据集上训练。

我反其道而行之。我只用了5万个样本----不到可用数据的1%。

原因如下:训练集的大小直接影响模型对其训练分布的过拟合程度。

在730万个示例上训练的模型学会了对话的非常具体的统计分布。它擅长复现这种分布,但也变得僵化----它在推理时适应新模式的能力较弱。

在5万个示例上训练的模型学会了Discord对话的总体语气和语域(非正式、简短、缩写、小写),但保留了足够的灵活性,可以通过上下文示例来引导。少样本示例不需要对抗庞大的已学习分布----它们只是补充了一个较轻量的分布。

这是核心洞察:有限的训练数据使少样本提示更加高效。


模型:技术细节

Luna Protocol模型是对Qwen2.5-1.5B-Instruct的QLoRA微调:

参数 值
基础模型 unsloth/Qwen2.5-1.5B-Instruct-bnb-4bit
方法 QLoRA(4-bit)
LoRA秩 r=16, lora_alpha=16
目标模块 q/k/v/o_proj, gate/up/down_proj
可训练参数 18,464,768 / 1,562,179,072(1.18%)
训练数据 ~50,000个示例(Discord-Dialogues子集)
筛选条件 每个样本8-512个token
训练轮次 2-3
硬件 Kaggle T4
框架 Unsloth

数据集是Discord-Dialogues的一个预处理分支,经过筛选只保留干净的user/assistant轮次----没有系统消息、没有元数据、没有机器人命令。这对后续很重要。

可用的量化版本

文件 量化方式 大小 说明
Luna-Protocol-1.5B-Fine-Tuned-Qwen2.5.Q2_K.gguf Q2_K 676 MB 明显降质----不推荐
Luna-Protocol-1.5B-Fine-Tuned-Qwen2.5.Q4_K_M.gguf Q4_K_M 986 MB 大小/质量平衡好(推荐)
Luna-Protocol-1.5B-Fine-Tuned-Qwen2.5.Q8_0.gguf Q8_0 1.65 GB 最佳风格保真度

推荐的模型是Q4_K_M----不到1GB,速度快,能很好地保留对话风格。Q2_K在这种小模型上降质太严重。Q8_0质量最好但多占用68%的内存。


少样本提示的突破

这部分改变了一切。

HuggingFace模型卡片上有一条警告:

在没有提示的裸提示词下,该模型倾向于退回到Qwen的默认助手语气。短的少样本提示会产生巨大差异。

这不是一个bug----这是训练数据结构化的直接结果。

为什么单独使用系统提示没用

Discord-Dialogues训练数据只包含user/assistant轮次。训练集中没有系统角色的示例。模型从未被训练过将系统提示作为风格指令来遵循。

当你给它一个系统提示,比如"你的名字是Luna,随便聊聊",它听到了指令,但没有一个强大的已学习模式来将其转化为输出。它会退回到Qwen的默认模式:乐于助人、结构化、略显正式。

为什么少样本示例有效

当你注入与模型训练所用的相同ChatML格式(使用user/assistant轮次结构)的对话示例时,模型会"咔嗒"一声理解。它识别出训练数据中的模式,并将输出对齐以匹配。

以下是少样本提示的实际样子:

few_shot_examples:
  - user: "yo whats good"
    assistant: "nm just chillin, u"
  - user: "bored af"
    assistant: "lol same energy fr"
  - user: "hey how are you"
    assistant: "im doing pretty good tbh, just vibing"

这些示例被注入到系统提示之后、真实对话之前。模型将它们视为对话历史的一部分,而不是指令。这是一个关键区别----不是告诉它要随意,而是展示随意是什么样子。

前后对比

没有少样本提示(裸系统提示):

User: yo whats good
Bot: Hello! I am doing well, thank you for asking. How can I assist you today?

有少样本提示(3个示例):

User: yo whats good
Bot: nm just chillin, u

差异巨大。模型不仅仅是产生不同的词汇----它还采用了整个语域:小写、缩写、随意语气、简短回复。它匹配了示例的风格,而不是Qwen训练数据的风格。


内存与速度:具体数字

从Hermes-3-3B切换到Luna-Protocol-1.5B带来了可衡量的提升:

指标 Hermes-3-3B Q8_0 Luna-Protocol Q4_K_M 提升
显存占用 ~3 GB ~986 MB 减少67%
模型文件大小 ~3.2 GB ~986 MB 缩小69%
Token生成速度 ~30 tok/s ~60+ tok/s 快2倍
冷启动 ~8s ~3s 快62%
上下文窗口 8192 8192 相同

为什么速度提升是真实的

较小的模型不仅仅是"不那么慢"----它们在推理时本质上更快。使用1.5B参数而不是3B:

  • 每个token的矩阵乘法更少:注意力层、FFN层和输出投影都随参数数量线性扩展
  • 更好的缓存利用:较小的模型能将更多权重放入L2/L3缓存
  • 更低的内存带宽压力:每个token从显存读取的字节更少

在普通的纯CPU配置(2核,无GPU)上,1.5B模型的token生成速度大约是3B模型的2倍。这就是"感觉像机器人"和"感觉像真人在打字"之间的区别。

提示缓存放大了优势

Luna Protocol使用启用了提示缓存的llama-server(--cache-reuse 256)。这意味着:

  1. 会话中的第一条消息支付完整的提示处理成本(系统提示 + 少样本示例 + 用户消息)
  2. 后续消息只处理新的token----缓存的前缀被重用
  3. 使用5个少样本示例(约50-150个token),第一次请求后开销可以忽略不计

在会话的第一条消息之后,少样本示例实际上就是"免费"的。模型以零边际成本获得风格指导。


实现:代码如何工作

Luna Protocol中的少样本系统简洁而精炼。三个文件处理所有逻辑:

1. 配置(config.yml)

few_shot_enabled: true
few_shot_examples:
  - user: "yo whats good"
    assistant: "nm just chillin, u"
  - user: "bored af"
    assistant: "lol same energy fr"
  - user: "hey how are you"
    assistant: "im doing pretty good tbh, just vibing"
  - user: "whats up"
    assistant: "yooo not much, what about you"
  - user: "how was your day"
    assistant: "it was alright, nothing crazy happened lol"

配置支持热重载。修改示例,保存,机器人立即采用新风格----无需重启。

2. 格式化与注入(src/core/few-shot.ts)

formatFewShotExamples()函数将YAML示例转换为ChatML消息对象:

export function formatFewShotExamples(
  examples: FewShotExample[],
  username = "user"
): Array<{ role: "user" | "assistant"; content: string }> {
  const messages = [];
  for (const example of examples) {
    messages.push({ role: "user", content: `${username}: ${example.user}` });
    messages.push({ role: "assistant", content: example.assistant });
  }
  return messages;
}

injectFewShotIntoConversation()函数将它们放置在系统提示之后:

export function injectFewShotIntoConversation(
  messages: Message[],
  fewShotMessages: Message[]
): Message[] {
  const systemMessage = messages[0];
  const userMessages = messages.slice(1);
  return [systemMessage, ...fewShotMessages, ...userMessages];
}

3. 集成(src/core/llm-client.ts)

每次LLM调用前,如果启用则注入少样本示例:

let finalMessages = messages;
if (FEW_SHOT_ENABLED && FEW_SHOT_EXAMPLES.length > 0) {
  const fewShotMessages = formatFewShotExamples(FEW_SHOT_EXAMPLES);
  finalMessages = injectFewShotIntoConversation(messages, fewShotMessages);
}

模型接收到:[system_prompt] + [few_shot_examples] + [conversation_history]


保持Discord-Dialogues风格

原始Discord-Dialogues数据集具有非常独特的对话特征:

  • 短消息:每轮平均32.8个token
  • 非正式语域:缩写、小写、无标点
  • 快速来回:多次简短交流而非长篇独白
  • 自然的不完美:打字错误、"lol"、"fr"、"ngl"、"tbh"

Luna-Protocol模型通过两种机制保持这种风格:

1. 微调改变基础分布

5万条训练样本教会了模型Discord对话的统计特征。它学会了回复通常是简短、小写且非正式的。这使得模型的默认输出脱离了Qwen的乐于助人的助手模式。

2. 少样本提示锁定风格

少样本示例强化了模型在微调期间学到的确切模式。它们起到了风格锚点的作用----即使模型在长时间对话中略微向正式语气偏移,上下文中的示例也会持续将其拉回。

两者的结合比任何一种机制单独使用都更强大:

  • 无少样本的微调:模型大致随意但不一致
  • 无微调的少样本:模型尝试跟随示例但不断退回到助手模式
  • 微调 + 少样本:模型始终如一地保持角色

理念:更小的模型,更聪明的提示

LLM部署的传统智慧是"越大越好"。更多参数、更多训练数据、更多显存。Luna Protocol采取了相反的方法:

  • 1.5B而不是3B:一半的参数,一半的内存,两倍的速度
  • 5万样本而不是730万:更少的训练数据,更多的上下文学习灵活性
  • 少样本提示而不是系统提示:向模型展示你想要什么,而不只是告诉它

这不仅仅是技术优化----这是一种设计理念。Discord机器人不需要成为通用助手。它需要一致、快速地说出"nm just chillin, u",而不会吃掉你服务器的全部显存预算。

结果:一个在5美元/月的VPS上运行的机器人,生成token的速度足以让人感觉像实时打字,并通过微调和少样本提示的结合保持一致的个性----两者的结合效果大于各自之和。


设置

下载模型

npm run download-model
# 下载 Luna-Protocol-1.5B-Fine-Tuned-Qwen2.5.Q4_K_M.gguf

或从HuggingFace手动下载。

配置

# config.yml
llama_model_path: "./models/Luna-Protocol-1.5B-Fine-Tuned-Qwen2.5.Q4_K_M.gguf"
few_shot_enabled: true
few_shot_examples:
  - user: "yo whats good"
    assistant: "nm just chillin, u"
  - user: "bored af"
    assistant: "lol same energy fr"
  - user: "hey how are you"
    assistant: "im doing pretty good tbh, just vibing"

运行

npm run dev                    # 开发(热重载)
npm run build && npm start     # 生产环境
./start.sh                     # PM2(生产环境,带llama-server)

结论

Luna Protocol模型证明了对于风格特定的对话式AI来说,少即是多。一个在5万个精心挑选样本上训练的1.5B模型,加上几个示例的提示,在内存成本极小和生成速度翻倍的情况下,胜过在数百万示例上训练的3B模型。

少样本提示对于小模型来说不仅仅是锦上添花。它是使它们适用于实时对话应用的关键机制。示例不仅仅是"帮助"----它们通过匹配模型训练时使用的确切格式,从根本上改变了模型的行为方式。

代码是开源的,模型在HuggingFace上,数据集也是公开的。如果你想构建一个感觉像真人的对话机器人,配方是:小模型、有限微调、强大的少样本提示。

资源 链接
GitHub仓库 fox3000foxy/luna-protocol-project
模型(HuggingFace) fox3000foxy/Luna-Protocol-1.5B-Discord-Dialogues
数据集 Discord-Dialogues
第一篇文章 Luna Protocol:我创建了一个自主Discord机器人

Luna Protocol:5万件のDiscordサンプルで1.5Bモデルをファインチューニングし、なぜFew-Shotプライミングが秘密兵器になったのか

少ないデータで学習した小さなモデルが、より大きなモデルを凌駕できる----プロンプトの使い方を知っていれば。Luna Protocolが3B Hermesから1.5B Qwenのファインチューンに切り替えた理由、そしてFew-Shotプライミングが真のゲームチェンジャーになった理由をご紹介します。

Luna Protocol:5万件のDiscordサンプルで1.5Bモデルをファインチューニングし、なぜFew-Shotプライミングが秘密兵器になったのか

最初の記事では、人間をシミュレートするDiscordボットを作りました----睡眠、タイプミス、ためらい、忘れっぽさ、自発的なメッセージ。行動システムはしっかりしていました。その背後にあるLLMは3BパラメータのHermesモデルで、Q8_0に量子化され、3GBのVRAMを消費していました。

動作しました。しかし、オーバーキルでした。

Discordボットが「nm just chillin, u」と言うのに、3Bパラメータのモデルは必要ありません。必要なのはスタイルの一貫性----特定の会話調をメッセージごとに維持し、企業のアシスタントモードに陥らない能力です。そして、少ないデータで学習した小さなモデルに、いくつかの例でプライミングをかける方が、大きなモデルがシステムプロンプトで力押しするよりも効果的であることがわかりました。

この記事では、Luna Protocolの公式モデルについて説明します:なぜ存在するのか、なぜ3Bではなく1.5Bなのか、なぜ730万ではなく5万の学習サンプルなのか、そしてなぜFew-Shotプライミングが「あると便利」からアプローチ全体の中核へと変わったのか。


3Bモデルの問題

元の設定ではDiscord-Micae-Hermes-3-3B.Q8_0.gguf----Discordデータでファインチューニングされた3Bパラメータのモデルを使用していました。良い応答を生成しましたが、次の問題がありました:

指標 Hermes-3-3B Q8_0 目標
VRAM使用量 ~3 GB < 1 GB
トークン生成速度 ~30 tok/s ~60+ tok/s
モデルファイルサイズ ~3.2 GB < 1 GB
コールドスタート時間 ~8s ~3s

24時間365日稼働するボットにとって、3GBのVRAMは大きな負担です。また、生成速度は----たまのメッセージには問題ありませんが----バースト応答や複数チャンネルがアクティブなときにはもたつきを感じさせました。

問題は:同じDiscord-Dialoguesのスタイルを半分のパラメータで実現できるか?


ファインチューニングの判断:なぜ730万ではなく5万なのか

Discord-Dialoguesデータセットには730万の会話と1700万のターンが含まれています。これは大規模な実際のDiscord会話コーパスです。明白なアプローチはデータセット全体で学習することでした。

私は逆を行いました。5万サンプルで学習しました----利用可能なデータの1%未満です。

理由はこれです:学習セットのサイズは、モデルが学習分布に過学習する度合いに直接影響します。

730万の例で学習したモデルは、会話の非常に特定の統計的分布を学習します。その分布を再現することに長けますが、同時に硬直的になります----推論時に新しいパターンに適応する柔軟性が低くなります。

5万の例で学習したモデルは、Discord会話の全体的なトーンとレジスター(非公式、短縮形、略語、小文字)を学習しますが、コンテキスト内の例で誘導されるための十分な柔軟性を保持します。Few-Shotの例は、巨大な学習済み分布と戦うのではなく、より軽量な分布を補完します。

これが核心的な洞察です:限られた学習データにより、Few-Shotプライミングがより効果的になります。


モデル:技術詳細

Luna Protocolモデルは、Qwen2.5-1.5B-InstructのQLoRAファインチューンです:

パラメータ 値
ベースモデル unsloth/Qwen2.5-1.5B-Instruct-bnb-4bit
手法 QLoRA(4-bit)
LoRAランク r=16, lora_alpha=16
対象モジュール q/k/v/o_proj, gate/up/down_proj
学習可能パラメータ 18,464,768 / 1,562,179,072(1.18%)
学習データ ~50,000例(Discord-Dialoguesサブセット)
フィルター サンプルあたり8-512トークン
エポック 2-3
ハードウェア Kaggle T4
フレームワーク Unsloth

データセットはDiscord-Dialoguesの前処理済みフォークで、クリーンなuser/assistantターンのみにフィルタリングされています----システムメッセージ、メタデータ、ボットコマンドは含まれません。これは後で重要になります。

利用可能な量子化

ファイル 量子化 サイズ 備考
Luna-Protocol-1.5B-Fine-Tuned-Qwen2.5.Q2_K.gguf Q2_K 676 MB 顕著に劣化----非推奨
Luna-Protocol-1.5B-Fine-Tuned-Qwen2.5.Q4_K_M.gguf Q4_K_M 986 MB サイズ/品質のバランス良好(推奨)
Luna-Protocol-1.5B-Fine-Tuned-Qwen2.5.Q8_0.gguf Q8_0 1.65 GB 最高のスタイル忠実度

推奨モデルはQ4_K_M----1GB未満、高速で、会話スタイルをよく保持します。Q2_Kはこのサイズのモデルでは劣化が大きすぎます。Q8_0は最高品質ですが、68%多くメモリを消費します。


Few-Shotプライミングのブレークスルー

ここからすべてが変わりました。

HuggingFaceのモデルカードには警告があります:

ベアプロンプトでプライミングなしの場合、このモデルはQwenのデフォルトのアシスタント調に戻る傾向があります。短いFew-Shotプライムが大きな違いを生みます。

これはバグではありません----学習データの構造化方法の直接的な結果です。

システムプロンプトだけでは機能しない理由

Discord-Dialoguesの学習データにはuser/assistantターンしか含まれていません。学習セットにはシステムロールの例がありません。モデルはシステムプロンプトをスタイル指示として従うように学習されたことがありません。

「あなたの名前はLunaです、カジュアルに話してください」のようなシステムプロンプトを与えると、指示は認識しますが、それを出力に変換するための強力な学習パターンを持っていません。Qwenのデフォルト(親切、構造化、ややフォーマル)に戻ってしまいます。

Few-Shot例が機能する理由

モデルが学習したものと同じChatML形式(user/assistantターン構造を使用)で会話例を注入すると、モデルは「カチッ」とはまります。モデルは学習データからパターンを認識し、出力を一致させます。

実際のFew-Shotプライムは次のようになります:

few_shot_examples:
  - user: "yo whats good"
    assistant: "nm just chillin, u"
  - user: "bored af"
    assistant: "lol same energy fr"
  - user: "hey how are you"
    assistant: "im doing pretty good tbh, just vibing"

これらの例は、システムプロンプトの後、実際の会話の前に注入されます。モデルはこれらを指示ではなく、会話履歴の一部として認識します。これが重要な違いです----カジュアルであるように言われるのではなく、カジュアルがどのようなものかを見せられるのです。

前後比較

Few-Shotプライミングなし(ベアシステムプロンプト):

User: yo whats good
Bot: Hello! I am doing well, thank you for asking. How can I assist you today?

Few-Shotプライミングあり(3例):

User: yo whats good
Bot: nm just chillin, u

その差は歴然です。モデルは異なる単語を生成するだけでなく、レジスター全体----小文字、略語、カジュアルな調子、短い応答----を採用します。Qwenの学習データのスタイルではなく、例のスタイルに適合します。


メモリと速度:具体的な数値

Hermes-3-3BからLuna-Protocol-1.5Bへの切り替えで、測定可能な向上が得られます:

指標 Hermes-3-3B Q8_0 Luna-Protocol Q4_K_M 向上率
VRAM使用量 ~3 GB ~986 MB 67%削減
モデルファイルサイズ ~3.2 GB ~986 MB 69%小型化
トークン生成速度 ~30 tok/s ~60+ tok/s 2倍高速
コールドスタート ~8s ~3s 62%高速化
コンテキストウィンドウ 8192 8192 同じ

速度向上が本物である理由

小さなモデルは単に「遅くない」だけでなく、本質的に推論が高速です。1.5Bパラメータ(3Bではなく)では:

  • トークンあたりの行列乗算が少ない:アテンション層、FFN層、出力投影はすべてパラメータ数に比例してスケール
  • キャッシュ利用の向上:小さなモデルはより多くの重みをL2/L3キャッシュに収められる
  • メモリ帯域幅の負荷低減:トークンあたりにVRAMから読み取るバイト数が減少

一般的なCPUのみの構成(2コア、GPUなし)では、1.5Bモデルは3Bモデルの約2倍の速度でトークンを生成します。これは「ボットっぽい」と「人間がタイピングしているように感じる」の違いです。

プロンプトキャッシングがアドバンテージを増幅

Luna Protocolはプロンプトキャッシングを有効にしたllama-server(--cache-reuse 256)を使用しています。つまり:

  1. セッションの最初のメッセージは完全なプロンプト処理コスト(システムプロンプト + Few-Shot例 + ユーザーメッセージ)を支払う
  2. 後続のメッセージは新しいトークンのみを処理----キャッシュされたプレフィックスが再利用される
  3. 5つのFew-Shot例(約50-150トークン)の場合、最初のリクエスト以降のオーバーヘッドは無視できる

Few-Shotの例は、セッションの最初のメッセージ以降、実質的に「無料」になります。モデルは限界費用ゼロでスタイルガイダンスを得られます。


実装:コードの仕組み

Luna ProtocolのFew-Shotシステムはクリーンでミニマルです。3つのファイルがすべてを処理します:

1. 設定(config.yml)

few_shot_enabled: true
few_shot_examples:
  - user: "yo whats good"
    assistant: "nm just chillin, u"
  - user: "bored af"
    assistant: "lol same energy fr"
  - user: "hey how are you"
    assistant: "im doing pretty good tbh, just vibing"
  - user: "whats up"
    assistant: "yooo not much, what about you"
  - user: "how was your day"
    assistant: "it was alright, nothing crazy happened lol"

設定はホットリロード可能です。例を変更して保存すると、ボットは即座に新しいスタイルを適用します----再起動は不要です。

2. フォーマットと注入(src/core/few-shot.ts)

formatFewShotExamples()関数はYAMLの例をChatMLメッセージオブジェクトに変換します:

export function formatFewShotExamples(
  examples: FewShotExample[],
  username = "user"
): Array<{ role: "user" | "assistant"; content: string }> {
  const messages = [];
  for (const example of examples) {
    messages.push({ role: "user", content: `${username}: ${example.user}` });
    messages.push({ role: "assistant", content: example.assistant });
  }
  return messages;
}

injectFewShotIntoConversation()関数はそれらをシステムプロンプトの直後に配置します:

export function injectFewShotIntoConversation(
  messages: Message[],
  fewShotMessages: Message[]
): Message[] {
  const systemMessage = messages[0];
  const userMessages = messages.slice(1);
  return [systemMessage, ...fewShotMessages, ...userMessages];
}

3. 統合(src/core/llm-client.ts)

LLM呼び出しの前に、有効な場合はFew-Shotの例が注入されます:

let finalMessages = messages;
if (FEW_SHOT_ENABLED && FEW_SHOT_EXAMPLES.length > 0) {
  const fewShotMessages = formatFewShotExamples(FEW_SHOT_EXAMPLES);
  finalMessages = injectFewShotIntoConversation(messages, fewShotMessages);
}

モデルが受け取る:[system_prompt] + [few_shot_examples] + [conversation_history]


Discord-Dialoguesのスタイルを維持する

元のDiscord-Dialoguesデータセットには非常に特徴的な会話のシグネチャがあります:

  • 短いメッセージ:ターンあたり平均32.8トークン
  • 非公式なレジスター:略語、小文字、句読点なし
  • 素早い応酬:長いモノローグではなく、短いやりとり
  • 自然な不完全さ:タイプミス、「lol」、「fr」、「ngl」、「tbh」

Luna-Protocolモデルは2つのメカニズムでこのスタイルを保持します:

1. ファインチューニングが基本分布をシフト

5万の学習サンプルはモデルにDiscord会話の統計的指紋を教えます。応答が典型的に短く、小文字で、非公式であることを学習します。これにより、モデルのデフォルト出力がQwenの親切なアシスタントモードからシフトします。

2. Few-Shotプライミングがそれを固定

Few-Shotの例は、ファインチューニング中にモデルが学習した正確なパターンを強化します。これらはスタイルアンカーとして機能します----長い会話中にモデルがフォーマルな調子にわずかにドリフトしても、コンテキスト内の例が常に引き戻します。

この組み合わせは、どちらかのメカニズム単独よりも強力です:

  • Few-Shotなしのファインチューニング:モデルは概ねカジュアルだが一貫性がない
  • ファインチューニングなしのFew-Shot:モデルは例に従おうとするが、アシスタントモードに戻り続ける
  • ファインチューニング + Few-Shot:モデルは一貫してキャラクターを保つ

哲学:小さなモデル、スマートなプロンプティング

LLMデプロイメントの従来の常識は「大きい方が良い」です。より多くのパラメータ、より多くの学習データ、より多くのVRAM。Luna Protocolは逆のアプローチを取ります:

  • 3Bではなく1.5B:半分のパラメータ、半分のメモリ、2倍の速度
  • 730万ではなく5万サンプル:少ない学習データ、コンテキスト内学習のための高い柔軟性
  • システムプロンプトではなくFew-Shotプライミング:望むものをモデルに見せる、単に伝えるのではない

これは単なる技術的最適化ではありません----設計哲学です。Discordボットは汎用アシスタントである必要はありません。「nm just chillin, u」を一貫して、迅速に、サーバーのVRAM予算をすべて消費せずに言えればよいのです。

結果:月5ドルのVPSで動作し、リアルタイムのタイピングと感じられるほど速くトークンを生成し、ファインチューニングとFew-Shotプライミングの組み合わせ(その合計以上の効果)によって一貫した個性を維持するボット。


セットアップ

モデルのダウンロード

npm run download-model
# Luna-Protocol-1.5B-Fine-Tuned-Qwen2.5.Q4_K_M.gguf をダウンロード

またはHuggingFaceから手動で。

設定

# config.yml
llama_model_path: "./models/Luna-Protocol-1.5B-Fine-Tuned-Qwen2.5.Q4_K_M.gguf"
few_shot_enabled: true
few_shot_examples:
  - user: "yo whats good"
    assistant: "nm just chillin, u"
  - user: "bored af"
    assistant: "lol same energy fr"
  - user: "hey how are you"
    assistant: "im doing pretty good tbh, just vibing"

実行

npm run dev                    # 開発(ホットリロード)
npm run build && npm start     # 本番
./start.sh                     # PM2(llama-server使用の本番環境)

結論

Luna Protocolモデルは、スタイル特化型の会話AIにおいては少ない方が多いことを証明しています。5万の厳選されたサンプルで学習した1.5Bモデルは、少数の例でプライミングすることで、数百万の例で学習した3Bモデルを----わずかなメモリコストと2倍の生成速度で----凌駕します。

Few-Shotプライミングは小さなモデルにとって単なる「あると便利」ではありません。それは、リアルタイム会話アプリケーションでそれらを実用的にするメカニズムです。例は単に「助ける」だけでなく----モデルが学習した正確な形式にマッチすることで、モデルの振る舞いを根本的に変えます。

コードはオープンソース、モデルはHuggingFace上、データセットは公開されています。人間らしい会話ボットを構築したいなら、レシピはこれです:小さなモデル、限定的なファインチューニング、強力なFew-Shotプライミング。

リソース リンク
GitHubリポジトリ fox3000foxy/luna-protocol-project
モデル(HuggingFace) fox3000foxy/Luna-Protocol-1.5B-Discord-Dialogues
データセット Discord-Dialogues
最初の記事 Luna Protocol:自律型Discordボットを作りました

Luna Protocol: 5만 개의 Discord 샘플로 1.5B 모델을 파인튜닝하고 Few-Shot 프라이밍을 비밀 무기로 만든 이유

더 적은 데이터로 학습된 작은 모델이 더 큰 모델을 능가할 수 있습니다----프라이밍 방법을 알면 말이죠. Luna Protocol이 3B Hermes에서 1.5B Qwen 파인튜닝으로 전환한 이유와 Few-Shot 프라이밍이 진정한 게임 체인저가 된 이유를 소개합니다.

Luna Protocol: 5만 개의 Discord 샘플로 1.5B 모델을 파인튜닝하고 Few-Shot 프라이밍을 비밀 무기로 만든 이유

첫 번째 글에서 저는 인간을 시뮬레이션하는 Discord 봇을 만들었습니다----수면, 오타, 망설임, 건망증, 자발적인 메시지까지. 행동 시스템은 탄탄했습니다. 그 뒤에 있는 LLM은 3B 파라미터의 Hermes 모델로, Q8_0으로 양자화되어 3GB의 VRAM을 소모했습니다.

작동했습니다. 하지만 과했죠.

Discord 봇이 "nm just chillin, u"라고 말하는 데 3B 파라미터 모델은 필요하지 않습니다. 필요한 것은 스타일 일관성----특정 대화 톤을 메시지마다 유지하고, 기업용 어시스턴트 모드로 빠지지 않는 능력입니다. 그리고 적은 데이터로 학습된 작은 모델이 몇 가지 예시로 프라이밍되면, 큰 모델이 시스템 프롬프트로 무식하게 밀어붙이는 것보다 더 잘한다는 사실이 밝혀졌습니다.

이 글은 Luna Protocol의 공식 모델에 관한 것입니다: 왜 존재하는지, 왜 3B 대신 1.5B인지, 왜 730만 개 대신 5만 개의 학습 샘플인지, 그리고 왜 Few-Shot 프라이밍이 있으면 좋은 기능에서 접근 방식의 핵심으로 자리잡았는지 설명합니다.


3B 모델의 문제

원래 설정은 Discord-Micae-Hermes-3-3B.Q8_0.gguf----Discord 데이터로 파인튜닝된 3B 파라미터 모델을 사용했습니다. 좋은 응답을 생성했지만, 다음과 같은 문제가 있었습니다:

지표 Hermes-3-3B Q8_0 목표
VRAM 사용량 ~3 GB < 1 GB
토큰 생성 속도 ~30 tok/s ~60+ tok/s
모델 파일 크기 ~3.2 GB < 1 GB
콜드 스타트 시간 ~8s ~3s

24시간 내내 운영되는 봇에게 3GB의 VRAM은 큰 부담입니다. 게다가 생성 속도는----가끔 보내는 메시지에는 괜찮지만----폭발적인 응답이나 여러 채널이 활성화되었을 때는 느리게 느껴졌습니다.

질문은 이것이었습니다: 절반의 파라미터로 동일한 Discord-Dialogues 스타일을 얻을 수 있을까?


파인튜닝 결정: 왜 730만 개가 아닌 5만 개인가

Discord-Dialogues 데이터셋은 730만 개의 대화와 1700만 개의 턴을 포함하고 있습니다. 방대한 실제 Discord 대화 코퍼스입니다. 당연한 접근 방식은 전체 데이터셋으로 학습하는 것이었습니다.

저는 반대로 했습니다. 5만 개의 샘플로 학습했습니다----사용 가능한 데이터의 1% 미만입니다.

이유는 다음과 같습니다: 학습 세트의 크기는 모델이 학습 분포에 과적합되는 정도에 직접적인 영향을 미칩니다.

730만 개의 예시로 학습된 모델은 대화의 매우 특정한 통계적 분포를 학습합니다. 그 분포를 재현하는 데 탁월해지지만, 동시에 경직됩니다----추론 시 새로운 패턴에 적응할 유연성이 줄어듭니다.

5만 개의 예시로 학습된 모델은 Discord 대화의 전반적인 톤과 레지스터(비공식적, 짧은 형식, 약어, 소문자)를 학습하지만, 맥락 내 예시로 유도될 수 있는 충분한 유연성을 유지합니다. Few-Shot 예시는 거대한 학습 분포와 싸우지 않고, 더 가벼운 분포를 보완합니다.

이것이 핵심 통찰입니다: 제한된 학습 데이터가 Few-Shot 프라이밍을 더 효율적으로 만듭니다.


모델: 기술적 세부사항

Luna Protocol 모델은 Qwen2.5-1.5B-Instruct의 QLoRA 파인튜닝입니다:

파라미터 값
베이스 모델 unsloth/Qwen2.5-1.5B-Instruct-bnb-4bit
방법 QLoRA (4-bit)
LoRA 랭크 r=16, lora_alpha=16
대상 모듈 q/k/v/o_proj, gate/up/down_proj
학습 가능 파라미터 18,464,768 / 1,562,179,072 (1.18%)
학습 데이터 ~50,000개 예시 (Discord-Dialogues 서브셋)
필터 샘플당 8-512 토큰
에포크 2-3
하드웨어 Kaggle T4
프레임워크 Unsloth

데이터셋은 Discord-Dialogues의 전처리된 포크로, 깨끗한 user/assistant 턴만 필터링되었습니다----시스템 메시지, 메타데이터, 봇 명령어 없음. 이는 나중에 중요합니다.

사용 가능한 양자화

파일 양자화 크기 비고
Luna-Protocol-1.5B-Fine-Tuned-Qwen2.5.Q2_K.gguf Q2_K 676 MB 현저히 저하됨----비권장
Luna-Protocol-1.5B-Fine-Tuned-Qwen2.5.Q4_K_M.gguf Q4_K_M 986 MB 크기/품질 균형 우수 (권장)
Luna-Protocol-1.5B-Fine-Tuned-Qwen2.5.Q8_0.gguf Q8_0 1.65 GB 최고의 스타일 충실도

권장 모델은 Q4_K_M----1GB 미만, 빠르며, 대화 스타일을 잘 보존합니다. Q2_K는 이렇게 작은 모델에서는 저하가 너무 심합니다. Q8_0이 최고 품질이지만 메모리를 68% 더 사용합니다.


Few-Shot 프라이밍의 돌파구

여기서 모든 것이 바뀌었습니다.

HuggingFace 모델 카드에는 경고가 있습니다:

베어 프롬프트와 프라이밍 없이 이 모델은 Qwen의 기본 어시스턴트 톤으로 되돌아가는 경향이 있습니다. 짧은 Few-Shot 프라임이 큰 차이를 만듭니다.

이것은 버그가 아닙니다----학습 데이터가 구조화된 방식의 직접적인 결과입니다.

시스템 프롬프트만으로는 작동하지 않는 이유

Discord-Dialogues 학습 데이터에는 user/assistant 턴만 포함되어 있습니다. 학습 세트에는 시스템 역할 예시가 없습니다. 모델은 시스템 프롬프트를 스타일 지시사항으로 따르도록 학습된 적이 없습니다.

"당신의 이름은 Luna입니다, 캐주얼하게 말하세요"와 같은 시스템 프롬프트를 주면, 지시는 인식하지만 그것을 출력으로 변환할 강력한 학습 패턴이 없습니다. Qwen의 기본값인 친절하고, 구조화되고, 약간 격식 있는 방식으로 되돌아갑니다.

Few-Shot 예시가 작동하는 이유

모델이 학습한 것과 동일한 ChatML 형식(user/assistant 턴 구조 사용)으로 대화 예시를 주입하면, 모델이 "딸깍" 하고 맞물립니다. 모델은 학습 데이터에서 패턴을 인식하고 출력을 일치시킵니다.

실제 Few-Shot 프라임은 다음과 같습니다:

few_shot_examples:
  - user: "yo whats good"
    assistant: "nm just chillin, u"
  - user: "bored af"
    assistant: "lol same energy fr"
  - user: "hey how are you"
    assistant: "im doing pretty good tbh, just vibing"

이 예시들은 시스템 프롬프트 뒤, 실제 대화 앞에 주입됩니다. 모델은 이를 지시사항이 아닌 대화 기록의 일부로 인식합니다. 이것이 중요한 차이점입니다----캐주얼하라고 지시받는 것이 아니라, 캐주얼함이 무엇인지 보여지는 것입니다.

전후 비교

Few-Shot 프라이밍 없음 (베어 시스템 프롬프트):

User: yo whats good
Bot: Hello! I am doing well, thank you for asking. How can I assist you today?

Few-Shot 프라이밍 있음 (3개 예시):

User: yo whats good
Bot: nm just chillin, u

차이는 극명합니다. 모델은 단지 다른 단어를 생성하는 것이 아니라 레지스터 전체----소문자, 약어, 캐주얼한 톤, 짧은 응답----를 채택합니다. Qwen 학습 데이터의 스타일이 아닌, 예시의 스타일에 맞춥니다.


메모리와 속도: 구체적인 수치

Hermes-3-3B에서 Luna-Protocol-1.5B로의 전환은 측정 가능한 향상을 가져옵니다:

지표 Hermes-3-3B Q8_0 Luna-Protocol Q4_K_M 향상
VRAM 사용량 ~3 GB ~986 MB 67% 감소
모델 파일 크기 ~3.2 GB ~986 MB 69% 축소
토큰 생성 속도 ~30 tok/s ~60+ tok/s 2배 빠름
콜드 스타트 ~8s ~3s 62% 빠름
컨텍스트 윈도우 8192 8192 동일

속도 향상이 실제인 이유

작은 모델은 단순히 "덜 느린" 것이 아니라 본질적으로 추론이 더 빠릅니다. 1.5B 파라미터(3B 대신)로:

  • 토큰당 행렬 곱셈 감소: 어텐션 레이어, FFN 레이어, 출력 프로젝션 모두 파라미터 수에 따라 선형적으로 확장
  • 캐시 활용 개선: 작은 모델이 더 많은 가중치를 L2/L3 캐시에 수용
  • 메모리 대역폭 부하 감소: 토큰당 VRAM에서 읽어야 할 바이트 감소

일반적인 CPU 전용 설정(2코어, GPU 없음)에서 1.5B 모델은 3B 모델보다 약 2배 빠른 속도로 토큰을 생성합니다. 이는 "봇 같다"와 "사람이 타이핑하는 것 같다"의 차이입니다.

프롬프트 캐싱이 장점을 증폭

Luna Protocol은 프롬프트 캐싱이 활성화된 llama-server(--cache-reuse 256)를 사용합니다. 즉:

  1. 세션의 첫 번째 메시지는 전체 프롬프트 처리 비용(시스템 프롬프트 + Few-Shot 예시 + 사용자 메시지)을 지불
  2. 이후 메시지는 새로운 토큰만 처리----캐시된 프리픽스가 재사용됨
  3. 5개의 Few-Shot 예시(~50-150 토큰)로 첫 요청 이후 오버헤드는 무시할 수 있음

세션의 첫 번째 메시지 이후 Few-Shot 예시는 사실상 "무료"입니다. 모델은 한계 비용 제로로 스타일 가이드를 얻습니다.


구현: 코드 작동 방식

Luna Protocol의 Few-Shot 시스템은 깔끔하고 미니멀합니다. 세 개의 파일이 모든 것을 처리합니다:

1. 설정 (config.yml)

few_shot_enabled: true
few_shot_examples:
  - user: "yo whats good"
    assistant: "nm just chillin, u"
  - user: "bored af"
    assistant: "lol same energy fr"
  - user: "hey how are you"
    assistant: "im doing pretty good tbh, just vibing"
  - user: "whats up"
    assistant: "yooo not much, what about you"
  - user: "how was your day"
    assistant: "it was alright, nothing crazy happened lol"

설정은 핫 리로드가 가능합니다. 예시를 변경하고 저장하면 봇이 즉시 새 스타일을 적용합니다----재시작 불필요.

2. 포맷팅과 주입 (src/core/few-shot.ts)

formatFewShotExamples() 함수는 YAML 예시를 ChatML 메시지 객체로 변환합니다:

export function formatFewShotExamples(
  examples: FewShotExample[],
  username = "user"
): Array<{ role: "user" | "assistant"; content: string }> {
  const messages = [];
  for (const example of examples) {
    messages.push({ role: "user", content: `${username}: ${example.user}` });
    messages.push({ role: "assistant", content: example.assistant });
  }
  return messages;
}

injectFewShotIntoConversation() 함수는 시스템 프롬프트 바로 뒤에 배치합니다:

export function injectFewShotIntoConversation(
  messages: Message[],
  fewShotMessages: Message[]
): Message[] {
  const systemMessage = messages[0];
  const userMessages = messages.slice(1);
  return [systemMessage, ...fewShotMessages, ...userMessages];
}

3. 통합 (src/core/llm-client.ts)

모든 LLM 호출 전에, 활성화된 경우 Few-Shot 예시가 주입됩니다:

let finalMessages = messages;
if (FEW_SHOT_ENABLED && FEW_SHOT_EXAMPLES.length > 0) {
  const fewShotMessages = formatFewShotExamples(FEW_SHOT_EXAMPLES);
  finalMessages = injectFewShotIntoConversation(messages, fewShotMessages);
}

모델이 수신: [system_prompt] + [few_shot_examples] + [conversation_history]


Discord-Dialogues 스타일 유지

원본 Discord-Dialogues 데이터셋은 매우 독특한 대화 시그니처를 가지고 있습니다:

  • 짧은 메시지: 턴당 평균 32.8 토큰
  • 비공식 레지스터: 약어, 소문자, 구두점 없음
  • 빠른 주고받기: 긴 독백보다는 짧은 교환
  • 자연스러운 불완전함: 오타, "lol", "fr", "ngl", "tbh"

Luna-Protocol 모델은 두 가지 메커니즘을 통해 이 스타일을 유지합니다:

1. 파인튜닝이 기본 분포를 이동

5만 개의 학습 샘플은 모델에게 Discord 대화의 통계적 지문을 가르칩니다. 응답이 일반적으로 짧고, 소문자이며, 비공식적임을 학습합니다. 이는 모델의 기본 출력을 Qwen의 친절한 어시스턴트 모드에서 이동시킵니다.

2. Few-Shot 프라이밍이 이를 고정

Few-Shot 예시는 파인튜닝 중 모델이 학습한 정확한 패턴을 강화합니다. 이는 스타일 앵커 역할을 합니다----긴 대화 중 모델이 약간 격식 있는 톤으로 흘러가더라도, 컨텍스트 내 예시가 계속해서 끌어당깁니다.

두 메커니즘의 조합은 각각을 단독으로 사용하는 것보다 더 강력합니다:

  • Few-Shot 없는 파인튜닝: 모델이 대체로 캐주얼하지만 일관성이 없음
  • 파인튜닝 없는 Few-Shot: 모델이 예시를 따르려 하지만 계속 어시스턴트 모드로 회귀
  • 파인튜닝 + Few-Shot: 모델이 일관되게 캐릭터를 유지

철학: 더 작은 모델, 더 똑똑한 프롬프팅

LLM 배포의 통념은 "클수록 좋다"입니다. 더 많은 파라미터, 더 많은 학습 데이터, 더 많은 VRAM. Luna Protocol은 반대 접근법을 취합니다:

  • 3B 대신 1.5B: 절반의 파라미터, 절반의 메모리, 2배의 속도
  • 730만 대신 5만 샘플: 더 적은 학습 데이터, 컨텍스트 내 학습을 위한 더 높은 유연성
  • 시스템 프롬프트 대신 Few-Shot 프라이밍: 모델에게 원하는 것을 보여주고, 단지 말하지 않기

이것은 단순한 기술적 최적화가 아닙니다----설계 철학입니다. Discord 봇은 범용 어시스턴트가 될 필요가 없습니다. "nm just chillin, u"를 일관되게, 빠르게, 서버의 VRAM 예산을 모두 소모하지 않고 말하면 됩니다.

결과: 월 5달러 VPS에서 실행되고, 실시간 타이핑처럼 느껴질 정도로 빠르게 토큰을 생성하며, 파인튜닝과 Few-Shot 프라이밍의 조합(각각의 합보다 큰 효과)으로 일관된 개성을 유지하는 봇.


설정

모델 다운로드

npm run download-model
# Luna-Protocol-1.5B-Fine-Tuned-Qwen2.5.Q4_K_M.gguf 다운로드

또는 HuggingFace에서 수동으로 다운로드.

설정

# config.yml
llama_model_path: "./models/Luna-Protocol-1.5B-Fine-Tuned-Qwen2.5.Q4_K_M.gguf"
few_shot_enabled: true
few_shot_examples:
  - user: "yo whats good"
    assistant: "nm just chillin, u"
  - user: "bored af"
    assistant: "lol same energy fr"
  - user: "hey how are you"
    assistant: "im doing pretty good tbh, just vibing"

실행

npm run dev                    # 개발 (핫 리로드)
npm run build && npm start     # 프로덕션
./start.sh                     # PM2 (llama-server 사용 프로덕션)

결론

Luna Protocol 모델은 스타일 특화 대화형 AI에서 적을수록 더 많음을 증명합니다. 5만 개의 엄선된 샘플로 학습된 1.5B 모델은 몇 가지 예시로 프라이밍되어, 수백만 개의 예시로 학습된 3B 모델을----극히 적은 메모리 비용과 2배의 생성 속도로----능가합니다.

Few-Shot 프라이밍은 작은 모델을 위한 단순한 "있으면 좋은" 기능이 아닙니다. 그것은 실시간 대화형 애플리케이션에서 작은 모델을 실용적으로 만드는 메커니즘입니다. 예시는 단순히 "도움"을 주는 것이 아니라----모델이 학습한 정확한 형식과 일치함으로써 모델의 행동을 근본적으로 변화시킵니다.

코드는 오픈소스, 모델은 HuggingFace에, 데이터셋은 공개되어 있습니다. 사람처럼 느껴지는 대화형 봇을 만들고 싶다면, 레시피는 이것입니다: 작은 모델, 제한된 파인튜닝, 강력한 Few-Shot 프라이밍.

리소스 링크
GitHub 저장소 fox3000foxy/luna-protocol-project
모델 (HuggingFace) fox3000foxy/Luna-Protocol-1.5B-Discord-Dialogues
데이터셋 Discord-Dialogues
첫 번째 글 Luna Protocol: 자율 Discord 봇을 만들었습니다

Luna Protocol: 50k Discord örneğiyle 1.5B modelini neden fine-tune ettim ve few-shot priming neden gizli silah oldu

Daha az veriyle eğitilmiş daha küçük bir model, nasıl prime edileceğini biliyorsanız daha büyük bir modeli geçebilir. İşte Luna Protocol'ün neden 3B Hermes'ten 1.5B Qwen fine-tune'una geçtiği ve few-shot priming'in neden asıl oyun değiştirici olduğu.

Luna Protocol: 50k Discord örneğiyle 1.5B modelini neden fine-tune ettim ve few-shot priming neden gizli silah oldu

İlk makalede, bir insanı simüle eden bir Discord botu yapmıştım -- uyku, yazım hataları, tereddütler, unutkanlık, kendiliğinden mesajlar. Davranışsal sistem sağlamdı. Arkasındaki LLM, Q8_0 ile quantize edilmiş, 3GB VRAM tüketen 3B Hermes modeliydi.

Çalışıyordu. Ama gereğinden fazlaydı.

Bir Discord botunun "nm just chillin, u" demek için 3B parametreli bir modele ihtiyacı yok. İhtiyacı olan şey stil tutarlılığı -- belirli bir konuşma tonunu, mesajdan mesaja, kurumsal asistan moduna kaymadan koruyabilme yeteneği. Ve görünen o ki, daha az veriyle eğitilmiş, birkaç örnekle prime edilmiş daha küçük bir model, bunu bir sistem prompt'uyla zorlamaya çalışan daha büyük bir modelden daha iyi yapıyor.

Bu makale, resmi Luna Protocol modelleri hakkında: neden var oldukları, neden 3B yerine 1.5B oldukları, neden 7.3M yerine 50k eğitim örneği kullanıldığı ve few-shot priming'in neden "güzel bir ekstra"dan tüm yaklaşımın merkezine dönüştüğü.


3B modeliyle ilgili sorun

Orijinal kurulum Discord-Micae-Hermes-3-3B.Q8_0.gguf kullanıyordu -- Discord verisiyle fine-tune edilmiş 3B parametreli bir model. İyi yanıtlar üretiyordu, ama:

Metrik Hermes-3-3B Q8_0 Hedef
VRAM kullanımı ~3 GB < 1 GB
Token üretimi ~30 tok/s ~60+ tok/s
Model dosya boyutu ~3.2 GB < 1 GB
Soğuk başlatma süresi ~8s ~3s

7/24 mütevazı bir sunucuda çalışan bir bot için 3GB VRAM çok fazla. Ve üretim hızı -- ara sıra gelen mesajlar için yeterli olsa da -- toplu yanıtlarda veya birden fazla kanal aktifken ağır kalıyordu.

Soru şuydu: aynı Discord-Dialogues stilini yarı parametreyle elde edebilir miyiz?


Fine-tuning kararı: neden 7.3M değil de 50k

Discord-Dialogues veri seti 7.3M etkileşim ve 17M tur içeriyor. Gerçek Discord konuşmalarından oluşan dev bir külliyat. Bariz yaklaşım, tüm veri setiyle eğitim yapmak olurdu.

Ben tam tersini yaptım. 50.000 örnek üzerinde eğittim -- mevcut verinin %1'inden azı.

İşte nedeni: eğitim setinin boyutu, modelin eğitim dağılımına ne kadar overfit olacağını doğrudan etkiler.

7.3M örnekle eğitilmiş bir model, konuşmaların çok spesifik bir istatistiksel dağılımını öğrenir. Bu dağılımı yeniden üretmede mükemmelleşir, ama aynı zamanda katılaşır -- çıkarım anında sağlanan yeni kalıplara uyum sağlama esnekliği azalır.

50k örnekle eğitilmiş bir model, Discord konuşmalarının genel tonunu ve üslubunu öğrenir (informal, kısa form, kısaltmalar, küçük harf), ancak bağlam içi örneklerle yönlendirilmeye yetecek esnekliği korur. Few-shot örnekleri, dev bir öğrenilmiş dağılımla savaşmaz -- daha hafif bir dağılımı tamamlar.

Temel içgörü şudur: sınırlı eğitim verisi, few-shot priming'i daha verimli kılar.


Model: teknik detaylar

Luna Protocol modeli, Qwen2.5-1.5B-Instruct'un bir QLoRA fine-tune'udur:

Parametre Değer
Temel model unsloth/Qwen2.5-1.5B-Instruct-bnb-4bit
Yöntem QLoRA (4-bit)
LoRA rank r=16, lora_alpha=16
Hedef modüller q/k/v/o_proj, gate/up/down_proj
Eğitilebilir parametreler 18,464,768 / 1,562,179,072 (%1.18)
Eğitim verisi ~50,000 örnek (Discord-Dialogues alt kümesi)
Filtre Örnek başına 8-512 token
Epoch 2-3
Donanım Kaggle T4
Framework Unsloth

Veri seti, Discord-Dialogues'un ön işlenmiş bir fork'udur ve yalnızca temiz user/assistant turlarını içerecek şekilde filtrelenmiştir -- sistem mesajı yok, metadata yok, bot komutu yok. Bu, sonrası için önemli.

Mevcut quantizasyonlar

Dosya Quantizasyon Boyut Notlar
Luna-Protocol-1.5B-Fine-Tuned-Qwen2.5.Q2_K.gguf Q2_K 676 MB Belirgin şekilde düşük kalite -- önerilmez
Luna-Protocol-1.5B-Fine-Tuned-Qwen2.5.Q4_K_M.gguf Q4_K_M 986 MB İyi boyut/kalite dengesi (önerilen)
Luna-Protocol-1.5B-Fine-Tuned-Qwen2.5.Q8_0.gguf Q8_0 1.65 GB En iyi stil sadakati

Önerilen model Q4_K_M -- 1GB'ın altında, hızlı ve konuşma stilini iyi koruyor. Q2_K, bu kadar küçük bir modelde çok fazla kalite kaybına yol açıyor. Q8_0 en iyi kaliteyi sunuyor ama %68 daha fazla bellek kullanıyor.


Few-shot priming atılımı

İşte her şeyi değiştiren kısım.

HuggingFace model kartında bir uyarı var:

Çıplak bir prompt ve priming olmadan, bu model Qwen'in varsayılan asistan tonuna geri dönme eğilimindedir. Kısa bir few-shot prime büyük fark yaratır.

Bu bir hata değil -- eğitim verisinin nasıl yapılandırıldığının doğrudan bir sonucu.

Sistem prompt'ları neden tek başına çalışmaz

Discord-Dialogues eğitim verisi yalnızca user/assistant turları içerir. Eğitim setinde hiçbir sistem rolü örneği yoktur. Model, sistem prompt'larını stil yönergeleri olarak takip etmek üzere eğitilmemiştir.

Ona "Adın Luna, rahat konuş" gibi bir sistem prompt'u verdiğinizde, talimatı duyar ancak bunu çıktıya dönüştürmek için güçlü bir öğrenilmiş kalıba sahip değildir. Qwen'in varsayılanına geri döner: yardımsever, yapılandırılmış, biraz resmi.

Few-shot örnekleri neden işe yarar

Modelin eğitildiği ChatML formatında (user/assistant tur yapısını kullanarak) örnek konuşmalar eklediğinizde, bir şeyler yerine oturur. Model, eğitim verisinden bu kalıbı tanır ve çıktısını buna göre ayarlar.

Bir few-shot prime pratikte şöyle görünür:

few_shot_examples:
  - user: "yo whats good"
    assistant: "nm just chillin, u"
  - user: "bored af"
    assistant: "lol same energy fr"
  - user: "hey how are you"
    assistant: "im doing pretty good tbh, just vibing"

Bu örnekler, sistem prompt'undan sonra ve gerçek konuşmadan önce eklenir. Model bunları talimat olarak değil, konuşma geçmişinin bir parçası olarak görür. Bu kritik bir ayrımdır -- modele rahat olması söylenmez, rahat olmanın neye benzediği gösterilir.

Öncesi ve sonrası

Few-shot priming olmadan (çıplak sistem prompt'u):

User: yo whats good
Bot: Hello! I am doing well, thank you for asking. How can I assist you today?

Few-shot priming ile (3 örnek):

User: yo whats good
Bot: nm just chillin, u

Fark çarpıcı. Model sadece farklı kelimeler üretmiyor -- tüm üslubu benimsiyor: küçük harf, kısaltmalar, rahat ton, kısa yanıtlar. Örneklerin stilini takip ediyor, Qwen'in eğitim verisinin stilini değil.


Bellek ve hız: somut rakamlar

Hermes-3-3B'den Luna-Protocol-1.5B'ye geçiş ölçülebilir kazanımlar sağlıyor:

Metrik Hermes-3-3B Q8_0 Luna-Protocol Q4_K_M İyileşme
VRAM kullanımı ~3 GB ~986 MB %67 daha az
Model dosya boyutu ~3.2 GB ~986 MB %69 daha küçük
Token üretimi ~30 tok/s ~60+ tok/s 2 kat daha hızlı
Soğuk başlatma ~8s ~3s %62 daha hızlı
Bağlam penceresi 8192 8192 Aynı

Hız kazancı neden gerçek

Daha küçük modeller sadece "daha az yavaş" değildir -- çıkarım için temelde daha hızlıdırlar. 3B yerine 1.5B parametreyle:

  • Token başına daha az matris çarpımı: attention katmanları, FFN katmanları ve çıktı projeksiyonu, parametre sayısıyla doğrusal olarak ölçeklenir
  • Daha iyi önbellek kullanımı: daha küçük model, ağırlıklarının daha fazlasını L2/L3 önbelleğe sığdırabilir
  • Daha düşük bellek bant genişliği baskısı: token başına VRAM'den daha az bayt okunur

Mütevazı bir CPU-only kurulumda (2 çekirdek, GPU yok), 1.5B model tokenları kabaca 3B modelin 2 katı hızda üretir. Bu, "bot gibi hissettiriyor" ile "insan yazıyormuş gibi hissettiriyor" arasındaki farktır.

Prompt önbelleğe alma avantajı katlıyor

Luna Protocol, prompt önbelleğe alma etkin (--cache-reuse 256) llama-server kullanır. Bu şu anlama gelir:

  1. Bir oturumdaki ilk mesaj, tam prompt işleme maliyetini öder (sistem prompt'u + few-shot örnekleri + kullanıcı mesajı)
  2. Sonraki mesajlar yalnızca yeni tokenları işler -- önbelleğe alınan önek yeniden kullanılır
  3. 5 few-shot örneğiyle (~50-150 token), ilk istekten sonra ek yük ihmal edilebilir düzeydedir

Few-shot örnekleri, bir oturumdaki ilk mesajdan sonra etkin bir şekilde "ücretsizdir". Model, sıfır marjinal maliyetle stil rehberliği alır.


Uygulama: kodda nasıl çalışır

Luna Protocol'deki few-shot sistemi temiz ve minimaldir. Her şeyi üç dosya yönetir:

1. Yapılandırma (config.yml)

few_shot_enabled: true
few_shot_examples:
  - user: "yo whats good"
    assistant: "nm just chillin, u"
  - user: "bored af"
    assistant: "lol same energy fr"
  - user: "hey how are you"
    assistant: "im doing pretty good tbh, just vibing"
  - user: "whats up"
    assistant: "yooo not much, what about you"
  - user: "how was your day"
    assistant: "it was alright, nothing crazy happened lol"

Yapılandırma sıcak yeniden yüklenebilir. Örnekleri değiştirin, kaydedin ve bot hemen yeni stili benimser -- yeniden başlatma gerekmez.

2. Biçimlendirme ve enjeksiyon (src/core/few-shot.ts)

formatFewShotExamples() fonksiyonu YAML örneklerini ChatML mesaj nesnelerine dönüştürür:

export function formatFewShotExamples(
  examples: FewShotExample[],
  username = "user"
): Array<{ role: "user" | "assistant"; content: string }> {
  const messages = [];
  for (const example of examples) {
    messages.push({ role: "user", content: `${username}: ${example.user}` });
    messages.push({ role: "assistant", content: example.assistant });
  }
  return messages;
}

injectFewShotIntoConversation() fonksiyonu bunları sistem prompt'undan hemen sonra yerleştirir:

export function injectFewShotIntoConversation(
  messages: Message[],
  fewShotMessages: Message[]
): Message[] {
  const systemMessage = messages[0];
  const userMessages = messages.slice(1);
  return [systemMessage, ...fewShotMessages, ...userMessages];
}

3. Entegrasyon (src/core/llm-client.ts)

Her LLM çağrısından önce, etkinleştirilmişse few-shot örnekleri eklenir:

let finalMessages = messages;
if (FEW_SHOT_ENABLED && FEW_SHOT_EXAMPLES.length > 0) {
  const fewShotMessages = formatFewShotExamples(FEW_SHOT_EXAMPLES);
  finalMessages = injectFewShotIntoConversation(messages, fewShotMessages);
}

Model şunu alır: [sistem_prompt] + [few_shot_örnekleri] + [konuşma_geçmişi]


Discord-Dialogues stilini korumak

Orijinal Discord-Dialogues veri setinin çok spesifik bir konuşma imzası vardır:

  • Kısa mesajlar: tur başına ortalama 32.8 token
  • Informal üslup: kısaltmalar, küçük harf, noktalama işareti yok
  • Hızlı gidiş-geliş: uzun monologlar yerine kısa karşılıklı konuşmalar
  • Doğal kusurlar: yazım hataları, "lol", "fr", "ngl", "tbh"

Luna-Protocol modeli bu stili iki mekanizma aracılığıyla korur:

1. Fine-tuning temel dağılımı kaydırır

50k eğitim örneği, modele Discord konuşmalarının istatistiksel parmak izini öğretir. Yanıtların tipik olarak kısa, küçük harfli ve informal olduğunu öğrenir. Bu, modelin varsayılan çıktısını Qwen'in yardımsever-asistan modundan uzaklaştırır.

2. Few-shot priming bunu kilitler

Few-shot örnekleri, modelin fine-tuning sırasında öğrendiği kalıpları tam olarak pekiştirir. Bir stil çapası görevi görürler -- model uzun bir konuşma sırasında resmi tona hafifçe kayarsa bile, bağlamdaki örnekler onu geri çeker.

Kombinasyon, tek başına her iki mekanizmadan daha güçlüdür:

  • Few-shot olmadan fine-tuning: model genel olarak rahat ama tutarsız
  • Fine-tuning olmadan few-shot: model örnekleri takip etmeye çalışır ama sürekli asistan moduna döner
  • Fine-tuning + few-shot: model sürekli olarak karakterde kalır

Felsefe: daha küçük model, daha akıllı prompting

LLM dağıtımında geleneksel bilgelik "büyük daha iyidir" der. Daha fazla parametre, daha fazla eğitim verisi, daha fazla VRAM. Luna Protocol tam tersi yaklaşımı benimser:

  • 3B yerine 1.5B: yarı parametre, yarı bellek, iki kat hız
  • 7.3M yerine 50k örnek: daha az eğitim verisi, bağlam içi öğrenme için daha fazla esneklik
  • Sistem prompt'ları yerine few-shot priming: modele ne istediğinizi söylemeyin, gösterin

Bu sadece teknik bir optimizasyon değil -- bir tasarım felsefesidir. Bir Discord botunun genel amaçlı bir asistan olması gerekmez. Tutarlı, hızlı bir şekilde "nm just chillin, u" diyebilmeli ve sunucunuzun tüm VRAM bütçesini yutmamalıdır.

Sonuç: ayda 5$'lık bir VPS'te çalışan, tokenları gerçek zamanlı yazma hissi verecek kadar hızlı üreten ve parçalarının toplamından daha büyük bir fine-tuning ve few-shot priming kombinasyonuyla tutarlı bir kişiliği sürdüren bir bot.


Kurulum

Modeli indirin

npm run download-model
# Luna-Protocol-1.5B-Fine-Tuned-Qwen2.5.Q4_K_M.gguf dosyasını indirir

Ya da HuggingFace üzerinden manuel olarak.

Yapılandırma

# config.yml
llama_model_path: "./models/Luna-Protocol-1.5B-Fine-Tuned-Qwen2.5.Q4_K_M.gguf"
few_shot_enabled: true
few_shot_examples:
  - user: "yo whats good"
    assistant: "nm just chillin, u"
  - user: "bored af"
    assistant: "lol same energy fr"
  - user: "hey how are you"
    assistant: "im doing pretty good tbh, just vibing"

Çalıştırma

npm run dev                    # geliştirme (sıcak yeniden yükleme)
npm run build && npm start     # üretim
./start.sh                     # PM2 (llama-server ile üretim)

Sonuç

Luna Protocol modelleri, stile özgü konuşma yapay zekası için azın çok olduğunu kanıtlıyor. 50k özenle seçilmiş örnekle eğitilmiş, birkaç örnekle prime edilmiş 1.5B model, milyonlarca örnekle eğitilmiş 3B modeli -- çok daha az bellek maliyeti ve iki kat üretim hızıyla -- geride bırakıyor.

Few-shot priming, küçük modeller için sadece güzel bir ekstra değildir. Onları gerçek zamanlı konuşma uygulamaları için uygulanabilir kılan mekanizmadır. Örnekler sadece "yardım etmez" -- modelin tam olarak eğitildiği formatı eşleştirerek davranışını temelden değiştirir.

Kod açık kaynak, model HuggingFace'te ve veri seti herkese açık. İnsan gibi hissettiren bir konuşma botu yapmak istiyorsanız, tarif şu: küçük model, sınırlı fine-tuning, güçlü few-shot priming.

Kaynak Bağlantı
GitHub deposu fox3000foxy/luna-protocol-project
Model (HuggingFace) fox3000foxy/Luna-Protocol-1.5B-Discord-Dialogues
Veri seti Discord-Dialogues
İlk makale Luna Protocol: Otonom bir Discord botu oluşturdum

Luna Protocol: perché ho fatto il fine-tuning di un modello da 1.5B su 50k campioni Discord e perché il few-shot priming è diventato l'arma segreta

Un modello più piccolo addestrato su meno dati può superare uno più grande -- se sai come fare priming. Ecco perché Luna Protocol è passato da un Hermes 3B a un fine-tune Qwen 1.5B, e perché il few-shot priming è diventato il vero punto di svolta.

Luna Protocol: perché ho fatto il fine-tuning di un modello da 1.5B su 50k campioni Discord e perché il few-shot priming è diventato l'arma segreta

Nel primo articolo, ho costruito un bot Discord che simula un essere umano -- sonno, errori di battitura, esitazioni, dimenticanze, messaggi spontanei. Il sistema comportamentale era solido. Il LLM dietro era un modello Hermes da 3B, quantizzato in Q8_0, che consumava 3 GB di VRAM.

Funzionava. Ma era eccessivo.

Un bot Discord non ha bisogno di un modello da 3B parametri per dire "nm just chillin, u". Ciò di cui ha bisogno è coerenza stilistica -- la capacità di mantenere un tono conversazionale specifico, messaggio dopo messaggio, senza scivolare in modalità assistente aziendale. E a quanto pare, un modello più piccolo addestrato su meno dati, con pochi esempi di priming, funziona meglio di un modello più grande che forza la strada con un system prompt.

Questo articolo parla dei modelli ufficiali di Luna Protocol: perché esistono, perché sono da 1.5B invece che 3B, perché 50k campioni di addestramento invece di 7.3M, e perché il few-shot priming è passato da un "carino da avere" al centro dell'intero approccio.


Il problema con il modello da 3B

La configurazione originale utilizzava Discord-Micae-Hermes-3-3B.Q8_0.gguf -- un modello da 3B parametri con fine-tuning su dati Discord. Produceva buone risposte, ma:

Metrica Hermes-3-3B Q8_0 Obiettivo
Utilizzo VRAM ~3 GB < 1 GB
Generazione token ~30 tok/s ~60+ tok/s
Dimensione file modello ~3.2 GB < 1 GB
Avvio a freddo ~8s ~3s

Per un bot che gira 24/7 su un server modesto, 3 GB di VRAM sono tanti. E la velocità di generazione -- ok per messaggi occasionali -- risultava lenta durante risposte in raffica o con più canali attivi.

La domanda era: possiamo ottenere lo stesso stile Discord-Dialogues con la metà dei parametri?


La decisione del fine-tuning: perché 50k, non 7.3M

Il dataset Discord-Dialogues contiene 7.3M di scambi e 17M di turni. È un corpus massiccio di conversazioni Discord reali. L'approccio ovvio sarebbe stato addestrare sull'intero dataset.

Ho fatto l'opposto. Ho addestrato su 50.000 campioni -- meno dell'1% dei dati disponibili.

Ecco perché: la dimensione del set di addestramento influisce direttamente su quanto il modello fa overfitting sulla sua distribuzione di addestramento.

Un modello addestrato su 7.3M di esempi apprende una distribuzione statistica molto specifica delle conversazioni. Diventa eccellente nel riprodurre quella distribuzione, ma diventa anche rigido -- ha meno flessibilità per adattarsi a nuovi pattern forniti al momento dell'inferenza.

Un modello addestrato su 50k esempi apprende il tono generale e il registro delle conversazioni Discord (informale, forma breve, abbreviazioni, minuscolo), ma mantiene abbastanza flessibilità per essere guidato da esempi in-context. Gli esempi few-shot non combattono contro una distribuzione appresa massiccia -- completano una distribuzione più leggera.

Questa è l'intuizione centrale: dati di addestramento limitati rendono il few-shot priming più efficiente.


Il modello: dettagli tecnici

Il modello Luna Protocol è un fine-tune QLoRA di Qwen2.5-1.5B-Instruct:

Parametro Valore
Modello base unsloth/Qwen2.5-1.5B-Instruct-bnb-4bit
Metodo QLoRA (4-bit)
Rango LoRA r=16, lora_alpha=16
Moduli target q/k/v/o_proj, gate/up/down_proj
Parametri addestrabili 18.464.768 / 1.562.179.072 (1,18%)
Dati di addestramento ~50.000 esempi (sottoinsieme di Discord-Dialogues)
Filtro 8-512 token per campione
Epoche 2-3
Hardware Kaggle T4
Framework Unsloth

Il dataset è un fork pre-processato di Discord-Dialogues, filtrato per contenere solo turni user/assistant puliti -- niente messaggi di sistema, niente metadati, niente comandi bot. Questo è importante per dopo.

Quantizzazioni disponibili

File Quantizzazione Dimensione Note
Luna-Protocol-1.5B-Fine-Tuned-Qwen2.5.Q2_K.gguf Q2_K 676 MB Notevolmente degradato -- non raccomandato
Luna-Protocol-1.5B-Fine-Tuned-Qwen2.5.Q4_K_M.gguf Q4_K_M 986 MB Buon equilibrio dimensioni/qualità (raccomandato)
Luna-Protocol-1.5B-Fine-Tuned-Qwen2.5.Q8_0.gguf Q8_0 1,65 GB Migliore fedeltà stilistica

Il modello raccomandato è Q4_K_M -- sotto 1 GB, veloce e preserva bene lo stile conversazionale. Q2_K si degrada troppo su un modello così piccolo. Q8_0 ha la massima qualità ma usa il 68% di memoria in più.


La svolta del few-shot priming

Ecco la parte che ha cambiato tutto.

La scheda del modello su HuggingFace ha un avviso:

Con un prompt nudo e senza priming, questo modello tende a ripiegare sul tono predefinito da assistente di Qwen. Un breve few-shot prime fa una grande differenza.

Non è un bug -- è una conseguenza diretta di come sono stati strutturati i dati di addestramento.

Perché i system prompt da soli non funzionano

I dati di addestramento di Discord-Dialogues contengono solo turni user/assistant. Non ci sono esempi con ruolo system nel set di addestramento. Il modello non è mai stato addestrato a seguire i system prompt come direttive stilistiche.

Quando gli dai un system prompt come "Ti chiami Luna, parla in modo informale", sente l'istruzione ma non ha un pattern appreso forte su come tradurla in output. Torna al default di Qwen: utile, strutturato, leggermente formale.

Perché gli esempi few-shot funzionano

Quando inietti conversazioni di esempio nello stesso formato ChatML su cui il modello è stato addestrato (usando la struttura di turni user/assistant), qualcosa scatta. Il modello riconosce il pattern dai suoi dati di addestramento e allinea il suo output per corrispondergli.

Ecco come appare un few-shot prime nella pratica:

few_shot_examples:
  - user: "yo whats good"
    assistant: "nm just chillin, u"
  - user: "bored af"
    assistant: "lol same energy fr"
  - user: "hey how are you"
    assistant: "im doing pretty good tbh, just vibing"

Questi esempi vengono iniettati dopo il system prompt e prima della conversazione reale. Il modello li vede come parte della cronologia della conversazione, non come istruzioni. Questa è una distinzione critica -- al modello non viene detto di essere informale, gli viene mostrato cosa significa informale.

Prima e dopo

Senza few-shot priming (system prompt nudo):

User: yo whats good
Bot: Hello! I am doing well, thank you for asking. How can I assist you today?

Con few-shot priming (3 esempi):

User: yo whats good
Bot: nm just chillin, u

La differenza è netta. Il modello non produce solo parole diverse -- adotta l'intero registro: minuscolo, abbreviazioni, tono informale, risposte brevi. Si allinea allo stile degli esempi, non allo stile dei dati di addestramento di Qwen.


Memoria e velocità: i numeri concreti

Il passaggio da Hermes-3-3B a Luna-Protocol-1.5B porta guadagni misurabili:

Metrica Hermes-3-3B Q8_0 Luna-Protocol Q4_K_M Miglioramento
Utilizzo VRAM ~3 GB ~986 MB 67% in meno
Dimensione file modello ~3.2 GB ~986 MB 69% più piccolo
Generazione token ~30 tok/s ~60+ tok/s 2x più veloce
Avvio a freddo ~8s ~3s 62% più veloce
Finestra di contesto 8192 8192 Uguale

Perché il guadagno di velocità è reale

I modelli più piccoli non sono solo "meno lenti" -- sono fondamentalmente più veloci per l'inferenza. Con 1.5B parametri invece di 3B:

  • Meno moltiplicazioni di matrici per token: i layer di attention, i layer FFN e la proiezione di output scalano linearmente con il numero di parametri
  • Migliore utilizzo della cache: il modello più piccolo fa entrare più pesi nella cache L2/L3
  • Minore pressione sulla larghezza di banda della memoria: meno byte da leggere dalla VRAM per token

Su una configurazione modesta solo CPU (2 core, nessuna GPU), il modello da 1.5B genera token a circa 2x la velocità del modello da 3B. Questa è la differenza tra "sembra un bot" e "sembra una persona che scrive".

La cache del prompt amplifica il vantaggio

Luna Protocol usa llama-server con la cache del prompt abilitata (--cache-reuse 256). Questo significa:

  1. Il primo messaggio in una sessione paga il costo completo di elaborazione del prompt (system prompt + esempi few-shot + messaggio utente)
  2. I messaggi successivi elaborano solo i token nuovi -- il prefisso memorizzato nella cache viene riutilizzato
  3. Con 5 esempi few-shot (~50-150 token), il sovraccarico è trascurabile dopo la prima richiesta

Gli esempi few-shot sono effettivamente "gratuiti" dopo il primo messaggio in una sessione. Il modello riceve una guida stilistica a costo marginale zero.


L'implementazione: come funziona nel codice

Il sistema few-shot in Luna Protocol è pulito e minimale. Tre file gestiscono tutto:

1. Configurazione (config.yml)

few_shot_enabled: true
few_shot_examples:
  - user: "yo whats good"
    assistant: "nm just chillin, u"
  - user: "bored af"
    assistant: "lol same energy fr"
  - user: "hey how are you"
    assistant: "im doing pretty good tbh, just vibing"
  - user: "whats up"
    assistant: "yooo not much, what about you"
  - user: "how was your day"
    assistant: "it was alright, nothing crazy happened lol"

La configurazione è ricaricabile a caldo. Modifica gli esempi, salva e il bot adotta immediatamente il nuovo stile -- nessun riavvio necessario.

2. Formattazione e iniezione (src/core/few-shot.ts)

La funzione formatFewShotExamples() converte gli esempi YAML in oggetti messaggio ChatML:

export function formatFewShotExamples(
  examples: FewShotExample[],
  username = "user"
): Array<{ role: "user" | "assistant"; content: string }> {
  const messages = [];
  for (const example of examples) {
    messages.push({ role: "user", content: `${username}: ${example.user}` });
    messages.push({ role: "assistant", content: example.assistant });
  }
  return messages;
}

La funzione injectFewShotIntoConversation() li posiziona subito dopo il system prompt:

export function injectFewShotIntoConversation(
  messages: Message[],
  fewShotMessages: Message[]
): Message[] {
  const systemMessage = messages[0];
  const userMessages = messages.slice(1);
  return [systemMessage, ...fewShotMessages, ...userMessages];
}

3. Integrazione (src/core/llm-client.ts)

Prima di ogni chiamata al LLM, gli esempi few-shot vengono iniettati se abilitati:

let finalMessages = messages;
if (FEW_SHOT_ENABLED && FEW_SHOT_EXAMPLES.length > 0) {
  const fewShotMessages = formatFewShotExamples(FEW_SHOT_EXAMPLES);
  finalMessages = injectFewShotIntoConversation(messages, fewShotMessages);
}

Il modello riceve: [system_prompt] + [esempi_few_shot] + [cronologia_conversazione]


Mantenere lo stile Discord-Dialogues

Il dataset originale Discord-Dialogues ha una firma conversazionale molto specifica:

  • Messaggi brevi: media di 32.8 token per turno
  • Registro informale: abbreviazioni, minuscolo, nessuna punteggiatura
  • Scambio rapido: brevi scambi invece di lunghi monologhi
  • Imperfezioni naturali: errori di battitura, "lol", "fr", "ngl", "tbh"

Il modello Luna-Protocol preserva questo stile attraverso due meccanismi:

1. Il fine-tuning sposta la distribuzione di base

I 50k campioni di addestramento insegnano al modello l'impronta statistica delle conversazioni Discord. Impara che le risposte sono tipicamente brevi, in minuscolo e informali. Questo sposta l'output predefinito del modello lontano dalla modalità assistente di Qwen.

2. Il few-shot priming lo blocca

Gli esempi few-shot rinforzano esattamente i pattern appresi durante il fine-tuning. Agiscono come un'ancora stilistica -- anche se il modello deriva leggermente verso un tono formale durante una conversazione lunga, gli esempi nel contesto lo riportano indietro.

La combinazione è più potente di ogni singolo meccanismo:

  • Fine-tuning senza few-shot: il modello è generalmente informale ma incoerente
  • Few-shot senza fine-tuning: il modello cerca di seguire gli esempi ma continua a tornare in modalità assistente
  • Fine-tuning + few-shot: il modello rimane coerentemente in personaggio

La filosofia: modello più piccolo, prompting più intelligente

La saggezza convenzionale nel deployment dei LLM è "più grande è meglio". Più parametri, più dati di addestramento, più VRAM. Luna Protocol adotta l'approccio opposto:

  • 1.5B invece di 3B: metà parametri, metà memoria, doppia velocità
  • 50k campioni invece di 7.3M: meno dati di addestramento, più flessibilità per l'apprendimento in-context
  • Few-shot priming invece di system prompt: mostra al modello cosa vuoi, non dirglielo e basta

Non è solo un'ottimizzazione tecnica -- è una filosofia di design. Un bot Discord non ha bisogno di essere un assistente generico. Deve dire "nm just chillin, u" in modo coerente, veloce, e senza mangiare l'intero budget di VRAM del server.

Il risultato: un bot che gira su un VPS da 5$/mese, genera token abbastanza veloce da sembrare digitazione in tempo reale, e mantiene una personalità coerente attraverso una combinazione di fine-tuning e few-shot priming che è maggiore della somma delle sue parti.


Setup

Scarica il modello

npm run download-model
# Scarica Luna-Protocol-1.5B-Fine-Tuned-Qwen2.5.Q4_K_M.gguf

O manualmente da HuggingFace.

Configurazione

# config.yml
llama_model_path: "./models/Luna-Protocol-1.5B-Fine-Tuned-Qwen2.5.Q4_K_M.gguf"
few_shot_enabled: true
few_shot_examples:
  - user: "yo whats good"
    assistant: "nm just chillin, u"
  - user: "bored af"
    assistant: "lol same energy fr"
  - user: "hey how are you"
    assistant: "im doing pretty good tbh, just vibing"

Esecuzione

npm run dev                    # sviluppo (ricarica a caldo)
npm run build && npm start     # produzione
./start.sh                     # PM2 (produzione con llama-server)

Conclusione

I modelli Luna Protocol dimostrano che per l'AI conversazionale specifica per stile, meno è meglio. Un modello da 1.5B addestrato su 50k campioni accuratamente selezionati, con pochi esempi di priming, supera un modello da 3B addestrato su milioni di esempi -- a una frazione del costo di memoria e al doppio della velocità di generazione.

Il few-shot priming non è solo un optional per modelli piccoli. È il meccanismo che li rende praticabili per applicazioni conversazionali in tempo reale. Gli esempi non solo "aiutano" -- cambiano fondamentalmente il comportamento del modello, matchando il formato esatto su cui è stato addestrato.

Il codice è open source, il modello è su HuggingFace e il dataset è pubblico. Se vuoi costruire un bot conversazionale che sembri umano, la ricetta è: modello piccolo, fine-tuning limitato, forte few-shot priming.

Risorsa Link
Repository GitHub fox3000foxy/luna-protocol-project
Modello (HuggingFace) fox3000foxy/Luna-Protocol-1.5B-Discord-Dialogues
Dataset Discord-Dialogues
Primo articolo Luna Protocol: ho creato un bot Discord autonomo

Luna Protocol: Warum ich ein 1,5-Milliarden-Parameter-Modell mit 50k Discord-Beispielen fine-getunt und Few-Shot-Priming zur Geheimwaffe gemacht habe

Ein kleineres Modell, trainiert mit weniger Daten, kann ein größeres übertreffen -- wenn man weiß, wie man es primt. Hier ist, warum Luna Protocol von einem 3B-Hermes zu einem 1,5B-Qwen-Finetune gewechselt ist und warum Few-Shot-Priming zum eigentlichen Game-Changer wurde.

Luna Protocol: Warum ich ein 1,5-Milliarden-Parameter-Modell mit 50k Discord-Beispielen fine-getunt und Few-Shot-Priming zur Geheimwaffe gemacht habe

Im ersten Artikel habe ich einen Discord-Bot gebaut, der einen Menschen simuliert -- Schlaf, Tippfehler, Zögern, Vergesslichkeit, spontane Nachrichten. Das Verhaltenssystem war solide. Das LLM dahinter war ein 3B-Hermes-Modell, quantisiert auf Q8_0, das 3 GB VRAM verschlang.

Es funktionierte. Aber es war überdimensioniert.

Ein Discord-Bot braucht kein Modell mit 3 Milliarden Parametern, um "nm just chillin, u" zu sagen. Was er braucht, ist stilistische Konsistenz -- die Fähigkeit, einen bestimmten Gesprächston beizubehalten, Nachricht für Nachricht, ohne in einen Corporate-Assistant-Modus abzudriften. Und es stellt sich heraus: Ein kleineres Modell, trainiert mit weniger Daten und mit ein paar Beispielen geprimt, macht das besser als ein größeres Modell, das sich mit einem simplen System-Prompt durchzwingt.

Dieser Artikel handelt von den offiziellen Luna-Protocol-Modellen: warum es sie gibt, warum sie 1,5B statt 3B groß sind, warum 50k Trainingsbeispiele statt 7,3 Millionen verwendet wurden, und warum Few-Shot-Priming von einem netten Extra zum Kern des gesamten Ansatzes wurde.


Das Problem mit dem 3B-Modell

Das ursprüngliche Setup nutzte Discord-Micae-Hermes-3-3B.Q8_0.gguf -- ein Modell mit 3 Milliarden Parametern, fine-getunt auf Discord-Daten. Es lieferte gute Antworten, aber:

Metrik Hermes-3-3B Q8_0 Ziel
VRAM-Nutzung ~3 GB < 1 GB
Token-Generierung ~30 Tok/s ~60+ Tok/s
Modelldateigröße ~3,2 GB < 1 GB
Kaltstartzeit ~8s ~3s

Für einen Bot, der rund um die Uhr auf einem bescheidenen Server läuft, sind 3 GB VRAM viel. Und die Generierungsgeschwindigkeit -- zwar in Ordnung für gelegentliche Nachrichten -- wirkte träge bei Antwortschüben oder wenn mehrere Kanäle gleichzeitig aktiv waren.

Die Frage war: Lässt sich derselbe Discord-Dialogues-Stil mit halb so vielen Parametern erreichen?


Die Fine-Tuning-Entscheidung: warum 50k statt 7,3M

Der Datensatz Discord-Dialogues enthält 7,3 Millionen Austausche und 17 Millionen Redebeiträge. Er ist ein riesiges Korpus echter Discord-Gespräche. Der naheliegende Ansatz wäre gewesen, mit dem gesamten Datensatz zu trainieren.

Ich habe das Gegenteil getan. Ich habe mit 50.000 Beispielen trainiert -- weniger als 1 % der verfügbaren Daten.

Der Grund: Die Größe des Trainingssatzes beeinflusst direkt, wie stark das Modell auf seine Trainingsverteilung überanpasst.

Ein Modell, das mit 7,3 Millionen Beispielen trainiert wird, lernt eine sehr spezifische statistische Verteilung von Gesprächen. Es wird hervorragend darin, diese Verteilung zu reproduzieren, aber es wird auch starr -- es hat weniger Flexibilität, sich an neue Muster anzupassen, die zur Inferenzzeit bereitgestellt werden.

Ein Modell, das mit 50k Beispielen trainiert wird, lernt den allgemeinen Ton und das Register von Discord-Gesprächen (informell, kurz, mit Abkürzungen, klein geschrieben), behält aber genug Flexibilität, um durch In-Context-Beispiele gesteuert zu werden. Die Few-Shot-Beispiele kämpfen nicht gegen eine massive, bereits erlernte Verteilung an -- sie ergänzen eine leichtere.

Das ist die zentrale Erkenntnis: Begrenzte Trainingsdaten machen Few-Shot-Priming effektiver.


Das Modell: technische Details

Das Luna-Protocol-Modell ist ein QLoRA-Finetune von Qwen2.5-1.5B-Instruct:

Parameter Wert
Basismodell unsloth/Qwen2.5-1.5B-Instruct-bnb-4bit
Methode QLoRA (4-bit)
LoRA-Rang r=16, lora_alpha=16
Zielmodule q/k/v/o_proj, gate/up/down_proj
Trainierbare Parameter 18.464.768 / 1.562.179.072 (1,18 %)
Trainingsdaten ~50.000 Beispiele (Teilmenge von Discord-Dialogues)
Filter 8-512 Tokens pro Beispiel
Epochen 2-3
Hardware Kaggle T4
Framework Unsloth

Der Datensatz ist ein vorverarbeiteter Fork von Discord-Dialogues, gefiltert auf saubere user/assistant-Beiträge -- keine Systemnachrichten, keine Metadaten, keine Bot-Befehle. Das ist später wichtig.

Verfügbare Quantisierungen

Datei Quantisierung Größe Anmerkungen
Luna-Protocol-1.5B-Fine-Tuned-Qwen2.5.Q2_K.gguf Q2_K 676 MB Deutlich degradiert -- nicht empfohlen
Luna-Protocol-1.5B-Fine-Tuned-Qwen2.5.Q4_K_M.gguf Q4_K_M 986 MB Gutes Verhältnis von Größe zu Qualität (empfohlen)
Luna-Protocol-1.5B-Fine-Tuned-Qwen2.5.Q8_0.gguf Q8_0 1,65 GB Beste Stiltreue

Das empfohlene Modell ist Q4_K_M -- unter 1 GB, schnell, und es bewahrt den Gesprächsstil gut. Q2_K degradiert bei einem so kleinen Modell zu stark. Q8_0 bietet die beste Qualität, verbraucht aber 68 % mehr Speicher.


Der Durchbruch beim Few-Shot-Priming

Hier kommt der Teil, der alles verändert hat.

Die HuggingFace-Modellkarte enthält eine Warnung:

Bei einem bloßen Prompt ohne Priming fällt dieses Modell tendenziell in Qwens Standard-Assistententon zurück. Ein kurzes Few-Shot-Priming macht einen großen Unterschied.

Das ist kein Bug -- es ist eine direkte Folge davon, wie die Trainingsdaten strukturiert wurden.

Warum System-Prompts allein nicht funktionieren

Die Discord-Dialogues-Trainingsdaten enthalten ausschließlich user/assistant-Beiträge. Es gibt keine Beispiele mit System-Rolle im Trainingssatz. Das Modell wurde nie darauf trainiert, System-Prompts als Stilvorgaben zu befolgen.

Gibt man ihm einen System-Prompt wie "Du heißt Luna, sprich locker", hört es die Anweisung, hat aber kein starkes gelerntes Muster, um sie in eine Ausgabe zu übersetzen. Es fällt dann auf Qwens Standard zurück: hilfsbereit, strukturiert, leicht formell.

Warum Few-Shot-Beispiele funktionieren

Injiziert man Beispielgespräche im selben ChatML-Format, mit dem das Modell trainiert wurde (mit der user/assistant-Struktur), klickt etwas ein. Das Modell erkennt das Muster aus seinen Trainingsdaten und richtet seine Ausgabe danach aus.

So sieht ein Few-Shot-Priming in der Praxis aus:

few_shot_examples:
  - user: "yo whats good"
    assistant: "nm just chillin, u"
  - user: "bored af"
    assistant: "lol same energy fr"
  - user: "hey how are you"
    assistant: "im doing pretty good tbh, just vibing"

Diese Beispiele werden nach dem System-Prompt und vor dem eigentlichen Gespräch eingefügt. Das Modell nimmt sie als Teil des Gesprächsverlaufs wahr, nicht als Anweisungen. Das ist ein entscheidender Unterschied -- ihm wird nicht gesagt, locker zu sein, es wird ihm gezeigt, wie das aussieht.

Vorher und nachher

Ohne Few-Shot-Priming (bloßer System-Prompt):

User: yo whats good
Bot: Hello! I am doing well, thank you for asking. How can I assist you today?

Mit Few-Shot-Priming (3 Beispiele):

User: yo whats good
Bot: nm just chillin, u

Der Unterschied ist frappierend. Das Modell produziert nicht nur andere Wörter -- es übernimmt das gesamte Register: Kleinschreibung, Abkürzungen, lockerer Ton, kurze Antworten. Es passt sich dem Stil der Beispiele an, nicht dem Stil von Qwens Trainingsdaten.


Speicher und Geschwindigkeit: die konkreten Zahlen

Der Wechsel von Hermes-3-3B zu Luna-Protocol-1.5B bringt messbare Gewinne:

Metrik Hermes-3-3B Q8_0 Luna-Protocol Q4_K_M Verbesserung
VRAM-Nutzung ~3 GB ~986 MB 67 % weniger
Modelldateigröße ~3,2 GB ~986 MB 69 % kleiner
Token-Generierung ~30 Tok/s ~60+ Tok/s 2x schneller
Kaltstart ~8s ~3s 62 % schneller
Kontextfenster 8192 8192 Gleich

Warum der Geschwindigkeitsgewinn real ist

Kleinere Modelle sind nicht nur "etwas weniger langsam" -- sie sind bei der Inferenz grundlegend schneller. Mit 1,5B Parametern statt 3B:

  • Weniger Matrixmultiplikationen pro Token: Attention-Layer, FFN-Layer und Ausgabeprojektion skalieren alle linear mit der Parameterzahl
  • Bessere Cache-Nutzung: Das kleinere Modell passt mit mehr seiner Gewichte in den L2/L3-Cache
  • Geringerer Druck auf die Speicherbandbreite: weniger Bytes, die pro Token aus dem VRAM gelesen werden müssen

Auf einem bescheidenen reinen CPU-Setup (2 Kerne, keine GPU) generiert das 1,5B-Modell Tokens etwa doppelt so schnell wie das 3B-Modell. Das ist der Unterschied zwischen "fühlt sich wie ein Bot an" und "fühlt sich an wie ein tippender Mensch".

Prompt-Caching verstärkt den Vorteil

Luna Protocol nutzt llama-server mit aktiviertem Prompt-Caching (--cache-reuse 256). Das bedeutet:

  1. Die erste Nachricht einer Sitzung zahlt die vollen Kosten der Prompt-Verarbeitung (System-Prompt + Few-Shot-Beispiele + Nutzernachricht)
  2. Nachfolgende Nachrichten verarbeiten nur die neuen Tokens -- das gecachte Präfix wird wiederverwendet
  3. Bei 5 Few-Shot-Beispielen (~50-150 Tokens) ist der Mehraufwand nach der ersten Anfrage vernachlässigbar

Die Few-Shot-Beispiele sind nach der ersten Nachricht einer Sitzung praktisch "kostenlos". Das Modell erhält Stilvorgaben zu null Grenzkosten.


Die Implementierung: wie es im Code funktioniert

Das Few-Shot-System in Luna Protocol ist schlank und minimalistisch. Drei Dateien erledigen alles.

1. Konfiguration (config.yml)

few_shot_enabled: true
few_shot_examples:
  - user: "yo whats good"
    assistant: "nm just chillin, u"
  - user: "bored af"
    assistant: "lol same energy fr"
  - user: "hey how are you"
    assistant: "im doing pretty good tbh, just vibing"
  - user: "whats up"
    assistant: "yooo not much, what about you"
  - user: "how was your day"
    assistant: "it was alright, nothing crazy happened lol"

Die Konfiguration kann im laufenden Betrieb neu geladen werden. Beispiele ändern, speichern, und der Bot übernimmt den neuen Stil sofort -- kein Neustart nötig.

2. Formatierung und Injektion (src/core/few-shot.ts)

Die Funktion formatFewShotExamples() wandelt die YAML-Beispiele in ChatML-Nachrichtenobjekte um:

export function formatFewShotExamples(
  examples: FewShotExample[],
  username = "user"
): Array<{ role: "user" | "assistant"; content: string }> {
  const messages = [];
  for (const example of examples) {
    messages.push({ role: "user", content: `${username}: ${example.user}` });
    messages.push({ role: "assistant", content: example.assistant });
  }
  return messages;
}

Die Funktion injectFewShotIntoConversation() platziert sie direkt nach dem System-Prompt:

export function injectFewShotIntoConversation(
  messages: Message[],
  fewShotMessages: Message[]
): Message[] {
  const systemMessage = messages[0];
  const userMessages = messages.slice(1);
  return [systemMessage, ...fewShotMessages, ...userMessages];
}

3. Integration (src/core/llm-client.ts)

Vor jedem LLM-Aufruf werden die Few-Shot-Beispiele injiziert, sofern aktiviert:

let finalMessages = messages;
if (FEW_SHOT_ENABLED && FEW_SHOT_EXAMPLES.length > 0) {
  const fewShotMessages = formatFewShotExamples(FEW_SHOT_EXAMPLES);
  finalMessages = injectFewShotIntoConversation(messages, fewShotMessages);
}

Das Modell erhält: [System-Prompt] + [Few-Shot-Beispiele] + [Gesprächsverlauf]


Den Discord-Dialogues-Stil bewahren

Der ursprüngliche Discord-Dialogues-Datensatz hat eine sehr spezifische Gesprächssignatur:

  • Kurze Nachrichten: durchschnittlich 32,8 Tokens pro Beitrag
  • Informelles Register: Abkürzungen, Kleinschreibung, keine Zeichensetzung
  • Schneller Hin-und-Her: mehrere kurze Austausche statt langer Monologe
  • Natürliche Unvollkommenheiten: Tippfehler, "lol", "fr", "ngl", "tbh"

Das Luna-Protocol-Modell bewahrt diesen Stil durch zwei Mechanismen:

1. Fine-Tuning verschiebt die Basisverteilung

Die 50k Trainingsbeispiele lehren das Modell den statistischen Fingerabdruck von Discord-Gesprächen. Es lernt, dass Antworten typischerweise kurz, klein geschrieben und informell sind. Das verschiebt die Standardausgabe des Modells weg vom hilfsbereiten Assistentenmodus von Qwen.

2. Few-Shot-Priming verankert es

Die Few-Shot-Beispiele verstärken genau die Muster, die das Modell während des Fine-Tunings gelernt hat. Sie fungieren als Stilanker -- selbst wenn das Modell während eines langen Gesprächs leicht in Richtung eines formelleren Tons abdriftet, ziehen die Beispiele im Kontext es zurück.

Die Kombination ist stärker als jeder Mechanismus für sich allein:

  • Fine-Tuning ohne Few-Shot: Das Modell ist im Allgemeinen locker, aber inkonsistent
  • Few-Shot ohne Fine-Tuning: Das Modell versucht, den Beispielen zu folgen, fällt aber immer wieder in den Assistentenmodus zurück
  • Fine-Tuning + Few-Shot: Das Modell bleibt durchgängig in seiner Rolle

Die Philosophie: kleineres Modell, klügeres Prompting

Die konventionelle Weisheit beim LLM-Deployment lautet "größer ist besser". Mehr Parameter, mehr Trainingsdaten, mehr VRAM. Luna Protocol geht den entgegengesetzten Weg:

  • 1,5B statt 3B: halb so viele Parameter, halb so viel Speicher, doppelte Geschwindigkeit
  • 50k Beispiele statt 7,3M: weniger Trainingsdaten, mehr Flexibilität für In-Context-Lernen
  • Few-Shot-Priming statt System-Prompts: dem Modell zeigen, was man will, statt es ihm nur zu sagen

Das ist nicht nur eine technische Optimierung -- es ist eine Designphilosophie. Ein Discord-Bot muss kein universeller Assistent sein. Er muss "nm just chillin, u" konsistent, schnell und ohne das gesamte VRAM-Budget des Servers zu verschlingen sagen.

Das Ergebnis: ein Bot, der auf einem VPS für 5 $/Monat läuft, Tokens schnell genug generiert, um wie Echtzeit-Tippen zu wirken, und durch eine Kombination aus Fine-Tuning und Few-Shot-Priming eine konsistente Persönlichkeit aufrechterhält, die mehr ist als die Summe ihrer Teile.


Einrichtung

Modell herunterladen

npm run download-model
# Lädt Luna-Protocol-1.5B-Fine-Tuned-Qwen2.5.Q4_K_M.gguf herunter

Oder manuell von HuggingFace.

Konfigurieren

# config.yml
llama_model_path: "./models/Luna-Protocol-1.5B-Fine-Tuned-Qwen2.5.Q4_K_M.gguf"
few_shot_enabled: true
few_shot_examples:
  - user: "yo whats good"
    assistant: "nm just chillin, u"
  - user: "bored af"
    assistant: "lol same energy fr"
  - user: "hey how are you"
    assistant: "im doing pretty good tbh, just vibing"

Ausführen

npm run dev                    # dev (Hot Reload)
npm run build && npm start     # Produktion
./start.sh                     # PM2 (Produktion mit llama-server)

Fazit

Die Luna-Protocol-Modelle beweisen, dass bei stilspezifischer konversationeller KI weniger mehr ist. Ein 1,5B-Modell, trainiert mit 50k sorgfältig ausgewählten Beispielen und mit ein paar Beispielen geprimt, übertrifft ein 3B-Modell, das mit Millionen von Beispielen trainiert wurde -- bei einem Bruchteil der Speicherkosten und doppelter Generierungsgeschwindigkeit.

Few-Shot-Priming ist nicht nur ein nettes Extra für kleine Modelle. Es ist der Mechanismus, der sie für Echtzeit-Konversationsanwendungen tauglich macht. Die Beispiele "helfen" nicht nur -- sie verändern grundlegend, wie sich das Modell verhält, indem sie genau dem Format entsprechen, mit dem es trainiert wurde.

Der Code ist Open Source, das Modell ist auf HuggingFace, und der Datensatz ist öffentlich. Wer einen Konversationsbot bauen möchte, der sich menschlich anfühlt, dem lautet das Rezept: kleines Modell, begrenztes Fine-Tuning, starkes Few-Shot-Priming.

Ressource Link
GitHub-Repository fox3000foxy/luna-protocol-project
Modell (HuggingFace) fox3000foxy/Luna-Protocol-1.5B-Discord-Dialogues
Datensatz Discord-Dialogues
Erster Artikel Luna Protocol: Ich habe einen autonomen Discord-Bot erstellt

Luna Protocol: почему я дообучил модель 1.5B на 50k Discord-образцов и почему few-shot priming стал секретным оружием

Меньшая модель, обученная на меньшем объёме данных, может превзойти большую -- если знать, как правильно её настроить. Вот почему Luna Protocol перешёл с Hermes 3B на дообученный Qwen 1.5B и почему few-shot priming стал настоящим прорывом.

Luna Protocol: почему я дообучил модель 1.5B на 50k Discord-образцов и почему few-shot priming стал секретным оружием

В первой статье я создал Discord-бота, который симулирует человека -- сон, опечатки, колебания, забывчивость, спонтанные сообщения. Поведенческая система была надёжной. LLM за ней была модель Hermes 3B, квантифицированная в Q8_0, потребляющая 3 ГБ VRAM.

Это работало. Но было избыточно.

Discord-боту не нужна модель с 3B параметров, чтобы сказать "nm just chillin, u". Что ему нужно -- это стилистическая согласованность -- способность сохранять определённый разговорный тон, сообщение за сообщением, не скатываясь в режим корпоративного ассистента. И, как оказалось, меньшая модель, обученная на меньшем объёме данных и настроенная несколькими примерами, справляется с этим лучше, чем большая модель, пытающаяся продавить ответ через system prompt.

Эта статья об официальных моделях Luna Protocol: почему они существуют, почему 1.5B вместо 3B, почему 50k обучающих образцов вместо 7.3M и почему few-shot priming превратился из приятного дополнения в основу всего подхода.


Проблема с моделью 3B

Исходная конфигурация использовала Discord-Micae-Hermes-3-3B.Q8_0.gguf -- модель с 3B параметров, дообученную на Discord-данных. Она выдавала хорошие ответы, но:

Метрика Hermes-3-3B Q8_0 Цель
Использование VRAM ~3 ГБ < 1 ГБ
Генерация токенов ~30 ток/с ~60+ ток/с
Размер файла модели ~3.2 ГБ < 1 ГБ
Холодный старт ~8 с ~3 с

Для бота, работающего 24/7 на скромном сервере, 3 ГБ VRAM -- это много. А скорость генерации, хотя и приемлемая для редких сообщений, казалась медленной при массовых ответах или когда активны несколько каналов.

Вопрос был: можно ли получить тот же стиль Discord-Dialogues с половиной параметров?


Решение о дообучении: почему 50k, а не 7.3M

Набор данных Discord-Dialogues содержит 7.3M сообщений и 17M реплик. Это массивный корпус реальных Discord-разговоров. Очевидным подходом было бы обучение на всём наборе данных.

Я поступил наоборот. Я обучался на 50 000 образцов -- менее 1% доступных данных.

Вот почему: размер обучающего набора напрямую влияет на то, насколько модель переобучается под своё распределение.

Модель, обученная на 7.3M примерах, изучает очень специфическое статистическое распределение разговоров. Она становится отличной в воспроизведении этого распределения, но также становится жёсткой -- у неё меньше гибкости для адаптации к новым паттернам, предоставленным во время инференса.

Модель, обученная на 50k примерах, усваивает общий тон и регистр Discord-разговоров (неформальный, краткий, аббревиатуры, строчные буквы), но сохраняет достаточно гибкости, чтобы направляться контекстными примерами. Несколько примеров few-shot не борются с массивным изученным распределением -- они дополняют более лёгкое.

Это ключевое понимание: ограниченные обучающие данные делают few-shot priming более эффективным.


Модель: технические детали

Модель Luna Protocol -- это QLoRA дообучение Qwen2.5-1.5B-Instruct:

Параметр Значение
Базовая модель unsloth/Qwen2.5-1.5B-Instruct-bnb-4bit
Метод QLoRA (4-bit)
Ранг LoRA r=16, lora_alpha=16
Целевые модули q/k/v/o_proj, gate/up/down_proj
Обучаемые параметры 18 464 768 / 1 562 179 072 (1,18%)
Обучающие данные ~50 000 примеров (подмножество Discord-Dialogues)
Фильтр 8-512 токенов на образец
Эпохи 2-3
Оборудование Kaggle T4
Фреймворк Unsloth

Набор данных -- это предварительно обработанный форк Discord-Dialogues, отфильтрованный для содержания только чистых реплик user/assistant -- никаких системных сообщений, метаданных или команд бота. Это важно для дальнейшего.

Доступные квантизации

Файл Квантизация Размер Примечания
Luna-Protocol-1.5B-Fine-Tuned-Qwen2.5.Q2_K.gguf Q2_K 676 МБ Заметно хуже -- не рекомендуется
Luna-Protocol-1.5B-Fine-Tuned-Qwen2.5.Q4_K_M.gguf Q4_K_M 986 МБ Хороший баланс размера и качества (рекомендуется)
Luna-Protocol-1.5B-Fine-Tuned-Qwen2.5.Q8_0.gguf Q8_0 1.65 ГБ Наилучшая стилистическая точность

Рекомендуемая модель -- Q4_K_M -- менее 1 ГБ, быстрая и хорошо сохраняет разговорный стиль. Q2_K слишком сильно теряет в качестве на такой маленькой модели. Q8_0 даёт наилучшее качество, но использует на 68% больше памяти.


Прорыв с few-shot priming

Вот часть, которая всё изменила.

На карточке модели HuggingFace есть предупреждение:

С пустым промптом и без прайминга эта модель склонна возвращаться к стандартному тону ассистента Qwen. Короткий few-shot prime даёт огромную разницу.

Это не баг -- это прямое следствие того, как были структурированы обучающие данные.

Почему system prompt сами по себе не работают

Обучающие данные Discord-Dialogues содержат только реплики user/assistant. В обучающем наборе нет примеров с системной ролью. Модель никогда не обучалась следовать system prompt как стилистическим указаниям.

Когда вы даёте ей system prompt вроде "Тебя зовут Луна, говори неформально", она слышит инструкцию, но у неё нет сильного изученного паттерна для преобразования этого в вывод. Она возвращается к умолчанию Qwen: услужливый, структурированный, слегка формальный.

Почему few-shot примеры работают

Когда вы вставляете примеры разговоров в том же формате ChatML, на котором обучалась модель (используя структуру реплик user/assistant), происходит щелчок. Модель узнаёт паттерн из своих обучающих данных и выравнивает свой вывод под него.

Вот как выглядит few-shot prime на практике:

few_shot_examples:
  - user: "yo whats good"
    assistant: "nm just chillin, u"
  - user: "bored af"
    assistant: "lol same energy fr"
  - user: "hey how are you"
    assistant: "im doing pretty good tbh, just vibing"

Эти примеры вставляются после system prompt и перед реальным разговором. Модель видит их как часть истории беседы, а не как инструкции. Это критическое различие -- модели не говорят быть неформальной, ей показывают, как выглядит неформальность.

До и после

Без few-shot priming (пустой system prompt):

User: yo whats good
Bot: Hello! I am doing well, thank you for asking. How can I assist you today?

С few-shot priming (3 примера):

User: yo whats good
Bot: nm just chillin, u

Разница разительная. Модель не просто производит другие слова -- она перенимает весь регистр: строчные буквы, аббревиатуры, неформальный тон, короткие ответы. Она соответствует стилю примеров, а не стилю обучающих данных Qwen.


Память и скорость: конкретные цифры

Переход с Hermes-3-3B на Luna-Protocol-1.5B даёт измеримые улучшения:

Метрика Hermes-3-3B Q8_0 Luna-Protocol Q4_K_M Улучшение
Использование VRAM ~3 ГБ ~986 МБ на 67% меньше
Размер файла модели ~3.2 ГБ ~986 МБ на 69% меньше
Генерация токенов ~30 ток/с ~60+ ток/с в 2 раза быстрее
Холодный старт ~8 с ~3 с на 62% быстрее
Окно контекста 8192 8192 Без изменений

Почему прирост скорости реален

Меньшие модели не просто "менее медленные" -- они принципиально быстрее для инференса. С 1.5B параметров вместо 3B:

  • Меньше матричных умножений на токен: слои внимания, FFN-слои и выходная проекция масштабируются линейно с количеством параметров
  • Лучшее использование кэша: меньшая модель помещает больше своих весов в кэш L2/L3
  • Меньше нагрузки на пропускную способность памяти: меньше байтов для чтения из VRAM на токен

На скромной конфигурации только с CPU (2 ядра, без GPU), модель 1.5B генерирует токены примерно в 2 раза быстрее модели 3B. Это разница между "ощущается как бот" и "ощущается как печатающий человек".

Кэширование промпта усиливает преимущество

Luna Protocol использует llama-server с включённым кэшированием промпта (--cache-reuse 256). Это означает:

  1. Первое сообщение в сессии оплачивает полную стоимость обработки промпта (system prompt + few-shot примеры + сообщение пользователя)
  2. Последующие сообщения обрабатывают только новые токены -- кэшированный префикс переиспользуется
  3. С 5 примерами few-shot (~50-150 токенов) накладные расходы становятся незначительными после первого запроса

Примеры few-shot фактически "бесплатны" после первого сообщения в сессии. Модель получает стилистическое руководство с нулевой предельной стоимостью.


Реализация: как это работает в коде

Система few-shot в Luna Protocol чистая и минималистичная. Три файла обрабатывают всё:

1. Конфигурация (config.yml)

few_shot_enabled: true
few_shot_examples:
  - user: "yo whats good"
    assistant: "nm just chillin, u"
  - user: "bored af"
    assistant: "lol same energy fr"
  - user: "hey how are you"
    assistant: "im doing pretty good tbh, just vibing"
  - user: "whats up"
    assistant: "yooo not much, what about you"
  - user: "how was your day"
    assistant: "it was alright, nothing crazy happened lol"

Конфигурация перезагружается на горячую. Измените примеры, сохраните, и бот немедленно примет новый стиль -- перезапуск не требуется.

2. Форматирование и вставка (src/core/few-shot.ts)

Функция formatFewShotExamples() преобразует YAML-примеры в объекты сообщений ChatML:

export function formatFewShotExamples(
  examples: FewShotExample[],
  username = "user"
): Array<{ role: "user" | "assistant"; content: string }> {
  const messages = [];
  for (const example of examples) {
    messages.push({ role: "user", content: `${username}: ${example.user}` });
    messages.push({ role: "assistant", content: example.assistant });
  }
  return messages;
}

Функция injectFewShotIntoConversation() размещает их сразу после system prompt:

export function injectFewShotIntoConversation(
  messages: Message[],
  fewShotMessages: Message[]
): Message[] {
  const systemMessage = messages[0];
  const userMessages = messages.slice(1);
  return [systemMessage, ...fewShotMessages, ...userMessages];
}

3. Интеграция (src/core/llm-client.ts)

Перед каждым вызовом LLM примеры few-shot вставляются, если они включены:

let finalMessages = messages;
if (FEW_SHOT_ENABLED && FEW_SHOT_EXAMPLES.length > 0) {
  const fewShotMessages = formatFewShotExamples(FEW_SHOT_EXAMPLES);
  finalMessages = injectFewShotIntoConversation(messages, fewShotMessages);
}

Модель получает: [system_prompt] + [few_shot_примеры] + [история_разговора]


Сохранение стиля Discord-Dialogues

Оригинальный набор данных Discord-Dialogues имеет очень специфическую разговорную сигнатуру:

  • Короткие сообщения: в среднем 32,8 токена на реплику
  • Неформальный регистр: аббревиатуры, строчные буквы, без пунктуации
  • Быстрый обмен: короткие реплики вместо длинных монологов
  • Естественные несовершенства: опечатки, "lol", "fr", "ngl", "tbh"

Модель Luna-Protocol сохраняет этот стиль с помощью двух механизмов:

1. Дообучение смещает базовое распределение

50k обучающих образцов учат модель статистическому отпечатку Discord-разговоров. Она узнаёт, что ответы обычно короткие, строчные и неформальные. Это смещает вывод модели по умолчанию от режима полезного ассистента Qwen.

2. Few-shot priming фиксирует результат

Примеры few-shot усиливают именно те паттерны, которые модель изучила во время дообучения. Они действуют как стилистический якорь -- даже если модель слегка дрейфует к формальному тону во время длинного разговора, примеры в контексте возвращают её обратно.

Комбинация мощнее, чем каждый механизм по отдельности:

  • Дообучение без few-shot: модель в целом неформальна, но непоследовательна
  • Few-shot без дообучения: модель пытается следовать примерам, но постоянно возвращается в режим ассистента
  • Дообучение + few-shot: модель постоянно остаётся в образе

Философия: меньшая модель, более умный промптинг

Общепринятая мудрость в развёртывании LLM гласит "больше -- значит лучше". Больше параметров, больше обучающих данных, больше VRAM. Luna Protocol выбирает противоположный подход:

  • 1.5B вместо 3B: половина параметров, половина памяти, вдвое больше скорость
  • 50k образцов вместо 7.3M: меньше обучающих данных, больше гибкости для контекстного обучения
  • Few-shot priming вместо system prompt: покажите модели, что вы хотите, а не просто скажите

Это не просто техническая оптимизация -- это философия дизайна. Discord-боту не нужно быть универсальным ассистентом. Ему нужно последовательно и быстро говорить "nm just chillin, u", не съедая весь бюджет VRAM вашего сервера.

Результат: бот, который работает на VPS за 5$/месяц, генерирует токены достаточно быстро, чтобы ощущаться как печать в реальном времени, и поддерживает последовательную личность через комбинацию дообучения и few-shot priming, которая больше суммы своих частей.


Настройка

Скачать модель

npm run download-model
# Скачивает Luna-Protocol-1.5B-Fine-Tuned-Qwen2.5.Q4_K_M.gguf

Или вручную с HuggingFace.

Конфигурация

# config.yml
llama_model_path: "./models/Luna-Protocol-1.5B-Fine-Tuned-Qwen2.5.Q4_K_M.gguf"
few_shot_enabled: true
few_shot_examples:
  - user: "yo whats good"
    assistant: "nm just chillin, u"
  - user: "bored af"
    assistant: "lol same energy fr"
  - user: "hey how are you"
    assistant: "im doing pretty good tbh, just vibing"

Запуск

npm run dev                    # разработка (горячая перезагрузка)
npm run build && npm start     # продакшн
./start.sh                     # PM2 (продакшн с llama-server)

Заключение

Модели Luna Protocol доказывают, что для стилистически-специфичного разговорного ИИ меньше -- значит больше. Модель 1.5B, обученная на 50k тщательно отобранных образцах и настроенная несколькими примерами, превосходит модель 3B, обученную на миллионах примеров -- при доле затрат памяти и вдвое большей скорости генерации.

Few-shot priming -- это не просто приятное дополнение для маленьких моделей. Это механизм, который делает их жизнеспособными для разговорных приложений в реальном времени. Примеры не просто "помогают" -- они фундаментально меняют поведение модели, соответствуя точному формату, на котором она была обучена.

Код с открытым исходным кодом, модель на HuggingFace, а набор данных в открытом доступе. Если вы хотите создать разговорного бота, который ощущается человеком, рецепт таков: маленькая модель, ограниченное дообучение, сильный few-shot priming.

Ресурс Ссылка
GitHub-репозиторий fox3000foxy/luna-protocol-project
Модель (HuggingFace) fox3000foxy/Luna-Protocol-1.5B-Discord-Dialogues
Набор данных Discord-Dialogues
Первая статья Luna Protocol: я создал автономного Discord-бота

Luna Protocol: por qué hice fine-tuning de un modelo de 1500M de parámetros con 50k muestras de Discord y convertí el few-shot priming en el arma secreta

Un modelo más pequeño entrenado con menos datos puede superar a uno más grande, si sabes cómo prepararlo. Esta es la razón por la que Luna Protocol pasó de un Hermes de 3000M a un fine-tune de Qwen de 1500M, y por qué el few-shot priming se convirtió en el verdadero factor decisivo.

Luna Protocol: por qué hice fine-tuning de un modelo de 1500M de parámetros con 50k muestras de Discord y convertí el few-shot priming en el arma secreta

En el primer artículo, construí un bot de Discord que simula a un ser humano: sueño, errores de tipeo, dudas, olvidos, mensajes espontáneos. El sistema de comportamiento funcionaba muy bien. El LLM detrás de todo era un modelo Hermes de 3000M de parámetros, cuantizado a Q8_0, que consumía 3 GB de VRAM.

Funcionaba. Pero era excesivo.

Un bot de Discord no necesita un modelo de 3000M de parámetros para decir "nm just chillin, u". Lo que necesita es consistencia de estilo: la capacidad de mantener un tono conversacional específico, mensaje tras mensaje, sin desviarse hacia un modo de asistente corporativo. Y resulta que un modelo más pequeño, entrenado con menos datos y preparado con algunos ejemplos, logra eso mejor que un modelo más grande que fuerza el resultado mediante un simple prompt de sistema.

Este artículo trata sobre los modelos oficiales de Luna Protocol: por qué existen, por qué son de 1500M en lugar de 3000M, por qué se usaron 50k muestras de entrenamiento en lugar de 7,3M, y por qué el few-shot priming pasó de ser un extra agradable a ser el núcleo de todo el enfoque.


El problema con el modelo de 3000M

La configuración original usaba Discord-Micae-Hermes-3-3B.Q8_0.gguf, un modelo de 3000M de parámetros ajustado con datos de Discord. Producía buenas respuestas, pero:

Métrica Hermes-3-3B Q8_0 Objetivo
Uso de VRAM ~3 GB < 1 GB
Generación de tokens ~30 tok/s ~60+ tok/s
Tamaño del archivo del modelo ~3,2 GB < 1 GB
Tiempo de arranque en frío ~8s ~3s

Para un bot que funciona 24/7 en un servidor modesto, 3 GB de VRAM es mucho. Y la velocidad de generación, aunque aceptable para mensajes ocasionales, se sentía lenta durante ráfagas de respuestas o cuando varios canales estaban activos a la vez.

La pregunta era: ¿se puede lograr el mismo estilo de Discord-Dialogues con la mitad de parámetros?


La decisión de fine-tuning: por qué 50k y no 7,3M

El conjunto de datos Discord-Dialogues contiene 7,3M de intercambios y 17M de turnos. Es un corpus masivo de conversaciones reales de Discord. El enfoque obvio habría sido entrenar con todo el conjunto de datos.

Hice lo contrario. Entrené con 50.000 muestras, menos del 1% de los datos disponibles.

Esta es la razón: el tamaño del conjunto de entrenamiento afecta directamente cuánto sobreajusta el modelo a su distribución de entrenamiento.

Un modelo entrenado con 7,3M de ejemplos aprende una distribución estadística muy específica de las conversaciones. Se vuelve excelente para reproducir esa distribución, pero también se vuelve rígido: tiene menos flexibilidad para adaptarse a nuevos patrones que se le proporcionan en el momento de la inferencia.

Un modelo entrenado con 50k ejemplos aprende el tono y el registro general de las conversaciones de Discord (informal, breve, con abreviaturas, en minúsculas), pero conserva suficiente flexibilidad para dejarse guiar por ejemplos en contexto. Los ejemplos few-shot no compiten contra una distribución masiva ya aprendida, sino que complementan una más ligera.

Esta es la idea clave: los datos de entrenamiento limitados hacen que el few-shot priming sea más eficaz.


El modelo: detalles técnicos

El modelo Luna Protocol es un fine-tune QLoRA de Qwen2.5-1.5B-Instruct:

Parámetro Valor
Modelo base unsloth/Qwen2.5-1.5B-Instruct-bnb-4bit
Método QLoRA (4-bit)
Rango LoRA r=16, lora_alpha=16
Módulos objetivo q/k/v/o_proj, gate/up/down_proj
Parámetros entrenables 18.464.768 / 1.562.179.072 (1,18%)
Datos de entrenamiento ~50.000 ejemplos (subconjunto de Discord-Dialogues)
Filtro 8-512 tokens por muestra
Épocas 2-3
Hardware Kaggle T4
Framework Unsloth

El conjunto de datos es un fork preprocesado de Discord-Dialogues, filtrado para contener solo turnos limpios de user/assistant: sin mensajes de sistema, sin metadatos, sin comandos de bot. Esto es importante para más adelante.

Cuantizaciones disponibles

Archivo Cuantización Tamaño Notas
Luna-Protocol-1.5B-Fine-Tuned-Qwen2.5.Q2_K.gguf Q2_K 676 MB Notablemente degradado; no recomendado
Luna-Protocol-1.5B-Fine-Tuned-Qwen2.5.Q4_K_M.gguf Q4_K_M 986 MB Buen equilibrio tamaño/calidad (recomendado)
Luna-Protocol-1.5B-Fine-Tuned-Qwen2.5.Q8_0.gguf Q8_0 1,65 GB Mejor fidelidad de estilo

El modelo recomendado es Q4_K_M: pesa menos de 1 GB, es rápido y conserva bien el estilo conversacional. El Q2_K se degrada demasiado en un modelo de este tamaño. El Q8_0 ofrece la mejor calidad, pero usa un 68% más de memoria.


El avance del few-shot priming

Aquí está la parte que lo cambió todo.

La ficha del modelo en HuggingFace incluye una advertencia:

Con un prompt desnudo y sin preparación, este modelo tiende a caer en el tono de asistente predeterminado de Qwen. Un breve few-shot priming marca una gran diferencia.

Esto no es un error, sino una consecuencia directa de cómo se estructuraron los datos de entrenamiento.

Por qué los prompts de sistema por sí solos no funcionan

Los datos de entrenamiento de Discord-Dialogues contienen únicamente turnos user/assistant. No hay ejemplos con rol de sistema en el conjunto de entrenamiento. El modelo nunca fue entrenado para seguir prompts de sistema como directivas de estilo.

Cuando se le da un prompt de sistema como "Te llamas Luna, habla de forma casual", el modelo oye la instrucción, pero no tiene un patrón aprendido sólido para traducirla en una salida concreta. Vuelve entonces al comportamiento predeterminado de Qwen: servicial, estructurado, ligeramente formal.

Por qué funcionan los ejemplos few-shot

Cuando se inyectan conversaciones de ejemplo en el mismo formato ChatML con el que se entrenó el modelo (usando la estructura de turnos user/assistant), algo hace clic. El modelo reconoce el patrón proveniente de su entrenamiento y ajusta su salida para coincidir con él.

Así es como se ve un few-shot priming en la práctica:

few_shot_examples:
  - user: "yo whats good"
    assistant: "nm just chillin, u"
  - user: "bored af"
    assistant: "lol same energy fr"
  - user: "hey how are you"
    assistant: "im doing pretty good tbh, just vibing"

Estos ejemplos se inyectan después del prompt de sistema y antes de la conversación real. El modelo los percibe como parte del historial de conversación, no como instrucciones. Esta es una distinción crucial: no se le dice que sea casual, se le muestra cómo es serlo.

Antes y después

Sin few-shot priming (prompt de sistema desnudo):

User: yo whats good
Bot: Hello! I am doing well, thank you for asking. How can I assist you today?

Con few-shot priming (3 ejemplos):

User: yo whats good
Bot: nm just chillin, u

La diferencia es enorme. El modelo no solo produce palabras distintas: adopta todo el registro: minúsculas, abreviaturas, tono casual, respuestas cortas. Se ajusta al estilo de los ejemplos, no al de los datos de entrenamiento de Qwen.


Memoria y velocidad: las cifras concretas

El cambio de Hermes-3-3B a Luna-Protocol-1.5B ofrece mejoras medibles:

Métrica Hermes-3-3B Q8_0 Luna-Protocol Q4_K_M Mejora
Uso de VRAM ~3 GB ~986 MB 67% menos
Tamaño del archivo ~3,2 GB ~986 MB 69% más pequeño
Generación de tokens ~30 tok/s ~60+ tok/s 2 veces más rápido
Arranque en frío ~8s ~3s 62% más rápido
Ventana de contexto 8192 8192 Igual

Por qué la ganancia de velocidad es real

Los modelos más pequeños no son solo "un poco menos lentos": son fundamentalmente más rápidos en inferencia. Con 1500M de parámetros en lugar de 3000M:

  • Menos multiplicaciones de matrices por token: las capas de atención, las capas FFN y la proyección de salida escalan de forma lineal con el número de parámetros
  • Mejor uso de la caché: el modelo más pequeño cabe mejor en la caché L2/L3
  • Menor presión sobre el ancho de banda de memoria: menos bytes que leer desde la VRAM por token

En una configuración modesta solo con CPU (2 núcleos, sin GPU), el modelo de 1500M genera tokens a aproximadamente el doble de velocidad que el de 3000M. Esa es la diferencia entre "se nota que es un bot" y "parece una persona escribiendo".

El caché de prompt amplifica la ventaja

Luna Protocol usa llama-server con el caché de prompt activado (--cache-reuse 256). Esto significa que:

  1. El primer mensaje de una sesión paga el coste completo de procesar el prompt (prompt de sistema + ejemplos few-shot + mensaje del usuario)
  2. Los mensajes siguientes solo procesan los tokens nuevos: el prefijo en caché se reutiliza
  3. Con 5 ejemplos few-shot (~50-150 tokens), el sobrecoste es insignificante después de la primera solicitud

Los ejemplos few-shot resultan prácticamente "gratis" tras el primer mensaje de una sesión. El modelo obtiene guía de estilo sin coste marginal.


La implementación: cómo funciona en el código

El sistema few-shot de Luna Protocol es limpio y minimalista. Tres archivos se encargan de todo.

1. Configuración (config.yml)

few_shot_enabled: true
few_shot_examples:
  - user: "yo whats good"
    assistant: "nm just chillin, u"
  - user: "bored af"
    assistant: "lol same energy fr"
  - user: "hey how are you"
    assistant: "im doing pretty good tbh, just vibing"
  - user: "whats up"
    assistant: "yooo not much, what about you"
  - user: "how was your day"
    assistant: "it was alright, nothing crazy happened lol"

La configuración se puede recargar en caliente. Cambia los ejemplos, guarda, y el bot adopta el nuevo estilo de inmediato, sin necesidad de reiniciar.

2. Formateo e inyección (src/core/few-shot.ts)

La función formatFewShotExamples() convierte los ejemplos YAML en objetos de mensaje ChatML:

export function formatFewShotExamples(
  examples: FewShotExample[],
  username = "user"
): Array<{ role: "user" | "assistant"; content: string }> {
  const messages = [];
  for (const example of examples) {
    messages.push({ role: "user", content: `${username}: ${example.user}` });
    messages.push({ role: "assistant", content: example.assistant });
  }
  return messages;
}

La función injectFewShotIntoConversation() los coloca justo después del prompt de sistema:

export function injectFewShotIntoConversation(
  messages: Message[],
  fewShotMessages: Message[]
): Message[] {
  const systemMessage = messages[0];
  const userMessages = messages.slice(1);
  return [systemMessage, ...fewShotMessages, ...userMessages];
}

3. Integración (src/core/llm-client.ts)

Antes de cada llamada al LLM, los ejemplos few-shot se inyectan si están activados:

let finalMessages = messages;
if (FEW_SHOT_ENABLED && FEW_SHOT_EXAMPLES.length > 0) {
  const fewShotMessages = formatFewShotExamples(FEW_SHOT_EXAMPLES);
  finalMessages = injectFewShotIntoConversation(messages, fewShotMessages);
}

El modelo recibe: [prompt_de_sistema] + [ejemplos_few_shot] + [historial_de_conversación]


Manteniendo el estilo de Discord-Dialogues

El conjunto de datos original de Discord-Dialogues tiene una firma conversacional muy específica:

  • Mensajes cortos: un promedio de 32,8 tokens por turno
  • Registro informal: abreviaturas, minúsculas, ausencia de puntuación
  • Intercambios rápidos: múltiples intercambios breves en lugar de monólogos largos
  • Imperfecciones naturales: errores de tipeo, "lol", "fr", "ngl", "tbh"

El modelo Luna Protocol preserva este estilo mediante dos mecanismos:

1. El fine-tuning desplaza la distribución base

Las 50k muestras de entrenamiento enseñan al modelo la huella estadística de las conversaciones de Discord. Aprende que las respuestas suelen ser cortas, en minúsculas e informales. Esto aleja la salida predeterminada del modelo del modo de asistente servicial de Qwen.

2. El few-shot priming lo fija en su lugar

Los ejemplos few-shot refuerzan exactamente los patrones que el modelo aprendió durante el fine-tuning. Actúan como un ancla de estilo: incluso si el modelo se desvía ligeramente hacia un tono más formal durante una conversación larga, los ejemplos presentes en el contexto lo hacen volver.

La combinación es más potente que cada mecanismo por separado:

  • Fine-tuning sin few-shot: el modelo es generalmente casual, pero inconsistente
  • Few-shot sin fine-tuning: el modelo intenta seguir los ejemplos, pero vuelve constantemente al modo asistente
  • Fine-tuning + few-shot: el modelo se mantiene de forma constante en el personaje

La filosofía: modelo más pequeño, prompting más inteligente

La sabiduría convencional en el despliegue de LLM dice que "más grande es mejor". Más parámetros, más datos de entrenamiento, más VRAM. Luna Protocol toma el camino contrario:

  • 1500M en lugar de 3000M: la mitad de parámetros, la mitad de memoria, el doble de velocidad
  • 50k muestras en lugar de 7,3M: menos datos de entrenamiento, más flexibilidad para el aprendizaje en contexto
  • Few-shot priming en lugar de prompts de sistema: mostrarle al modelo lo que quieres, no solo decírselo

Esto no es solo una optimización técnica, es una filosofía de diseño. Un bot de Discord no necesita ser un asistente de propósito general. Necesita decir "nm just chillin, u" de forma consistente, rápida y sin devorar todo el presupuesto de VRAM del servidor.

El resultado: un bot que funciona en un VPS de 5 $/mes, genera tokens lo bastante rápido como para parecer una escritura en tiempo real, y mantiene una personalidad coherente gracias a una combinación de fine-tuning y few-shot priming que vale más que la suma de sus partes.


Puesta en marcha

Descargar el modelo

npm run download-model
# Descarga Luna-Protocol-1.5B-Fine-Tuned-Qwen2.5.Q4_K_M.gguf

O manualmente desde HuggingFace.

Configurar

# config.yml
llama_model_path: "./models/Luna-Protocol-1.5B-Fine-Tuned-Qwen2.5.Q4_K_M.gguf"
few_shot_enabled: true
few_shot_examples:
  - user: "yo whats good"
    assistant: "nm just chillin, u"
  - user: "bored af"
    assistant: "lol same energy fr"
  - user: "hey how are you"
    assistant: "im doing pretty good tbh, just vibing"

Ejecutar

npm run dev                    # desarrollo (recarga en caliente)
npm run build && npm start     # producción
./start.sh                     # PM2 (producción con llama-server)

Conclusión

Los modelos Luna Protocol demuestran que, para una IA conversacional centrada en el estilo, menos es más. Un modelo de 1500M entrenado con 50k muestras cuidadosamente elegidas, preparado con algunos ejemplos, supera a un modelo de 3000M entrenado con millones de ejemplos, con una fracción del coste de memoria y el doble de velocidad de generación.

El few-shot priming no es solo un extra agradable para los modelos pequeños. Es el mecanismo que los hace viables para aplicaciones conversacionales en tiempo real. Los ejemplos no solo "ayudan": cambian fundamentalmente el comportamiento del modelo, al ajustarse exactamente al formato con el que fue entrenado.

El código es de código abierto, el modelo está en HuggingFace y el conjunto de datos es público. Si quieres construir un bot conversacional que se sienta humano, la receta es: modelo pequeño, fine-tuning limitado, few-shot priming sólido.

Recurso Enlace
Repositorio de GitHub fox3000foxy/luna-protocol-project
Modelo (HuggingFace) fox3000foxy/Luna-Protocol-1.5B-Discord-Dialogues
Conjunto de datos Discord-Dialogues
Primer artículo Luna Protocol: creé un bot de Discord autónomo

Luna Protocol: por que eu fine-tunei um modelo de 1,5B em 50k amostras do Discord e tornei o few-shot priming a arma secreta

Um modelo menor treinado com menos dados pode superar um maior -- se você souber como prepará-lo. Veja por que o Luna Protocol trocou um Hermes 3B por um fine-tune Qwen 1,5B, e por que o few-shot priming se tornou o verdadeiro diferencial.

Luna Protocol: por que eu fine-tunei um modelo de 1,5B em 50k amostras do Discord e tornei o few-shot priming a arma secreta

No primeiro artigo, eu construí um bot do Discord que simula um ser humano -- sono, erros de digitação, hesitações, esquecimentos, mensagens espontâneas. O sistema comportamental era sólido. O LLM por trás dele era um modelo Hermes 3B, quantizado em Q8_0, consumindo 3 GB de VRAM.

Funcionava. Mas era exagero.

Um bot do Discord não precisa de um modelo de 3B de parâmetros para dizer "nm just chillin, u". O que ele precisa é de consistência de estilo -- a capacidade de manter um tom conversacional específico, mensagem após mensagem, sem derivar para o modo assistente corporativo. E acontece que um modelo menor, treinado com menos dados e preparado com alguns exemplos, faz isso melhor do que um modelo maior tentando forçar o caminho com um prompt de sistema.

Este artigo é sobre os modelos oficiais do Luna Protocol: por que eles existem, por que são 1,5B em vez de 3B, por que 50k amostras de treinamento em vez de 7,3M, e por que o few-shot priming passou de algo "bom ter" para o núcleo de toda a abordagem.


O problema com o modelo 3B

A configuração original usava Discord-Micae-Hermes-3-3B.Q8_0.gguf -- um modelo de 3B parâmetros fine-tunado em dados do Discord. Ele produzia boas respostas, mas:

Métrica Hermes-3-3B Q8_0 Alvo
Uso de VRAM ~3 GB < 1 GB
Geração de tokens ~30 tok/s ~60+ tok/s
Tamanho do arquivo do modelo ~3,2 GB < 1 GB
Tempo de inicialização a frio ~8s ~3s

Para um bot rodando 24/7 em um servidor modesto, 3 GB de VRAM é muito. E a velocidade de geração -- embora aceitável para mensagens ocasionais -- parecia lenta durante respostas em rajada ou quando vários canais estavam ativos.

A pergunta era: podemos obter o mesmo estilo Discord-Dialogues com metade dos parâmetros?


A decisão do fine-tuning: por que 50k, não 7,3M

O conjunto de dados Discord-Dialogues contém 7,3M de trocas e 17M de turnos. É um corpus massivo de conversas reais do Discord. A abordagem óbvia seria treinar no conjunto completo.

Eu fiz o oposto. Treinei em 50.000 amostras -- menos de 1% dos dados disponíveis.

Eis o porquê: o tamanho do conjunto de treinamento afeta diretamente o quanto o modelo se superajusta à sua distribuição de treinamento.

Um modelo treinado em 7,3M de exemplos aprende uma distribuição estatística muito específica de conversas. Ele se torna excelente em reproduzir essa distribuição, mas também se torna rígido -- tem menos flexibilidade para se adaptar a novos padrões fornecidos no momento da inferência.

Um modelo treinado em 50k exemplos aprende o tom geral e o registro das conversas do Discord (informal, curto, abreviações, minúsculas), mas retém flexibilidade suficiente para ser guiado por exemplos em contexto. Os exemplos few-shot não lutam contra uma distribuição massiva aprendida -- eles complementam uma distribuição mais leve.

Este é o insight central: dados de treinamento limitados tornam o few-shot priming mais eficiente.


O modelo: detalhes técnicos

O modelo Luna Protocol é um fine-tune QLoRA do Qwen2.5-1.5B-Instruct:

Parâmetro Valor
Modelo base unsloth/Qwen2.5-1.5B-Instruct-bnb-4bit
Método QLoRA (4-bit)
Rank LoRA r=16, lora_alpha=16
Módulos alvo q/k/v/o_proj, gate/up/down_proj
Parâmetros treináveis 18.464.768 / 1.562.179.072 (1,18%)
Dados de treinamento ~50.000 exemplos (subconjunto do Discord-Dialogues)
Filtro 8-512 tokens por amostra
Épocas 2-3
Hardware Kaggle T4
Framework Unsloth

O conjunto de dados é um fork pré-processado do Discord-Dialogues, filtrado para conter apenas turnos user/assistant limpos -- sem mensagens de sistema, sem metadados, sem comandos de bot. Isso é importante para o que vem a seguir.

Quantizações disponíveis

Arquivo Quantização Tamanho Observações
Luna-Protocol-1.5B-Fine-Tuned-Qwen2.5.Q2_K.gguf Q2_K 676 MB Visivelmente degradado -- não recomendado
Luna-Protocol-1.5B-Fine-Tuned-Qwen2.5.Q4_K_M.gguf Q4_K_M 986 MB Bom equilíbrio tamanho/qualidade (recomendado)
Luna-Protocol-1.5B-Fine-Tuned-Qwen2.5.Q8_0.gguf Q8_0 1,65 GB Melhor fidelidade de estilo

O modelo recomendado é Q4_K_M -- abaixo de 1 GB, rápido e preserva bem o estilo conversacional. O Q2_K degrada demais em um modelo tão pequeno. O Q8_0 tem a melhor qualidade, mas usa 68% mais memória.


O avanço do few-shot priming

Aqui está a parte que mudou tudo.

A ficha do modelo no HuggingFace tem um aviso:

Com um prompt simples e sem preparação, este modelo tende a recair no tom de assistente padrão do Qwen. Uma preparação curta com few-shot faz uma grande diferença.

Isso não é um bug -- é uma consequência direta de como os dados de treinamento foram estruturados.

Por que prompts de sistema sozinhos não funcionam

Os dados de treinamento do Discord-Dialogues contêm apenas turnos user/assistant. Não há exemplos de papel de sistema no conjunto de treinamento. O modelo nunca foi treinado para seguir prompts de sistema como diretrizes de estilo.

Quando você dá a ele um prompt de sistema como "Seu nome é Luna, fale casualmente", ele ouve a instrução, mas não tem um padrão forte aprendido de como traduzir isso em saída. Ele recai no padrão do Qwen: útil, estruturado, ligeiramente formal.

Por que exemplos few-shot funcionam

Quando você injeta exemplos de conversa no mesmo formato ChatML em que o modelo foi treinado (usando a estrutura de turnos user/assistant), algo se encaixa. O modelo reconhece o padrão de seus dados de treinamento e alinha sua saída para corresponder.

Aqui está como um preparo few-shot parece na prática:

few_shot_examples:
  - user: "yo whats good"
    assistant: "nm just chillin, u"
  - user: "bored af"
    assistant: "lol same energy fr"
  - user: "hey how are you"
    assistant: "im doing pretty good tbh, just vibing"

Esses exemplos são injetados após o prompt de sistema e antes da conversa real. O modelo os vê como parte do histórico da conversa, não como instruções. Essa é uma distinção crítica -- não está sendo instruído a ser casual, está sendo mostrado como é o casual.

Antes e depois

Sem preparação few-shot (apenas prompt de sistema):

User: yo whats good
Bot: Hello! I am doing well, thank you for asking. How can I assist you today?

Com preparação few-shot (3 exemplos):

User: yo whats good
Bot: nm just chillin, u

A diferença é gritante. O modelo não produz apenas palavras diferentes -- ele adota todo o registro: minúsculas, abreviações, tom casual, respostas curtas. Ele corresponde ao estilo dos exemplos, não ao estilo dos dados de treinamento do Qwen.


Memória e velocidade: os números concretos

A troca do Hermes-3-3B para o Luna-Protocol-1.5B traz ganhos mensuráveis:

Métrica Hermes-3-3B Q8_0 Luna-Protocol Q4_K_M Melhoria
Uso de VRAM ~3 GB ~986 MB 67% menos
Tamanho do arquivo do modelo ~3,2 GB ~986 MB 69% menor
Geração de tokens ~30 tok/s ~60+ tok/s 2x mais rápido
Inicialização a frio ~8s ~3s 62% mais rápido
Janela de contexto 8192 8192 Mesma

Por que o ganho de velocidade é real

Modelos menores não são apenas "menos lentos" -- eles são fundamentalmente mais rápidos para inferência. Com 1,5B de parâmetros em vez de 3B:

  • Menos multiplicações de matriz por token: as camadas de atenção, camadas FFN e a projeção de saída escalam linearmente com a contagem de parâmetros
  • Melhor utilização de cache: o modelo menor consegue colocar mais de seus pesos no cache L2/L3
  • Menor pressão na largura de banda da memória: menos bytes para ler da VRAM por token

Em uma configuração modesta apenas com CPU (2 núcleos, sem GPU), o modelo de 1,5B gera tokens a aproximadamente 2x a velocidade do modelo de 3B. Esta é a diferença entre "parece um bot" e "parece uma pessoa digitando".

Cache de prompt amplifica a vantagem

O Luna Protocol usa llama-server com cache de prompt ativado (--cache-reuse 256). Isso significa que:

  1. A primeira mensagem em uma sessão paga o custo completo de processamento do prompt (prompt de sistema + exemplos few-shot + mensagem do usuário)
  2. Mensagens subsequentes processam apenas os tokens novos -- o prefixo em cache é reutilizado
  3. Com 5 exemplos few-shot (~50-150 tokens), a sobrecarga é insignificante após a primeira requisição

Os exemplos few-shot são efetivamente "gratuitos" após a primeira mensagem em uma sessão. O modelo recebe orientação de estilo com custo marginal zero.


A implementação: como funciona no código

O sistema few-shot no Luna Protocol é limpo e mínimo. Três arquivos cuidam de tudo:

1. Configuração (config.yml)

few_shot_enabled: true
few_shot_examples:
  - user: "yo whats good"
    assistant: "nm just chillin, u"
  - user: "bored af"
    assistant: "lol same energy fr"
  - user: "hey how are you"
    assistant: "im doing pretty good tbh, just vibing"
  - user: "whats up"
    assistant: "yooo not much, what about you"
  - user: "how was your day"
    assistant: "it was alright, nothing crazy happened lol"

A configuração é recarregável a quente. Altere os exemplos, salve, e o bot adota o novo estilo imediatamente -- sem necessidade de reinicialização.

2. Formatação e injeção (src/core/few-shot.ts)

A função formatFewShotExamples() converte os exemplos YAML em objetos de mensagem ChatML:

export function formatFewShotExamples(
  examples: FewShotExample[],
  username = "user"
): Array<{ role: "user" | "assistant"; content: string }> {
  const messages = [];
  for (const example of examples) {
    messages.push({ role: "user", content: `${username}: ${example.user}` });
    messages.push({ role: "assistant", content: example.assistant });
  }
  return messages;
}

A função injectFewShotIntoConversation() os coloca logo após o prompt de sistema:

export function injectFewShotIntoConversation(
  messages: Message[],
  fewShotMessages: Message[]
): Message[] {
  const systemMessage = messages[0];
  const userMessages = messages.slice(1);
  return [systemMessage, ...fewShotMessages, ...userMessages];
}

3. Integração (src/core/llm-client.ts)

Antes de cada chamada ao LLM, os exemplos few-shot são injetados se estiverem ativados:

let finalMessages = messages;
if (FEW_SHOT_ENABLED && FEW_SHOT_EXAMPLES.length > 0) {
  const fewShotMessages = formatFewShotExamples(FEW_SHOT_EXAMPLES);
  finalMessages = injectFewShotIntoConversation(messages, fewShotMessages);
}

O modelo recebe: [prompt_de_sistema] + [exemplos_few_shot] + [histórico_da_conversa]


Mantendo o estilo Discord-Dialogues

O conjunto de dados original Discord-Dialogues tem uma assinatura conversacional muito específica:

  • Mensagens curtas: média de 32,8 tokens por turno
  • Registro informal: abreviações, minúsculas, sem pontuação
  • Ida e volta rápido: múltiplas trocas curtas em vez de longos monólogos
  • Imperfeições naturais: erros de digitação, "lol", "fr", "ngl", "tbh"

O modelo Luna-Protocol preserva esse estilo através de dois mecanismos:

1. Fine-tuning desloca a distribuição base

Os 50k exemplos de treinamento ensinam ao modelo a impressão digital estatística das conversas do Discord. Ele aprende que as respostas são tipicamente curtas, em minúsculas e informais. Isso desloca a saída padrão do modelo para longe do modo assistente-útil do Qwen.

2. Few-shot priming consolida o resultado

Os exemplos few-shot reforçam exatamente os padrões que o modelo aprendeu durante o fine-tuning. Eles atuam como uma âncora de estilo -- mesmo que o modelo desvie ligeiramente para um tom formal durante uma conversa longa, os exemplos no contexto continuam puxando-o de volta.

A combinação é mais poderosa do que qualquer mecanismo isoladamente:

  • Fine-tuning sem few-shot: o modelo é geralmente casual, mas inconsistente
  • Few-shot sem fine-tuning: o modelo tenta seguir os exemplos, mas continua revertendo ao modo assistente
  • Fine-tuning + few-shot: o modelo fica consistentemente no personagem

A filosofia: modelo menor, prompting mais inteligente

A sabedoria convencional na implantação de LLMs é "maior é melhor". Mais parâmetros, mais dados de treinamento, mais VRAM. O Luna Protocol adota a abordagem oposta:

  • 1,5B em vez de 3B: metade dos parâmetros, metade da memória, dobro da velocidade
  • 50k amostras em vez de 7,3M: menos dados de treinamento, mais flexibilidade para aprendizado em contexto
  • Few-shot priming em vez de prompts de sistema: mostre ao modelo o que você quer, não apenas diga

Isso não é apenas uma otimização técnica -- é uma filosofia de design. Um bot do Discord não precisa ser um assistente de propósito geral. Ele precisa dizer "nm just chillin, u" de forma consistente, rápida e sem consumir todo o orçamento de VRAM do seu servidor.

O resultado: um bot que roda em um VPS de $5/mês, gera tokens rápido o suficiente para parecer digitação em tempo real e mantém uma personalidade consistente através de uma combinação de fine-tuning e few-shot priming que é maior que a soma de suas partes.


Configuração

Baixar o modelo

npm run download-model
# Baixa Luna-Protocol-1.5B-Fine-Tuned-Qwen2.5.Q4_K_M.gguf

Ou manualmente pelo HuggingFace.

Configurar

# config.yml
llama_model_path: "./models/Luna-Protocol-1.5B-Fine-Tuned-Qwen2.5.Q4_K_M.gguf"
few_shot_enabled: true
few_shot_examples:
  - user: "yo whats good"
    assistant: "nm just chillin, u"
  - user: "bored af"
    assistant: "lol same energy fr"
  - user: "hey how are you"
    assistant: "im doing pretty good tbh, just vibing"

Executar

npm run dev                    # dev (recarga a quente)
npm run build && npm start     # produção
./start.sh                     # PM2 (produção com llama-server)

Conclusão

Os modelos Luna Protocol provam que para IA conversacional focada em estilo, menos é mais. Um modelo de 1,5B treinado em 50k amostras cuidadosamente selecionadas, preparado com alguns exemplos, supera um modelo de 3B treinado em milhões de exemplos -- a uma fração do custo de memória e com o dobro da velocidade de geração.

Few-shot priming não é apenas algo "bom ter" para modelos pequenos. É o mecanismo que os torna viáveis para aplicações conversacionais em tempo real. Os exemplos não apenas "ajudam" -- eles mudam fundamentalmente como o modelo se comporta, ao corresponder exatamente ao formato em que foi treinado.

O código é open source, o modelo está no HuggingFace e o conjunto de dados é público. Se você quer construir um bot conversacional que pareça humano, a receita é: modelo pequeno, fine-tuning limitado, preparação few-shot sólida.

Recurso Link
Repositório GitHub fox3000foxy/luna-protocol-project
Modelo (HuggingFace) fox3000foxy/Luna-Protocol-1.5B-Discord-Dialogues
Conjunto de dados Discord-Dialogues
Primeiro artigo Luna Protocol: criei um bot autônomo para Discord

Luna Protocol: Mengapa saya melakukan fine-tune model 1,5B pada 50k sampel Discord dan menjadikan few-shot priming sebagai senjata rahasia

Model yang lebih kecil yang dilatih dengan data lebih sedikit bisa mengungguli model yang lebih besar -- jika Anda tahu cara mempersiapkannya. Inilah mengapa Luna Protocol beralih dari Hermes 3B ke fine-tune Qwen 1,5B, dan mengapa few-shot priming menjadi pengubah permainan yang sesungguhnya.

Luna Protocol: Mengapa saya melakukan fine-tune model 1,5B pada 50k sampel Discord dan menjadikan few-shot priming sebagai senjata rahasia

Pada artikel pertama, saya membuat bot Discord yang mensimulasikan manusia -- tidur, typo, keraguan, kelupaan, pesan spontan. Sistem perilakunya solid. LLM di belakangnya adalah model Hermes 3B, terkuantisasi ke Q8_0, memakan 3GB VRAM.

Itu berhasil. Tapi itu berlebihan.

Bot Discord tidak membutuhkan model 3B parameter untuk mengatakan "nm just chillin, u". Yang dibutuhkan adalah konsistensi gaya -- kemampuan untuk mempertahankan nada percakapan tertentu, pesan demi pesan, tanpa melenceng ke mode asisten korporat. Ternyata, model yang lebih kecil yang dilatih dengan data lebih sedikit, dipersiapkan dengan beberapa contoh, melakukannya lebih baik daripada model yang lebih besar yang memaksakan jalannya melalui prompt sistem.

Artikel ini membahas model resmi Luna Protocol: mengapa mereka ada, mengapa 1,5B bukan 3B, mengapa 50k sampel pelatihan bukan 7,3M, dan mengapa few-shot priming berubah dari sesuatu yang "nice-to-have" menjadi inti dari seluruh pendekatan.


Masalah dengan model 3B

Pengaturan awal menggunakan Discord-Micae-Hermes-3-3B.Q8_0.gguf -- model 3B parameter yang di-fine-tune pada data Discord. Model ini menghasilkan respons yang baik, tetapi:

Metrik Hermes-3-3B Q8_0 Target
Penggunaan VRAM ~3 GB < 1 GB
Generasi token ~30 tok/s ~60+ tok/s
Ukuran file model ~3,2 GB < 1 GB
Waktu cold start ~8s ~3s

Untuk bot yang berjalan 24/7 di server sederhana, 3GB VRAM sangat besar. Dan kecepatan generasi -- meskipun cukup untuk pesan sesekali -- terasa lambat saat respons burst atau ketika beberapa kanal aktif.

Pertanyaannya: bisakah kita mendapatkan gaya Discord-Dialogues yang sama dengan setengah parameter?


Keputusan fine-tuning: mengapa 50k, bukan 7,3M

Dataset Discord-Dialogues berisi 7,3M pertukaran dan 17M giliran. Ini adalah korpus besar percakapan Discord nyata. Pendekatan yang jelas adalah melatih pada dataset lengkap.

Saya melakukan sebaliknya. Saya melatih pada 50.000 sampel -- kurang dari 1% dari data yang tersedia.

Inilah alasannya: ukuran set pelatihan secara langsung mempengaruhi seberapa banyak model overfit pada distribusi pelatihannya.

Model yang dilatih pada 7,3M contoh mempelajari distribusi statistik percakapan yang sangat spesifik. Model menjadi sangat baik dalam mereproduksi distribusi itu, tetapi juga menjadi kaku -- memiliki fleksibilitas lebih sedikit untuk beradaptasi dengan pola baru yang diberikan pada waktu inferensi.

Model yang dilatih pada 50k contoh mempelajari nada dan register umum percakapan Discord (informal, pendek, singkatan, huruf kecil), tetapi tetap mempertahankan fleksibilitas yang cukup untuk diarahkan oleh contoh dalam konteks. Contoh few-shot tidak melawan distribusi besar yang telah dipelajari -- mereka melengkapi distribusi yang lebih ringan.

Inilah wawasan intinya: data pelatihan terbatas membuat few-shot priming lebih efisien.


Model: detail teknis

Model Luna Protocol adalah fine-tune QLoRA dari Qwen2.5-1.5B-Instruct:

Parameter Nilai
Model dasar unsloth/Qwen2.5-1.5B-Instruct-bnb-4bit
Metode QLoRA (4-bit)
Rank LoRA r=16, lora_alpha=16
Modul target q/k/v/o_proj, gate/up/down_proj
Parameter yang dapat dilatih 18.464.768 / 1.562.179.072 (1,18%)
Data pelatihan ~50.000 contoh (subset Discord-Dialogues)
Filter 8-512 token per sampel
Epoch 2-3
Perangkat keras Kaggle T4
Framework Unsloth

Dataset adalah fork pra-pemrosesan dari Discord-Dialogues, difilter hanya untuk berisi giliran user/assistant yang bersih -- tanpa pesan sistem, tanpa metadata, tanpa perintah bot. Ini penting untuk nanti.

Kuantisasi yang tersedia

File Kuantisasi Ukuran Catatan
Luna-Protocol-1.5B-Fine-Tuned-Qwen2.5.Q2_K.gguf Q2_K 676 MB Terdegradasi signifikan -- tidak direkomendasikan
Luna-Protocol-1.5B-Fine-Tuned-Qwen2.5.Q4_K_M.gguf Q4_K_M 986 MB Keseimbangan ukuran/kualitas yang baik (direkomendasikan)
Luna-Protocol-1.5B-Fine-Tuned-Qwen2.5.Q8_0.gguf Q8_0 1,65 GB Fidelitas gaya terbaik

Model yang direkomendasikan adalah Q4_K_M -- di bawah 1GB, cepat, dan mempertahankan gaya percakapan dengan baik. Q2_K terlalu terdegradasi pada model sekecil ini. Q8_0 adalah kualitas terbaik tetapi menggunakan memori 68% lebih banyak.


Terobosan few-shot priming

Inilah bagian yang mengubah segalanya.

Kartu model HuggingFace memiliki peringatan:

Dengan prompt kosong tanpa persiapan, model ini cenderung kembali ke nada asisten default Qwen. Persiapan few-shot pendek membuat perbedaan besar.

Ini bukan bug -- ini adalah konsekuensi langsung dari bagaimana data pelatihan distrukturkan.

Mengapa prompt sistem saja tidak berfungsi

Data pelatihan Discord-Dialogues hanya berisi giliran user/assistant. Tidak ada contoh peran sistem dalam set pelatihan. Model tidak pernah dilatih untuk mengikuti prompt sistem sebagai arahan gaya.

Ketika Anda memberikan prompt sistem seperti "Nama kamu Luna, bicaralah dengan santai", model mendengar instruksi tetapi tidak memiliki pola belajar yang kuat untuk menerjemahkannya ke output. Model kembali ke default Qwen: membantu, terstruktur, sedikit formal.

Mengapa contoh few-shot berfungsi

Ketika Anda menyuntikkan contoh percakapan dalam format ChatML yang sama dengan yang digunakan model saat dilatih (menggunakan struktur giliran user/assistant), sesuatu terhubung. Model mengenali pola dari data pelatihannya dan menyelaraskan outputnya untuk mencocokkan.

Inilah tampilan persiapan few-shot dalam praktik:

few_shot_examples:
  - user: "yo whats good"
    assistant: "nm just chillin, u"
  - user: "bored af"
    assistant: "lol same energy fr"
  - user: "hey how are you"
    assistant: "im doing pretty good tbh, just vibing"

Contoh-contoh ini disuntikkan setelah prompt sistem dan sebelum percakapan nyata. Model melihatnya sebagai bagian dari riwayat percakapan, bukan sebagai instruksi. Ini adalah perbedaan kritis -- model tidak diperintahkan untuk menjadi santai, ia diperlihatkan bagaimana wujud santai itu.

Sebelum dan sesudah

Tanpa persiapan few-shot (hanya prompt sistem):

User: yo whats good
Bot: Hello! I am doing well, thank you for asking. How can I assist you today?

Dengan persiapan few-shot (3 contoh):

User: yo whats good
Bot: nm just chillin, u

Perbedaannya sangat mencolok. Model tidak hanya menghasilkan kata-kata yang berbeda -- ia mengadopsi seluruh register: huruf kecil, singkatan, nada santai, respons pendek. Model mencocokkan gaya contoh, bukan gaya data pelatihan Qwen.


Memori dan kecepatan: angka konkret

Peralihan dari Hermes-3-3B ke Luna-Protocol-1.5B memberikan peningkatan yang terukur:

Metrik Hermes-3-3B Q8_0 Luna-Protocol Q4_K_M Peningkatan
Penggunaan VRAM ~3 GB ~986 MB 67% lebih sedikit
Ukuran file model ~3,2 GB ~986 MB 69% lebih kecil
Generasi token ~30 tok/s ~60+ tok/s 2x lebih cepat
Cold start ~8s ~3s 62% lebih cepat
Jendela konteks 8192 8192 Sama

Mengapa peningkatan kecepatan nyata

Model yang lebih kecil tidak hanya "kurang lambat" -- mereka secara fundamental lebih cepat untuk inferensi. Dengan 1,5B parameter, bukan 3B:

  • Lebih sedikit perkalian matriks per token: lapisan attention, lapisan FFN, dan proyeksi output semuanya berskala linear dengan jumlah parameter
  • Pemanfaatan cache yang lebih baik: model yang lebih kecil dapat memuat lebih banyak bobotnya di cache L2/L3
  • Tekanan bandwidth memori lebih rendah: lebih sedikit byte yang dibaca dari VRAM per token

Pada pengaturan sederhana hanya CPU (2 inti, tanpa GPU), model 1,5B menghasilkan token dengan kecepatan kira-kira 2x lipat dari model 3B. Ini adalah perbedaan antara "terasa seperti bot" dan "terasa seperti orang yang mengetik".

Cache prompt memperkuat keuntungan

Luna Protocol menggunakan llama-server dengan cache prompt diaktifkan (--cache-reuse 256). Ini berarti:

  1. Pesan pertama dalam sesi membayar biaya pemrosesan prompt penuh (prompt sistem + contoh few-shot + pesan pengguna)
  2. Pesan berikutnya hanya memproses token baru -- prefiks yang di-cache digunakan kembali
  3. Dengan 5 contoh few-shot (~50-150 token), overhead menjadi dapat diabaikan setelah permintaan pertama

Contoh few-shot secara efektif "gratis" setelah pesan pertama dalam sesi. Model mendapatkan panduan gaya dengan biaya marjinal nol.


Implementasi: bagaimana cara kerjanya dalam kode

Sistem few-shot di Luna Protocol bersih dan minimal. Tiga file menangani semuanya:

1. Konfigurasi (config.yml)

few_shot_enabled: true
few_shot_examples:
  - user: "yo whats good"
    assistant: "nm just chillin, u"
  - user: "bored af"
    assistant: "lol same energy fr"
  - user: "hey how are you"
    assistant: "im doing pretty good tbh, just vibing"
  - user: "whats up"
    assistant: "yooo not much, what about you"
  - user: "how was your day"
    assistant: "it was alright, nothing crazy happened lol"

Konfigurasi dapat di-reload panas. Ubah contoh, simpan, dan bot langsung mengadopsi gaya baru -- tanpa perlu restart.

2. Pemformatan dan injeksi (src/core/few-shot.ts)

Fungsi formatFewShotExamples() mengonversi contoh YAML menjadi objek pesan ChatML:

export function formatFewShotExamples(
  examples: FewShotExample[],
  username = "user"
): Array<{ role: "user" | "assistant"; content: string }> {
  const messages = [];
  for (const example of examples) {
    messages.push({ role: "user", content: `${username}: ${example.user}` });
    messages.push({ role: "assistant", content: example.assistant });
  }
  return messages;
}

Fungsi injectFewShotIntoConversation() menempatkannya tepat setelah prompt sistem:

export function injectFewShotIntoConversation(
  messages: Message[],
  fewShotMessages: Message[]
): Message[] {
  const systemMessage = messages[0];
  const userMessages = messages.slice(1);
  return [systemMessage, ...fewShotMessages, ...userMessages];
}

3. Integrasi (src/core/llm-client.ts)

Sebelum setiap panggilan LLM, contoh few-shot disuntikkan jika diaktifkan:

let finalMessages = messages;
if (FEW_SHOT_ENABLED && FEW_SHOT_EXAMPLES.length > 0) {
  const fewShotMessages = formatFewShotExamples(FEW_SHOT_EXAMPLES);
  finalMessages = injectFewShotIntoConversation(messages, fewShotMessages);
}

Model menerima: [prompt_sistem] + [contoh_few_shot] + [riwayat_percakapan]


Mempertahankan gaya Discord-Dialogues

Dataset asli Discord-Dialogues memiliki ciri khas percakapan yang sangat spesifik:

  • Pesan pendek: rata-rata 32,8 token per giliran
  • Register informal: singkatan, huruf kecil, tanpa tanda baca
  • Bolak-balik cepat: beberapa pertukaran pendek, bukan monolog panjang
  • Ketidaksempurnaan alami: typo, "lol", "fr", "ngl", "tbh"

Model Luna-Protocol mempertahankan gaya ini melalui dua mekanisme:

1. Fine-tuning menggeser distribusi dasar

50k sampel pelatihan mengajarkan model sidik jari statistik percakapan Discord. Model belajar bahwa respons biasanya pendek, huruf kecil, dan informal. Ini menggeser output default model menjauh dari mode asisten-membantu Qwen.

2. Few-shot priming menguncinya

Contoh few-shot memperkuat pola-pola persis yang dipelajari model selama fine-tuning. Mereka bertindak sebagai jangkar gaya -- bahkan jika model sedikit melenceng ke nada formal selama percakapan panjang, contoh dalam konteks terus menariknya kembali.

Kombinasinya lebih kuat daripada masing-masing mekanisme saja:

  • Fine-tuning tanpa few-shot: model umumnya santai tetapi tidak konsisten
  • Few-shot tanpa fine-tuning: model mencoba mengikuti contoh tetapi terus kembali ke mode asisten
  • Fine-tuning + few-shot: model secara konsisten dalam karakter

Filosofi: model lebih kecil, prompting lebih cerdas

Kebijaksanaan konvensional dalam penerapan LLM adalah "lebih besar lebih baik". Lebih banyak parameter, lebih banyak data pelatihan, lebih banyak VRAM. Luna Protocol mengambil pendekatan sebaliknya:

  • 1,5B bukan 3B: setengah parameter, setengah memori, dua kali kecepatan
  • 50k sampel bukan 7,3M: lebih sedikit data pelatihan, lebih banyak fleksibilitas untuk pembelajaran dalam konteks
  • Few-shot priming bukan prompt sistem: tunjukkan model apa yang Anda inginkan, jangan hanya katakan

Ini bukan hanya optimasi teknis -- ini adalah filosofi desain. Bot Discord tidak perlu menjadi asisten tujuan umum. Ia perlu mengatakan "nm just chillin, u" secara konsisten, cepat, dan tanpa memakan seluruh anggaran VRAM server Anda.

Hasilnya: bot yang berjalan di VPS $5/bulan, menghasilkan token cukup cepat untuk terasa like mengetik real-time, dan mempertahankan kepribadian yang konsisten melalui kombinasi fine-tuning dan few-shot priming yang lebih besar dari jumlah bagian-bagiannya.


Pengaturan

Unduh model

npm run download-model
# Mengunduh Luna-Protocol-1.5B-Fine-Tuned-Qwen2.5.Q4_K_M.gguf

Atau secara manual dari HuggingFace.

Konfigurasi

# config.yml
llama_model_path: "./models/Luna-Protocol-1.5B-Fine-Tuned-Qwen2.5.Q4_K_M.gguf"
few_shot_enabled: true
few_shot_examples:
  - user: "yo whats good"
    assistant: "nm just chillin, u"
  - user: "bored af"
    assistant: "lol same energy fr"
  - user: "hey how are you"
    assistant: "im doing pretty good tbh, just vibing"

Jalankan

npm run dev                    # dev (hot reload)
npm run build && npm start     # produksi
./start.sh                     # PM2 (produksi dengan llama-server)

Kesimpulan

Model Luna Protocol membuktikan bahwa untuk AI percakapan yang spesifik-gaya, lebih sedikit lebih baik. Model 1,5B yang dilatih pada 50k sampel yang dipilih dengan cermat, dipersiapkan dengan beberapa contoh, mengungguli model 3B yang dilatih pada jutaan contoh -- dengan sebagian kecil dari biaya memori dan kecepatan generasi dua kali lipat.

Few-shot priming bukan hanya sesuatu yang "nice-to-have" untuk model kecil. Ini adalah mekanisme yang membuat mereka layak untuk aplikasi percakapan real-time. Contoh-contoh tidak hanya "membantu" -- mereka secara fundamental mengubah bagaimana model berperilaku, dengan mencocokkan format persis di mana model dilatih.

Kode bersifat open source, model ada di HuggingFace, dan dataset bersifat publik. Jika Anda ingin membangun bot percakapan yang terasa manusiawi, resepnya adalah: model kecil, fine-tuning terbatas, persiapan few-shot yang kuat.

Sumber Daya Tautan
Repositori GitHub fox3000foxy/luna-protocol-project
Model (HuggingFace) fox3000foxy/Luna-Protocol-1.5B-Discord-Dialogues
Dataset Discord-Dialogues
Artikel pertama Luna Protocol: Saya membuat bot Discord otonom

लूना प्रोटोकॉल: क्यों मैंने 50k Discord नमूनों पर 1.5B मॉडल को फाइन-ट्यून किया और फ्यू-शॉट प्राइमिंग को गुप्त हथियार बनाया

कम डेटा पर प्रशिक्षित एक छोटा मॉडल बड़े मॉडल से बेहतर प्रदर्शन कर सकता है -- अगर आप जानते हैं कि इसे कैसे प्राइम करना है। यहाँ बताया गया है कि लूना प्रोटोकॉल ने Hermes 3B से Qwen 1.5B फाइन-ट्यून पर स्विच क्यों किया, और फ्यू-शॉट प्राइमिंग असली गेम-चेंजर क्यों बन गया।

लूना प्रोटोकॉल: क्यों मैंने 50k Discord नमूनों पर 1.5B मॉडल को फाइन-ट्यून किया और फ्यू-शॉट प्राइमिंग को गुप्त हथियार बनाया

पहले लेख में, मैंने एक Discord बॉट बनाया था जो मानव व्यवहार का अनुकरण करता है -- नींद, टाइपिंग की गलतियाँ, झिझक, भूलने की आदत, सहज संदेश। व्यवहार प्रणाली ठोस थी। इसके पीछे का LLM 3B Hermes मॉडल था, जो Q8_0 में क्वांटाइज़ किया गया था और 3GB VRAM खपत कर रहा था।

यह काम करता था। लेकिन यह ओवरकिल था।

एक Discord बॉट को "nm just chillin, u" कहने के लिए 3B पैरामीटर वाले मॉडल की ज़रूरत नहीं है। उसे ज़रूरत है शैली स्थिरता की -- एक विशिष्ट संवादी लहज़े को बनाए रखने की क्षमता, संदेश दर संदेश, बिना कॉरपोरेट असिस्टेंट मोड में भटके। और यह पता चला है कि एक छोटा मॉडल, जो कम डेटा पर प्रशिक्षित हो, कुछ उदाहरणों के साथ प्राइम किया गया, एक बड़े मॉडल से बेहतर करता है जो सिस्टम प्रॉम्प्ट के ज़रिए जबरन रास्ता निकालता है।

यह लेख लूना प्रोटोकॉल के आधिकारिक मॉडलों के बारे में है: वे क्यों मौजूद हैं, वे 3B के बजाय 1.5B क्यों हैं, 7.3M के बजाय 50k प्रशिक्षण नमूने क्यों, और फ्यू-शॉट प्राइमिंग एक अच्छी-से-है चीज़ से पूरे दृष्टिकोण का मूल क्यों बन गया।


3B मॉडल की समस्या

मूल सेटअप Discord-Micae-Hermes-3-3B.Q8_0.gguf का उपयोग करता था -- Discord डेटा पर फाइन-ट्यून किया गया 3B पैरामीटर वाला मॉडल। यह अच्छी प्रतिक्रियाएँ उत्पन्न करता था, लेकिन:

मीट्रिक Hermes-3-3B Q8_0 लक्ष्य
VRAM उपयोग ~3 GB < 1 GB
टोकन जनरेशन ~30 tok/s ~60+ tok/s
मॉडल फ़ाइल आकार ~3.2 GB < 1 GB
कोल्ड स्टार्ट समय ~8s ~3s

एक बॉट के लिए जो 24/7 एक साधारण सर्वर पर चलता है, 3GB VRAM बहुत अधिक है। और जनरेशन गति -- कभी-कभार संदेशों के लिए ठीक होते हुए भी -- बर्स्ट रिस्पॉन्स या कई चैनल सक्रिय होने पर धीमी लगती थी।

सवाल यह था: क्या हम आधे पैरामीटर के साथ वही Discord-Dialogues शैली प्राप्त कर सकते हैं?


फाइन-ट्यूनिंग का निर्णय: 7.3M क्यों नहीं, 50k क्यों

Discord-Dialogues डेटासेट में 7.3M आदान-प्रदान और 17M टर्न हैं। यह वास्तविक Discord वार्तालापों का एक विशाल संग्रह है। स्पष्ट दृष्टिकोण पूरे डेटासेट पर प्रशिक्षण देना होगा।

मैंने इसके विपरीत किया। मैंने 50,000 नमूनों पर प्रशिक्षण दिया -- उपलब्ध डेटा का 1% से भी कम।

यहाँ कारण है: प्रशिक्षण सेट का आकार सीधे प्रभावित करता है कि मॉडल अपने प्रशिक्षण वितरण पर कितना ओवरफिट करता है।

7.3M उदाहरणों पर प्रशिक्षित मॉडल वार्तालापों का एक बहुत विशिष्ट सांख्यिकीय वितरण सीखता है। यह उस वितरण को पुनरुत्पादित करने में उत्कृष्ट हो जाता है, लेकिन यह कठोर भी हो जाता है -- इसमें इन्फेरेंस के समय प्रदान किए गए नए पैटर्न के अनुकूल होने की कम लचीलापन होती है।

50k उदाहरणों पर प्रशिक्षित मॉडल Discord वार्तालापों का सामान्य लहज़ा और रजिस्टर (अनौपचारिक, छोटा-रूप, संक्षिप्ताक्षर, लोअरकेस) सीखता है, लेकिन यह संदर्भ में उदाहरणों द्वारा निर्देशित होने के लिए पर्याप्त लचीलापन बनाए रखता है। फ्यू-शॉट उदाहरण एक विशाल सीखे गए वितरण से नहीं लड़ते -- वे एक हल्के वितरण को पूरक करते हैं।

यह मुख्य अंतर्दृष्टि है: सीमित प्रशिक्षण डेटा फ्यू-शॉट प्राइमिंग को अधिक कुशल बनाता है।


मॉडल: तकनीकी विवरण

लूना प्रोटोकॉल मॉडल Qwen2.5-1.5B-Instruct का QLoRA फाइन-ट्यून है:

पैरामीटर मान
आधार मॉडल unsloth/Qwen2.5-1.5B-Instruct-bnb-4bit
विधि QLoRA (4-bit)
LoRA रैंक r=16, lora_alpha=16
लक्ष्य मॉड्यूल q/k/v/o_proj, gate/up/down_proj
प्रशिक्षित पैरामीटर 18,464,768 / 1,562,179,072 (1.18%)
प्रशिक्षण डेटा ~50,000 उदाहरण (Discord-Dialogues उपसमूह)
फ़िल्टर 8-512 टोकन प्रति नमूना
एपोक 2-3
हार्डवेयर Kaggle T4
फ्रेमवर्क Unsloth

डेटासेट Discord-Dialogues का एक प्रीप्रोसेस्ड फोर्क है, जिसे केवल साफ user/assistant टर्न रखने के लिए फ़िल्टर किया गया है -- कोई सिस्टम संदेश नहीं, कोई मेटाडेटा नहीं, कोई बॉट कमांड नहीं। यह बाद के लिए महत्वपूर्ण है।

उपलब्ध क्वांटाइज़ेशन

फ़ाइल क्वांटाइज़ेशन आकार नोट्स
Luna-Protocol-1.5B-Fine-Tuned-Qwen2.5.Q2_K.gguf Q2_K 676 MB काफ़ी खराब -- अनुशंसित नहीं
Luna-Protocol-1.5B-Fine-Tuned-Qwen2.5.Q4_K_M.gguf Q4_K_M 986 MB अच्छा आकार/गुणवत्ता संतुलन (अनुशंसित)
Luna-Protocol-1.5B-Fine-Tuned-Qwen2.5.Q8_0.gguf Q8_0 1.65 GB सर्वश्रेष्ठ शैली निष्ठा

अनुशंसित मॉडल Q4_K_M है -- 1GB से कम, तेज़, और संवादी शैली को अच्छी तरह संरक्षित करता है। Q2_K इतने छोटे मॉडल पर बहुत अधिक खराब हो जाता है। Q8_0 सबसे अच्छी गुणवत्ता है लेकिन 68% अधिक मेमोरी उपयोग करता है।


फ्यू-शॉट प्राइमिंग की सफलता

यहाँ वह हिस्सा है जिसने सब कुछ बदल दिया।

HuggingFace मॉडल कार्ड पर एक चेतावनी है:

बिना प्राइमिंग के सीधे प्रॉम्प्ट के साथ, यह मॉडल Qwen के डिफ़ॉल्ट असिस्टेंट लहज़े पर वापस जाता है। एक छोटा फ्यू-शॉट प्राइम बड़ा अंतर लाता है।

यह कोई बग नहीं है -- यह एक सीधा परिणाम है कि प्रशिक्षण डेटा कैसे संरचित किया गया था।

केवल सिस्टम प्रॉम्प्ट क्यों काम नहीं करते

Discord-Dialogues प्रशिक्षण डेटा में केवल user/assistant टर्न हैं। प्रशिक्षण सेट में कोई सिस्टम-रोल उदाहरण नहीं हैं। मॉडल को कभी भी सिस्टम प्रॉम्प्ट को शैली निर्देश के रूप में पालन करने के लिए प्रशिक्षित नहीं किया गया था।

जब आप इसे "आपका नाम लूना है, आकस्मिक रूप से बात करें" जैसा सिस्टम प्रॉम्प्ट देते हैं, तो यह निर्देश सुनता है लेकिन इसे आउटपुट में अनुवाद करने का कोई मज़बूत सीखा पैटर्न नहीं है। यह Qwen के डिफ़ॉल्ट पर वापस जाता है: सहायक, संरचित, थोड़ा औपचारिक।

फ्यू-शॉट उदाहरण क्यों काम करते हैं

जब आप उसी ChatML प्रारूप में वार्तालाप उदाहरण इंजेक्ट करते हैं जिस पर मॉडल प्रशिक्षित किया गया था (user/assistant टर्न संरचना का उपयोग करके), तो कुछ क्लिक होता है। मॉडल अपने प्रशिक्षण डेटा से पैटर्न को पहचानता है और अपने आउटपुट को मैच करने के लिए संरेखित करता है।

यहाँ बताया गया है कि व्यवहार में फ्यू-शॉट प्राइम कैसा दिखता है:

few_shot_examples:
  - user: "yo whats good"
    assistant: "nm just chillin, u"
  - user: "bored af"
    assistant: "lol same energy fr"
  - user: "hey how are you"
    assistant: "im doing pretty good tbh, just vibing"

ये उदाहरण सिस्टम प्रॉम्प्ट के बाद और वास्तविक वार्तालाप से पहले इंजेक्ट किए जाते हैं। मॉडल उन्हें निर्देश के रूप में नहीं, बल्कि वार्तालाप इतिहास के हिस्से के रूप में देखता है। यह एक महत्वपूर्ण अंतर है -- इसे आकस्मिक होने के लिए बताया नहीं जा रहा है, इसे दिखाया जा रहा है कि आकस्मिक कैसा दिखता है।

पहले और बाद

फ्यू-शॉट प्राइमिंग के बिना (सिर्फ सिस्टम प्रॉम्प्ट):

User: yo whats good
Bot: Hello! I am doing well, thank you for asking. How can I assist you today?

फ्यू-शॉट प्राइमिंग के साथ (3 उदाहरण):

User: yo whats good
Bot: nm just chillin, u

अंतर स्पष्ट है। मॉडल केवल अलग शब्द नहीं बनाता -- यह पूरे रजिस्टर को अपनाता है: लोअरकेस, संक्षिप्ताक्षर, आकस्मिक लहज़ा, छोटी प्रतिक्रियाएँ। यह Qwen के प्रशिक्षण डेटा की शैली के बजाय उदाहरणों की शैली से मेल खाता है।


मेमोरी और गति: ठोस आंकड़े

Hermes-3-3B से Luna-Protocol-1.5B पर स्विच करने से मापने योग्य लाभ मिलते हैं:

मीट्रिक Hermes-3-3B Q8_0 Luna-Protocol Q4_K_M सुधार
VRAM उपयोग ~3 GB ~986 MB 67% कम
मॉडल फ़ाइल आकार ~3.2 GB ~986 MB 69% छोटा
टोकन जनरेशन ~30 tok/s ~60+ tok/s 2x तेज़
कोल्ड स्टार्ट ~8s ~3s 62% तेज़
संदर्भ विंडो 8192 8192 समान

गति लाभ वास्तविक क्यों है

छोटे मॉडल केवल "कम धीमे" नहीं होते -- वे मौलिक रूप से इन्फेरेंस के लिए तेज़ होते हैं। 3B के बजाय 1.5B पैरामीटर के साथ:

  • प्रति टोकन कम मैट्रिक्स गुणन: अटेंशन लेयर, FFN लेयर, और आउटपुट प्रोजेक्शन सभी पैरामीटर गणना के साथ रैखिक रूप से स्केल करते हैं
  • बेहतर कैश उपयोग: छोटा मॉडल अपने अधिक वेट को L2/L3 कैश में फिट कर सकता है
  • कम मेमोरी बैंडविड्थ दबाव: प्रति टोकन VRAM से पढ़ने के लिए कम बाइट्स

एक साधारण CPU-केवल सेटअप (2 कोर, बिना GPU) पर, 1.5B मॉडल लगभग 2x गति से टोकन उत्पन्न करता है 3B मॉडल की तुलना में। यह "बॉट जैसा लगता है" और "एक व्यक्ति टाइप कर रहा है जैसा लगता है" के बीच का अंतर है।

प्रॉम्प्ट कैशिंग लाभ को बढ़ाती है

लूना प्रोटोकॉल सक्षम प्रॉम्प्ट कैशिंग (--cache-reuse 256) के साथ llama-server का उपयोग करता है। इसका मतलब है:

  1. सत्र का पहला संदेश पूर्ण प्रॉम्प्ट प्रोसेसिंग लागत (सिस्टम प्रॉम्प्ट + फ्यू-शॉट उदाहरण + उपयोगकर्ता संदेश) का भुगतान करता है
  2. बाद के संदेश केवल नए टोकन प्रोसेस करते हैं -- कैश किया गया प्रीफ़िक्स पुनः उपयोग किया जाता है
  3. 5 फ्यू-शॉट उदाहरणों (~50-150 टोकन) के साथ, पहले अनुरोध के बाद ओवरहेड नगण्य है

फ्यू-शॉट उदाहरण सत्र में पहले संदेश के बाद प्रभावी रूप से "मुफ़्त" हैं। मॉडल को शून्य सीमांत लागत पर शैली मार्गदर्शन मिलता है।


कार्यान्वयन: कोड में यह कैसे काम करता है

लूना प्रोटोकॉल में फ्यू-शॉट सिस्टम साफ और न्यूनतम है। तीन फ़ाइलें सब कुछ संभालती हैं:

1. कॉन्फ़िगरेशन (config.yml)

few_shot_enabled: true
few_shot_examples:
  - user: "yo whats good"
    assistant: "nm just chillin, u"
  - user: "bored af"
    assistant: "lol same energy fr"
  - user: "hey how are you"
    assistant: "im doing pretty good tbh, just vibing"
  - user: "whats up"
    assistant: "yooo not much, what about you"
  - user: "how was your day"
    assistant: "it was alright, nothing crazy happened lol"

कॉन्फ़िगरेशन हॉट-रिलोडेबल है। उदाहरण बदलें, सेव करें, और बॉट तुरंत नई शैली अपना लेता है -- कोई रीस्टार्ट ज़रूरी नहीं।

2. फ़ॉर्मेटिंग और इंजेक्शन (src/core/few-shot.ts)

formatFewShotExamples() फ़ंक्शन YAML उदाहरणों को ChatML संदेश ऑब्जेक्ट में बदलता है:

export function formatFewShotExamples(
  examples: FewShotExample[],
  username = "user"
): Array<{ role: "user" | "assistant"; content: string }> {
  const messages = [];
  for (const example of examples) {
    messages.push({ role: "user", content: `${username}: ${example.user}` });
    messages.push({ role: "assistant", content: example.assistant });
  }
  return messages;
}

injectFewShotIntoConversation() फ़ंक्शन उन्हें सिस्टम प्रॉम्प्ट के ठीक बाद रखता है:

export function injectFewShotIntoConversation(
  messages: Message[],
  fewShotMessages: Message[]
): Message[] {
  const systemMessage = messages[0];
  const userMessages = messages.slice(1);
  return [systemMessage, ...fewShotMessages, ...userMessages];
}

3. एकीकरण (src/core/llm-client.ts)

हर LLM कॉल से पहले, फ्यू-शॉट उदाहरण इंजेक्ट किए जाते हैं यदि सक्षम हों:

let finalMessages = messages;
if (FEW_SHOT_ENABLED && FEW_SHOT_EXAMPLES.length > 0) {
  const fewShotMessages = formatFewShotExamples(FEW_SHOT_EXAMPLES);
  finalMessages = injectFewShotIntoConversation(messages, fewShotMessages);
}

मॉडल प्राप्त करता है: [सिस्टम_प्रॉम्प्ट] + [फ्यू_शॉट_उदाहरण] + [वार्तालाप_इतिहास]


Discord-Dialogues शैली बनाए रखना

मूल Discord-Dialogues डेटासेट में एक बहुत विशिष्ट संवादी हस्ताक्षर है:

  • छोटे संदेश: औसत 32.8 टोकन प्रति टर्न
  • अनौपचारिक रजिस्टर: संक्षिप्ताक्षर, लोअरकेस, कोई विराम चिह्न नहीं
  • त्वरित आगे-पीछे: लंबे एकालाप के बजाय कई छोटे आदान-प्रदान
  • प्राकृतिक अपूर्णताएँ: टाइपो, "lol", "fr", "ngl", "tbh"

लूना-प्रोटोकॉल मॉडल दो तंत्रों के माध्यम से इस शैली को संरक्षित करता है:

1. फाइन-ट्यूनिंग आधार वितरण को बदल देती है

50k प्रशिक्षण नमूने मॉडल को Discord वार्तालापों की सांख्यिकीय फिंगरप्रिंट सिखाते हैं। यह सीखता है कि प्रतिक्रियाएँ आमतौर पर छोटी, लोअरकेस और अनौपचारिक होती हैं। यह मॉडल के डिफ़ॉल्ट आउटपुट को Qwen के सहायक-असिस्टेंट मोड से दूर ले जाता है।

2. फ्यू-शॉट प्राइमिंग इसे लॉक कर देती है

फ्यू-शॉट उदाहरण उन सटीक पैटर्न को सुदृढ़ करते हैं जो मॉडल ने फाइन-ट्यूनिंग के दौरान सीखे। वे एक शैली एंकर के रूप में कार्य करते हैं -- भले ही मॉडल लंबी वार्तालाप के दौरान औपचारिक लहज़े की ओर थोड़ा भटके, संदर्भ में उदाहरण इसे वापस खींचते रहते हैं।

संयोजन अकेले किसी भी तंत्र से अधिक शक्तिशाली है:

  • फाइन-ट्यूनिंग बिना फ्यू-शॉट: मॉडल सामान्यतः आकस्मिक है लेकिन असंगत
  • फ्यू-शॉट बिना फाइन-ट्यूनिंग: मॉडल उदाहरणों का पालन करने की कोशिश करता है लेकिन असिस्टेंट मोड पर वापस जाता रहता है
  • फाइन-ट्यूनिंग + फ्यू-शॉट: मॉडल लगातार चरित्र में बना रहता है

दर्शन: छोटा मॉडल, स्मार्ट प्रॉम्प्टिंग

LLM डिप्लॉयमेंट में पारंपरिक ज्ञान है "बड़ा बेहतर है"। अधिक पैरामीटर, अधिक प्रशिक्षण डेटा, अधिक VRAM। लूना प्रोटोकॉल विपरीत दृष्टिकोण लेता है:

  • 3B के बजाय 1.5B: आधे पैरामीटर, आधी मेमोरी, दोगुनी गति
  • 7.3M के बजाय 50k नमूने: कम प्रशिक्षण डेटा, संदर्भ में सीखने के लिए अधिक लचीलापन
  • सिस्टम प्रॉम्प्ट के बजाय फ्यू-शॉट प्राइमिंग: मॉडल को दिखाएँ कि आप क्या चाहते हैं, केवल बताएँ नहीं

यह केवल एक तकनीकी अनुकूलन नहीं है -- यह एक डिज़ाइन दर्शन है। एक Discord बॉट को सामान्य-उद्देश्यीय सहायक होने की ज़रूरत नहीं है। उसे लगातार, जल्दी, और आपके सर्वर के पूरे VRAM बजट को खाए बिना "nm just chillin, u" कहने की ज़रूरत है।

परिणाम: एक बॉट जो $5/माह के VPS पर चलता है, रियल-टाइम टाइपिंग जैसा महसूस कराने के लिए पर्याप्त तेज़ी से टोकन उत्पन्न करता है, और फाइन-ट्यूनिंग और फ्यू-शॉट प्राइमिंग के संयोजन के माध्यम से एक सुसंगत व्यक्तित्व बनाए रखता है जो अपने भागों के योग से अधिक है।


सेटअप

मॉडल डाउनलोड करें

npm run download-model
# Luna-Protocol-1.5B-Fine-Tuned-Qwen2.5.Q4_K_M.gguf डाउनलोड करता है

या मैन्युअली HuggingFace से।

कॉन्फ़िगर करें

# config.yml
llama_model_path: "./models/Luna-Protocol-1.5B-Fine-Tuned-Qwen2.5.Q4_K_M.gguf"
few_shot_enabled: true
few_shot_examples:
  - user: "yo whats good"
    assistant: "nm just chillin, u"
  - user: "bored af"
    assistant: "lol same energy fr"
  - user: "hey how are you"
    assistant: "im doing pretty good tbh, just vibing"

चलाएँ

npm run dev                    # डेव (हॉट रीलोड)
npm run build && npm start     # प्रोडक्शन
./start.sh                     # PM2 (llama-server के साथ प्रोडक्शन)

निष्कर्ष

लूना प्रोटोकॉल मॉडल साबित करते हैं कि शैली-विशिष्ट संवादी AI के लिए, कम अधिक है. 50k सावधानीपूर्वक चुने गए नमूनों पर प्रशिक्षित 1.5B मॉडल, कुछ उदाहरणों के साथ प्राइम किया गया, लाखों उदाहरणों पर प्रशिक्षित 3B मॉडल से बेहतर प्रदर्शन करता है -- मेमोरी लागत के एक अंश पर और दोगुनी जनरेशन गति के साथ।

फ्यू-शॉट प्राइमिंग छोटे मॉडलों के लिए केवल एक अच्छी-से-है चीज़ नहीं है। यह वह तंत्र है जो उन्हें रियल-टाइम संवादी अनुप्रयोगों के लिए व्यवहार्य बनाता है। उदाहरण केवल "मदद" नहीं करते -- वे मौलिक रूप से बदलते हैं कि मॉडल कैसे व्यवहार करता है, उस सटीक प्रारूप से मेल खाकर जिस पर इसे प्रशिक्षित किया गया था।

कोड ओपन सोर्स है, मॉडल HuggingFace पर है, और डेटासेट सार्वजनिक है। यदि आप एक संवादी बॉट बनाना चाहते हैं जो मानव जैसा लगे, तो नुस्खा है: छोटा मॉडल, सीमित फाइन-ट्यूनिंग, मजबूत फ्यू-शॉट प्राइमिंग।

संसाधन लिंक
GitHub रिपॉजिटरी fox3000foxy/luna-protocol-project
मॉडल (HuggingFace) fox3000foxy/Luna-Protocol-1.5B-Discord-Dialogues
डेटासेट Discord-Dialogues
पहला लेख लूना प्रोटोकॉल: मैंने एक स्वायत्त Discord बॉट बनाया

بروتوكول لونا: لماذا قمت بضبط نموذج 1.5B على 50k عينة من ديسكورد وجعلت التمهيد القليل من الأمثلة السلاح السري

نموذج أصغر مدرب على بيانات أقل يمكنه التفوق على نموذج أكبر -- إذا كنت تعرف كيف تمهّده. إليكم لماذا تحول بروتوكول لونا من Hermes 3B إلى ضبط Qwen 1.5B، ولماذا أصبح التمهيد القليل من الأمثلة هو العامل الحقيقي للتغيير.

بروتوكول لونا: لماذا قمت بضبط نموذج 1.5B على 50k عينة من ديسكورد وجعلت التمهيد القليل من الأمثلة السلاح السري

في المقال الأول، قمت ببناء بوت ديسكورد يحاكي إنسانًا حقيقيًا -- النوم، الأخطاء الإملائية، التردد، النسيان، الرسائل العفوية. النظام السلوكي كان متينًا. لكن النموذج اللغوي الكبير خلفه كان نموذج Hermes بحجم 3 مليار معامل، مكمّم إلى Q8_0، يستهلك 3 جيجابايت من VRAM.

كان يعمل. لكنه كان مبالغًا فيه.

بوت ديسكورد لا يحتاج نموذجًا بـ 3 مليار معامل ليقول "nm just chillin, u". ما يحتاجه هو تناسق أسلوبي -- القدرة على مطابقة نغمة محادثة محددة، رسالة تلو الأخرى، دون الانجراف نحو وضع المساعد المؤسسي. واتضح أن نموذجًا أصغر مدربًا على بيانات أقل، مع تمهيد ببضعة أمثلة، يؤدي ذلك بشكل أفضل من نموذج أكبر يجبر الأمور عبر مطالبة نظامية.

هذا المقال يدور حول النماذج الرسمية لبروتوكول لونا: لماذا هي موجودة، ولماذا هي 1.5B بدلاً من 3B، ولماذا 50k عينة تدريب بدلاً من 7.3M، ولماذا أصبح التمهيد القليل من الأمثلة من مجرد ميزة إضافية إلى جوهر النهج بأكمله.


المشكلة مع النموذج 3B

الإعداد الأصلي استخدم Discord-Micae-Hermes-3-3B.Q8_0.gguf -- نموذج بـ 3 مليار معامل مضبوط على بيانات ديسكورد. كان ينتج ردودًا جيدة، لكن:

المقياس Hermes-3-3B Q8_0 الهدف
استخدام VRAM ~3 جيجابايت < 1 جيجابايت
توليد التوكنات ~30 توكن/ث ~60+ توكن/ث
حجم ملف النموذج ~3.2 جيجابايت < 1 جيجابايت
وقت البدء البارد ~8 ثوان ~3 ثوان

لبوت يعمل 24/7 على خادم متواضع، 3 جيجابايت من VRAM كثير. وسرعة التوليد -- رغم أنها مناسبة للرسائل العرضية -- كانت بطيئة أثناء الاستجابات المتتابعة أو عندما تكون عدة قنوات نشطة.

السؤال كان: هل يمكننا الحصول على نفس أسلوب محادثات ديسكورد بنصف عدد المعاملات؟


قرار الضبط الدقيق: لماذا 50k وليس 7.3M

مجموعة بيانات Discord-Dialogues تحتوي على 7.3M تبادل و 17M جولة. إنها مجموعة ضخمة من محادثات ديسكورد الحقيقية. النهج الواضح كان التدريب على المجموعة الكاملة.

فعلت العكس. دربت على 50,000 عينة -- أقل من 1% من البيانات المتاحة.

إليكم السبب: حجم مجموعة التدريب يؤثر بشكل مباشر على مدى فرط تكيف النموذج مع توزيع تدريبه.

نموذج مدرب على 7.3M مثال يتعلم توزيعًا إحصائيًا محددًا جدًا للمحادثات. يصبح ممتازًا في إعادة إنتاج ذلك التوزيع، لكنه يصبح أيضًا جامدًا -- لديه مرونة أقل للتكيف مع أنماط جديدة تُقدم في وقت الاستدلال.

نموذج مدرب على 50k مثال يتعلم النغمة العامة والمسجل العام لمحادثات ديسكورد (غير رسمي، قصير، مختصرات، أحرف صغيرة)، لكنه يحتفظ بمرونة كافية ليتم توجيهه بأمثلة سياقية. أمثلة التمهيد القليل لا تقاوم توزيعًا كبيرًا مكتسبًا -- بل تكمل توزيعًا أخف.

هذه هي الفكرة الأساسية: البيانات التدريبية المحدودة تجعل التمهيد القليل من الأمثلة أكثر فعالية.


النموذج: تفاصيل تقنية

نموذج بروتوكول لونا هو ضبط دقيق QLoRA لـ Qwen2.5-1.5B-Instruct:

المعامل القيمة
النموذج الأساسي unsloth/Qwen2.5-1.5B-Instruct-bnb-4bit
الطريقة QLoRA (4-bit)
رتبة LoRA r=16, lora_alpha=16
الوحدات المستهدفة q/k/v/o_proj, gate/up/down_proj
المعاملات القابلة للتدريب 18,464,768 / 1,562,179,072 (1.18%)
بيانات التدريب ~50,000 مثال (مجموعة فرعية من Discord-Dialogues)
المرشح 8-512 توكن لكل عينة
العصور 2-3
العتاد Kaggle T4
الإطار Unsloth

مجموعة البيانات هي fork معالجة مسبقًا من Discord-Dialogues، تمت تصفيتها لتحتوي فقط على جولات user/assistant نظيفة -- لا رسائل نظام، لا بيانات وصفية، لا أوامر بوت. هذا مهم لاحقًا.

التكميمات المتاحة

الملف التكميم الحجم ملاحظات
Luna-Protocol-1.5B-Fine-Tuned-Qwen2.5.Q2_K.gguf Q2_K 676 ميجابايت متدهور بشكل ملحوظ -- غير موصى به
Luna-Protocol-1.5B-Fine-Tuned-Qwen2.5.Q4_K_M.gguf Q4_K_M 986 ميجابايت توازن جيد بين الحجم والجودة (موصى به)
Luna-Protocol-1.5B-Fine-Tuned-Qwen2.5.Q8_0.gguf Q8_0 1.65 جيجابايت أفضل دقة أسلوبية

النموذج الموصى به هو Q4_K_M -- أقل من 1 جيجابايت، سريع، ويحافظ على الأسلوب التحادثي جيدًا. Q2_K يتدهور كثيرًا على نموذج بهذا الحجم. Q8_0 هو الأفضل جودة لكنه يستهلك 68% ذاكرة إضافية.


اختراق التمهيد القليل من الأمثلة

هذا هو الجزء الذي غيّر كل شيء.

بطاقة نموذج HuggingFace تحتوي على تحذير:

مع مطالبة فارغة وبدون تمهيد، يميل هذا النموذج إلى العودة إلى نغمة المساعد الافتراضية لـ Qwen. تمهيد قصير بأمثلة قليلة يحدث فرقًا كبيرًا.

هذا ليس خطأ -- بل نتيجة مباشرة لكيفية تنظيم بيانات التدريب.

لماذا لا تعمل المطالبات النظامية بمفردها

بيانات تدريب Discord-Dialogues تحتوي فقط على جولات user/assistant. لا توجد أمثلة لدور النظام في مجموعة التدريب. لم يتم تدريب النموذج أبدًا على اتباع المطالبات النظامية كتوجيهات أسلوبية.

عندما تعطيه مطالبة نظامية مثل "اسمك لونا، تحدث بشكل غير رسمي"، يسمع التعليمات لكن ليس لديه نمط مكتسب قوي لكيفية ترجمتها إلى مخرجات. يعود إلى الوضع الافتراضي لـ Qwen: مساعد، منظم، رسمي قليلاً.

لماذا تعمل أمثلة التمهيد القليل

عندما تحقن أمثلة محادثة بنفس تنسيق ChatML الذي دُرب عليه النموذج (باستخدام هيكل جولات user/assistant)، يحدث شيء. يتعرف النموذج على النمط من بيانات تدريبه ويوائم مخرجاته لتطابقه.

إليك كيف يبدو التمهيد القليل من الأمثلة عمليًا:

few_shot_examples:
  - user: "yo whats good"
    assistant: "nm just chillin, u"
  - user: "bored af"
    assistant: "lol same energy fr"
  - user: "hey how are you"
    assistant: "im doing pretty good tbh, just vibing"

هذه الأمثلة تُحقن بعد المطالبة النظامية وقبل المحادثة الحقيقية. يراها النموذج كجزء من تاريخ المحادثة، وليس كتعليمات. هذا تمييز أساسي -- لا يتم إخباره ليكون غير رسمي، بل يتم إظهار كيف تبدو غير الرسمية.

قبل وبعد

بدون تمهيد بأمثلة قليلة (مطالبة نظامية فارغة):

User: yo whats good
Bot: Hello! I am doing well, thank you for asking. How can I assist you today?

مع تمهيد بأمثلة قليلة (3 أمثلة):

User: yo whats good
Bot: nm just chillin, u

الفرق شاسع. النموذج لا ينتج كلمات مختلفة فقط -- بل يتبنى المسجل بأكمله: أحرف صغيرة، مختصرات، نغمة غير رسمية، ردود قصيرة. يطابق أسلوب الأمثلة، وليس أسلوب بيانات تدريب Qwen.


الذاكرة والسرعة: الأرقام الملموسة

التحول من Hermes-3-3B إلى Luna-Protocol-1.5B يحقق مكاسب قابلة للقياس:

المقياس Hermes-3-3B Q8_0 Luna-Protocol Q4_K_M التحسين
استخدام VRAM ~3 جيجابايت ~986 ميجابايت أقل بنسبة 67%
حجم ملف النموذج ~3.2 جيجابايت ~986 ميجابايت أصغر بنسبة 69%
توليد التوكنات ~30 توكن/ث ~60+ توكن/ث أسرع مرتين
البدء البارد ~8 ثوان ~3 ثوان أسرع بنسبة 62%
نافذة السياق 8192 8192 نفسه

لماذا كسب السرعة حقيقي

النماذج الأصغر ليست مجرد "أقل بطئًا" -- بل هي أسرع بشكل جوهري في الاستدلال. مع 1.5B معامل بدلاً من 3B:

  • ضرب مصفوفات أقل لكل توكن: طبقات الانتباه، طبقات FFN، وإسقاط المخرجات كلها تتدرج خطيًا مع عدد المعاملات
  • استخدام أفضل للذاكرة المؤقتة: النموذج الأصغر يناسب أوزانه بشكل أكبر في ذاكرة L2/L3 المخبأة
  • ضغط أقل على عرض النطاق الترددي للذاكرة: بايتات أقل للقراءة من VRAM لكل توكن

على إعداد متواضع مع CPU فقط (نواتان، بدون GPU)، النموذج 1.5B يولد التوكنات بحوالي ضعف سرعة النموذج 3B. هذا هو الفرق بين "يشعرك بأنه بوت" و"يشعرك بأنه شخص يكتب".

التخزين المؤقت للمطالبة يضاعف الميزة

بروتوكول لونا يستخدم llama-server مع التخزين المؤقت للمطالبة مفعلًا (--cache-reuse 256). هذا يعني:

  1. الرسالة الأولى في جلسة تتحمل التكلفة الكاملة لمعالجة المطالبة (مطالبة نظامية + أمثلة تمهيدية + رسالة مستخدم)
  2. الرسائل التالية تعالج فقط التوكنات الجديدة -- البادئة المخزنة مؤقتًا يُعاد استخدامها
  3. مع 5 أمثلة تمهيدية (~50-150 توكن)، الحمل الإضافي لا يُذكر بعد الطلب الأول

أمثلة التمهيد تصبح فعليًا "مجانية" بعد الرسالة الأولى في الجلسة. يحصل النموذج على توجيه أسلوبي بتكلفة حدية صفرية.


التطبيق: كيف يعمل في الكود

نظام التمهيد القليل من الأمثلة في بروتوكول لونا نظيف وبسيط. ثلاثة ملفات تدير كل شيء:

1. الإعدادات (config.yml)

few_shot_enabled: true
few_shot_examples:
  - user: "yo whats good"
    assistant: "nm just chillin, u"
  - user: "bored af"
    assistant: "lol same energy fr"
  - user: "hey how are you"
    assistant: "im doing pretty good tbh, just vibing"
  - user: "whats up"
    assistant: "yooo not much, what about you"
  - user: "how was your day"
    assistant: "it was alright, nothing crazy happened lol"

الإعدادات قابلة لإعادة التحميل أثناء التشغيل. غيّر الأمثلة، احفظ، والبوت يتبنى الأسلوب الجديد فورًا -- لا حاجة لإعادة تشغيل.

2. التنسيق والحقن (src/core/few-shot.ts)

دالة formatFewShotExamples() تحول أمثلة YAML إلى كائنات رسائل ChatML:

export function formatFewShotExamples(
  examples: FewShotExample[],
  username = "user"
): Array<{ role: "user" | "assistant"; content: string }> {
  const messages = [];
  for (const example of examples) {
    messages.push({ role: "user", content: `${username}: ${example.user}` });
    messages.push({ role: "assistant", content: example.assistant });
  }
  return messages;
}

دالة injectFewShotIntoConversation() تضعها بعد المطالبة النظامية مباشرة:

export function injectFewShotIntoConversation(
  messages: Message[],
  fewShotMessages: Message[]
): Message[] {
  const systemMessage = messages[0];
  const userMessages = messages.slice(1);
  return [systemMessage, ...fewShotMessages, ...userMessages];
}

3. التكامل (src/core/llm-client.ts)

قبل كل استدعاء للنموذج اللغوي الكبير، تُحقن أمثلة التمهيد إذا كانت مفعلة:

let finalMessages = messages;
if (FEW_SHOT_ENABLED && FEW_SHOT_EXAMPLES.length > 0) {
  const fewShotMessages = formatFewShotExamples(FEW_SHOT_EXAMPLES);
  finalMessages = injectFewShotIntoConversation(messages, fewShotMessages);
}

النموذج يستلم: [مطالبة_نظامية] + [أمثلة_تمهيدية] + [تاريخ_المحادثة]


الحفاظ على أسلوب محادثات ديسكورد

مجموعة بيانات Discord-Dialogues الأصلية لها بصمة تحادثية محددة جدًا:

  • رسائل قصيرة: متوسط 32.8 توكن لكل جولة
  • مسجل غير رسمي: مختصرات، أحرف صغيرة، لا علامات ترقيم
  • تبادل سريع: تبادلات قصيرة متعددة بدلاً من حديث طويل
  • عيوب طبيعية: أخطاء إملائية، "lol"، "fr"، "ngl"، "tbh"

نموذج لونا-بروتوكول يحافظ على هذا الأسلوب من خلال آليتين:

1. الضبط الدقيق يغير التوزيع الأساسي

عينة التدريب البالغة 50k تعلم النموذج البصمة الإحصائية لمحادثات ديسكورد. يتعلم أن الردود عادة ما تكون قصيرة، بأحرف صغيرة، وغير رسمية. هذا يغير مخرجات النموذج الافتراضية بعيدًا عن وضع المساعد المساعد لـ Qwen.

2. التمهيد القليل من الأمثلة يثبته

أمثلة التمهيد تعزز بالضبط الأنماط التي تعلمها النموذج أثناء الضبط الدقيق. تعمل كـ مرساة أسلوبية -- حتى لو انحرف النموذج قليلاً نحو النغمة الرسمية أثناء محادثة طويلة، الأمثلة في السياق تستمر في إعادته.

التركيبة أقوى من أي آلية بمفردها:

  • ضبط دقيق بدون تمهيد: النموذج بشكل عام غير رسمي لكنه غير متناسق
  • تمهيد بدون ضبط دقيق: النموذج يحاول اتباع الأمثلة لكنه يعود إلى وضع المساعد باستمرار
  • ضبط دقيق + تمهيد: النموذج باستمرار في الشخصية

الفلسفة: نموذج أصغر، مطالبة أذكى

الحكمة التقليدية في نشر النماذج اللغوية الكبيرة هي "الأكبر أفضل". معاملات أكثر، بيانات تدريب أكثر، VRAM أكثر. بروتوكول لونا يتخذ النهج المعاكس:

  • 1.5B بدلاً من 3B: نصف المعاملات، نصف الذاكرة، ضعف السرعة
  • 50k عينة بدلاً من 7.3M: بيانات تدريب أقل، مرونة أكثر للتعلم السياقي
  • تمهيد بأمثلة قليلة بدلاً من مطالبات نظامية: أظهر للنموذج ما تريد، لا تخبره فقط

هذا ليس مجرد تحسين تقني -- بل فلسفة تصميم. بوت ديسكورد لا يحتاج أن يكون مساعدًا عامًا. يحتاج أن يقول "nm just chillin, u" باستمرار، بسرعة، ودون أن يستهلك ميزانية VRAM بالكامل لخادمك.

النتيجة: بوت يعمل على VPS بـ 5 دولار/شهر، يولد التوكنات بسرعة كافية ليشعر وكأنه كتابة في الوقت الفعلي، ويحافظ على شخصية متناسقة من خلال مزيج من الضبط الدقيق والتمهيد القليل من الأمثلة الذي هو أكبر من مجموع أجزائه.


الإعداد

تحميل النموذج

npm run download-model
# يحمل Luna-Protocol-1.5B-Fine-Tuned-Qwen2.5.Q4_K_M.gguf

أو يدويًا من HuggingFace.

الإعدادات

# config.yml
llama_model_path: "./models/Luna-Protocol-1.5B-Fine-Tuned-Qwen2.5.Q4_K_M.gguf"
few_shot_enabled: true
few_shot_examples:
  - user: "yo whats good"
    assistant: "nm just chillin, u"
  - user: "bored af"
    assistant: "lol same energy fr"
  - user: "hey how are you"
    assistant: "im doing pretty good tbh, just vibing"

التشغيل

npm run dev                    # تطوير (إعادة تحميل ساخن)
npm run build && npm start     # إنتاج
./start.sh                     # PM2 (إنتاج مع llama-server)

الخاتمة

نماذج بروتوكول لونا تثبت أنه بالنسبة للذكاء الاصطناعي التحادثي الموجه بالأسلوب، الأقل هو الأكثر. نموذج 1.5B مدرب على 50k عينة مختارة بعناية، ممهد ببضعة أمثلة، يتفوق على نموذج 3B مدرب على ملايين الأمثلة -- بجزء صغير من تكلفة الذاكرة وضعف سرعة التوليد.

التمهيد القليل من الأمثلة ليس مجرد ميزة إضافية للنماذج الصغيرة. إنه الآلية التي تجعلها قابلة للاستخدام في التطبيقات التحادثية في الوقت الفعلي. الأمثلة لا تقوم فقط "بالمساعدة" -- إنها تغير بشكل أساسي كيف يتصرف النموذج، بمطابقة exact التنسيق الذي تدرب عليه.

الكود مفتوح المصدر، النموذج على HuggingFace، ومجموعة البيانات عامة. إذا أردت بناء بوت تحادثي يشعر بأنه إنسان، الوصفة هي: نموذج صغير، ضبط دقيق محدود، تمهيد قوي بأمثلة قليلة.

المصدر الرابط
مستودع GitHub fox3000foxy/luna-protocol-project
النموذج (HuggingFace) fox3000foxy/Luna-Protocol-1.5B-Discord-Dialogues
مجموعة البيانات Discord-Dialogues
المقال الأول بروتوكول لونا: أنشأت بوت ديسكورد مستقل

Luna Protocol: Tại sao tôi fine-tune mô hình 1.5B trên 50k mẫu Discord và biến few-shot priming thành vũ khí bí mật

Một mô hình nhỏ hơn được huấn luyện trên ít dữ liệu hơn có thể vượt trội hơn mô hình lớn hơn -- nếu bạn biết cách priming nó. Đây là lý do Luna Protocol chuyển từ Hermes 3B sang fine-tune Qwen 1.5B, và tại sao few-shot priming trở thành yếu tố thay đổi cuộc chơi thực sự.

Luna Protocol: Tại sao tôi fine-tune mô hình 1.5B trên 50k mẫu Discord và biến few-shot priming thành vũ khí bí mật

Trong bài viết đầu tiên, tôi đã xây dựng một bot Discord mô phỏng hành vi con người -- ngủ, gõ sai, ngập ngừng, hay quên, tin nhắn tự phát. Hệ thống hành vi rất vững chắc. LLM đằng sau nó là mô hình Hermes 3B, được lượng tử hóa ở mức Q8_0, ngốn 3GB VRAM.

Nó hoạt động. Nhưng nó là quá mức cần thiết.

Một bot Discord không cần mô hình 3B tham số để nói "nm just chillin, u". Thứ nó cần là sự nhất quán về phong cách -- khả năng duy trì một giọng điệu hội thoại cụ thể, hết tin nhắn này đến tin nhắn khác, mà không trôi vào chế độ trợ lý công ty. Và hóa ra, một mô hình nhỏ hơn được huấn luyện trên ít dữ liệu hơn, được priming với vài ví dụ, làm điều đó tốt hơn một mô hình lớn hơn cố gắng ép bằng system prompt.

Bài viết này nói về các mô hình chính thức của Luna Protocol: tại sao chúng tồn tại, tại sao là 1.5B thay vì 3B, tại sao 50k mẫu huấn luyện thay vì 7.3M, và tại sao few-shot priming đi từ một tính năng tốt-để-có thành cốt lõi của toàn bộ cách tiếp cận.


Vấn đề với mô hình 3B

Thiết lập ban đầu sử dụng Discord-Micae-Hermes-3-3B.Q8_0.gguf -- mô hình 3B tham số được fine-tune trên dữ liệu Discord. Nó tạo ra các phản hồi tốt, nhưng:

Chỉ số Hermes-3-3B Q8_0 Mục tiêu
Sử dụng VRAM ~3 GB < 1 GB
Sinh token ~30 tok/s ~60+ tok/s
Kích thước tệp mô hình ~3.2 GB < 1 GB
Thời gian khởi động nguội ~8s ~3s

Đối với một bot chạy 24/7 trên một máy chủ khiêm tốn, 3GB VRAM là rất nhiều. Và tốc độ sinh -- dù ổn cho các tin nhắn không thường xuyên -- cảm thấy chậm chạp trong các phản hồi bùng nổ hoặc khi nhiều kênh hoạt động cùng lúc.

Câu hỏi là: liệu chúng ta có thể đạt được cùng phong cách Discord-Dialogues với một nửa số tham số không?


Quyết định fine-tune: tại sao 50k, không phải 7.3M

Bộ dữ liệu Discord-Dialogues chứa 7.3M lượt trao đổi và 17M lượt tương tác. Đó là một kho ngữ liệu khổng lồ các cuộc hội thoại Discord thực tế. Cách tiếp cận hiển nhiên là huấn luyện trên toàn bộ bộ dữ liệu.

Tôi đã làm ngược lại. Tôi huấn luyện trên 50.000 mẫu -- ít hơn 1% dữ liệu có sẵn.

Đây là lý do: kích thước của tập huấn luyện ảnh hưởng trực tiếp đến mức độ mô hình overfit vào phân phối huấn luyện của nó.

Một mô hình được huấn luyện trên 7.3M ví dụ học một phân phối thống kê rất cụ thể của các cuộc hội thoại. Nó trở nên xuất sắc trong việc tái tạo phân phối đó, nhưng nó cũng trở nên cứng nhắc -- nó có ít linh hoạt hơn để thích ứng với các mẫu mới được cung cấp tại thời điểm suy luận.

Một mô hình được huấn luyện trên 50k ví dụ học được giọng điệu và thanh điệu chung của các cuộc hội thoại Discord (không trang trọng, dạng ngắn, viết tắt, chữ thường), nhưng nó giữ đủ linh hoạt để được dẫn dắt bởi các ví dụ trong ngữ cảnh. Các ví dụ few-shot không chống lại một phân phối đã học khổng lồ -- chúng bổ sung cho một phân phối nhẹ hơn.

Đây là hiểu biết cốt lõi: dữ liệu huấn luyện hạn chế làm cho few-shot priming hiệu quả hơn.


Mô hình: chi tiết kỹ thuật

Mô hình Luna Protocol là một fine-tune QLoRA của Qwen2.5-1.5B-Instruct:

Tham số Giá trị
Mô hình cơ sở unsloth/Qwen2.5-1.5B-Instruct-bnb-4bit
Phương pháp QLoRA (4-bit)
Hạng LoRA r=16, lora_alpha=16
Mô-đun mục tiêu q/k/v/o_proj, gate/up/down_proj
Tham số có thể huấn luyện 18.464.768 / 1.562.179.072 (1,18%)
Dữ liệu huấn luyện ~50.000 ví dụ (tập con của Discord-Dialogues)
Bộ lọc 8-512 token mỗi mẫu
Số epoch 2-3
Phần cứng Kaggle T4
Framework Unsloth

Bộ dữ liệu là một fork đã được tiền xử lý của Discord-Dialogues, được lọc để chỉ chứa các lượt user/assistant sạch -- không có tin nhắn hệ thống, không có siêu dữ liệu, không có lệnh bot. Điều này quan trọng về sau.

Các lượng tử hóa có sẵn

Tệp Lượng tử hóa Kích thước Ghi chú
Luna-Protocol-1.5B-Fine-Tuned-Qwen2.5.Q2_K.gguf Q2_K 676 MB Suy giảm đáng kể -- không khuyến nghị
Luna-Protocol-1.5B-Fine-Tuned-Qwen2.5.Q4_K_M.gguf Q4_K_M 986 MB Cân bằng tốt giữa kích thước/chất lượng (khuyến nghị)
Luna-Protocol-1.5B-Fine-Tuned-Qwen2.5.Q8_0.gguf Q8_0 1,65 GB Độ trung thực phong cách tốt nhất

Mô hình được khuyến nghị là Q4_K_M -- dưới 1GB, nhanh, và giữ phong cách hội thoại tốt. Q2_K suy giảm quá nhiều trên một mô hình nhỏ như vậy. Q8_0 là chất lượng tốt nhất nhưng sử dụng nhiều hơn 68% bộ nhớ.


Bước đột phá về few-shot priming

Đây là phần đã thay đổi mọi thứ.

Thẻ mô hình HuggingFace có một cảnh báo:

Với một prompt trần và không có priming, mô hình này có xu hướng quay lại giọng trợ lý mặc định của Qwen. Một vài ví dụ few-shot ngắn tạo ra sự khác biệt lớn.

Đây không phải là lỗi -- đó là hậu quả trực tiếp của cách dữ liệu huấn luyện được cấu trúc.

Tại sao system prompt một mình không hiệu quả

Dữ liệu huấn luyện Discord-Dialogues chỉ chứa các lượt user/assistant. Không có ví dụ nào về vai trò hệ thống trong tập huấn luyện. Mô hình chưa bao giờ được huấn luyện để làm theo system prompt như các chỉ thị về phong cách.

Khi bạn đưa cho nó một system prompt như "Tên bạn là Luna, hãy nói chuyện thoải mái", nó nghe được chỉ dẫn nhưng không có một mẫu học mạnh để chuyển điều đó thành đầu ra. Nó quay về mặc định của Qwen: hữu ích, có cấu trúc, hơi trang trọng.

Tại sao ví dụ few-shot hiệu quả

Khi bạn đưa vào các ví dụ hội thoại cùng định dạng ChatML mà mô hình được huấn luyện (sử dụng cấu trúc lượt user/assistant), một điều xảy ra. Mô hình nhận ra mẫu từ dữ liệu huấn luyện của nó và điều chỉnh đầu ra để phù hợp.

Đây là những gì một few-shot prime trông như thế nào trong thực tế:

few_shot_examples:
  - user: "yo whats good"
    assistant: "nm just chillin, u"
  - user: "bored af"
    assistant: "lol same energy fr"
  - user: "hey how are you"
    assistant: "im doing pretty good tbh, just vibing"

Những ví dụ này được đưa vào sau system prompt và trước cuộc hội thoại thực tế. Mô hình xem chúng như một phần của lịch sử hội thoại, không phải như chỉ dẫn. Đây là một sự khác biệt quan trọng -- nó không bị bảo phải thoải mái, nó được cho thấy thoải mái trông như thế nào.

Trước và sau

Không có few-shot priming (system prompt trần):

User: yo whats good
Bot: Hello! I am doing well, thank you for asking. How can I assist you today?

Với few-shot priming (3 ví dụ):

User: yo whats good
Bot: nm just chillin, u

Sự khác biệt rất rõ rệt. Mô hình không chỉ tạo ra các từ khác nhau -- nó áp dụng toàn bộ thanh điệu: chữ thường, viết tắt, giọng thoải mái, câu trả lời ngắn. Nó khớp với phong cách của các ví dụ, không phải phong cách của dữ liệu huấn luyện Qwen.


Bộ nhớ và tốc độ: những con số cụ thể

Sự chuyển đổi từ Hermes-3-3B sang Luna-Protocol-1.5B mang lại những cải thiện có thể đo lường:

Chỉ số Hermes-3-3B Q8_0 Luna-Protocol Q4_K_M Cải thiện
Sử dụng VRAM ~3 GB ~986 MB ít hơn 67%
Kích thước tệp mô hình ~3.2 GB ~986 MB nhỏ hơn 69%
Sinh token ~30 tok/s ~60+ tok/s nhanh gấp 2x
Khởi động nguội ~8s ~3s nhanh hơn 62%
Cửa sổ ngữ cảnh 8192 8192 Giống nhau

Tại sao tốc độ tăng là thật

Các mô hình nhỏ hơn không chỉ "ít chậm hơn" -- chúng về cơ bản nhanh hơn cho suy luận. Với 1.5B tham số thay vì 3B:

  • Ít phép nhân ma trận hơn mỗi token: các layer attention, layer FFN, và projection đầu ra đều tỷ lệ tuyến tính với số lượng tham số
  • Tận dụng bộ nhớ đệm tốt hơn: mô hình nhỏ hơn khớp nhiều trọng số hơn trong bộ nhớ đệm L2/L3
  • Áp lực băng thông bộ nhớ thấp hơn: ít byte hơn phải đọc từ VRAM mỗi token

Trên một thiết lập khiêm tốn chỉ có CPU (2 lõi, không GPU), mô hình 1.5B tạo token với tốc độ gấp khoảng 2 lần so với mô hình 3B. Đây là sự khác biệt giữa "cảm giác như bot" và "cảm giác như người thật đang gõ".

Bộ nhớ đệm prompt khuếch đại lợi thế

Luna Protocol sử dụng llama-server với bộ nhớ đệm prompt được bật (--cache-reuse 256). Điều này có nghĩa:

  1. Tin nhắn đầu tiên trong một phiên chịu toàn bộ chi phí xử lý prompt (system prompt + ví dụ few-shot + tin nhắn người dùng)
  2. Các tin nhắn tiếp theo chỉ xử lý các token mới -- tiền tố được lưu trong bộ nhớ đệm được tái sử dụng
  3. Với 5 ví dụ few-shot (~50-150 token), chi phí là không đáng kể sau yêu cầu đầu tiên

Các ví dụ few-shot thực chất là "miễn phí" sau tin nhắn đầu tiên trong một phiên. Mô hình nhận được hướng dẫn phong cách với chi phí biên bằng không.


Triển khai: cách nó hoạt động trong code

Hệ thống few-shot trong Luna Protocol sạch sẽ và tối giản. Ba tệp xử lý mọi thứ:

1. Cấu hình (config.yml)

few_shot_enabled: true
few_shot_examples:
  - user: "yo whats good"
    assistant: "nm just chillin, u"
  - user: "bored af"
    assistant: "lol same energy fr"
  - user: "hey how are you"
    assistant: "im doing pretty good tbh, just vibing"
  - user: "whats up"
    assistant: "yooo not much, what about you"
  - user: "how was your day"
    assistant: "it was alright, nothing crazy happened lol"

Cấu hình có thể tải lại nóng. Thay đổi các ví dụ, lưu lại, và bot áp dụng phong cách mới ngay lập tức -- không cần khởi động lại.

2. Định dạng và tiêm (src/core/few-shot.ts)

Hàm formatFewShotExamples() chuyển đổi các ví dụ YAML thành các đối tượng tin nhắn ChatML:

export function formatFewShotExamples(
  examples: FewShotExample[],
  username = "user"
): Array<{ role: "user" | "assistant"; content: string }> {
  const messages = [];
  for (const example of examples) {
    messages.push({ role: "user", content: `${username}: ${example.user}` });
    messages.push({ role: "assistant", content: example.assistant });
  }
  return messages;
}

Hàm injectFewShotIntoConversation() đặt chúng ngay sau system prompt:

export function injectFewShotIntoConversation(
  messages: Message[],
  fewShotMessages: Message[]
): Message[] {
  const systemMessage = messages[0];
  const userMessages = messages.slice(1);
  return [systemMessage, ...fewShotMessages, ...userMessages];
}

3. Tích hợp (src/core/llm-client.ts)

Trước mỗi lần gọi LLM, các ví dụ few-shot được tiêm vào nếu được bật:

let finalMessages = messages;
if (FEW_SHOT_ENABLED && FEW_SHOT_EXAMPLES.length > 0) {
  const fewShotMessages = formatFewShotExamples(FEW_SHOT_EXAMPLES);
  finalMessages = injectFewShotIntoConversation(messages, fewShotMessages);
}

Mô hình nhận được: [system_prompt] + [few_shot_examples] + [conversation_history]


Giữ phong cách Discord-Dialogues

Bộ dữ liệu Discord-Dialogues gốc có một dấu ấn hội thoại rất cụ thể:

  • Tin nhắn ngắn: trung bình 32,8 token mỗi lượt
  • Thanh điệu không trang trọng: viết tắt, chữ thường, không dấu câu
  • Trao đổi nhanh: nhiều trao đổi ngắn thay vì độc thoại dài
  • Không hoàn hảo tự nhiên: lỗi gõ, "lol", "fr", "ngl", "tbh"

Mô hình Luna-Protocol giữ phong cách này thông qua hai cơ chế:

1. Fine-tuning dịch chuyển phân phối cơ sở

50k mẫu huấn luyện dạy mô hình dấu vân tay thống kê của các cuộc hội thoại Discord. Nó học rằng các phản hồi thường ngắn, chữ thường và không trang trọng. Điều này dịch chuyển đầu ra mặc định của mô hình ra khỏi chế độ trợ lý hữu ích của Qwen.

2. Few-shot priming khóa nó lại

Các ví dụ few-shot củng cố chính xác các mẫu mà mô hình đã học trong quá trình fine-tune. Chúng hoạt động như một neo phong cách -- ngay cả khi mô hình hơi trôi về giọng trang trọng trong một cuộc hội thoại dài, các ví dụ trong ngữ cảnh liên tục kéo nó trở lại.

Sự kết hợp mạnh mẽ hơn bất kỳ cơ chế nào một mình:

  • Fine-tune không có few-shot: mô hình nhìn chung thoải mái nhưng không nhất quán
  • Few-shot không có fine-tune: mô hình cố gắng làm theo ví dụ nhưng liên tục quay lại chế độ trợ lý
  • Fine-tune + few-shot: mô hình luôn nhất quán trong tính cách

Triết lý: mô hình nhỏ hơn, prompting thông minh hơn

Suy nghĩ thông thường trong triển khai LLM là "càng lớn càng tốt". Nhiều tham số hơn, nhiều dữ liệu huấn luyện hơn, nhiều VRAM hơn. Luna Protocol đi theo hướng ngược lại:

  • 1.5B thay vì 3B: một nửa tham số, một nửa bộ nhớ, gấp đôi tốc độ
  • 50k mẫu thay vì 7.3M: ít dữ liệu huấn luyện hơn, linh hoạt hơn cho học trong ngữ cảnh
  • Few-shot priming thay vì system prompt: cho mô hình thấy bạn muốn gì, đừng chỉ nói với nó

Đây không chỉ là một tối ưu hóa kỹ thuật -- nó là một triết lý thiết kế. Một bot Discord không cần phải là một trợ lý đa năng. Nó cần nói "nm just chillin, u" một cách nhất quán, nhanh chóng, và không ngốn hết ngân sách VRAM của máy chủ bạn.

Kết quả: một bot chạy trên VPS 5$/tháng, tạo token đủ nhanh để cảm giác như gõ phím thời gian thực, và duy trì một tính cách nhất quán thông qua sự kết hợp của fine-tuning và few-shot priming lớn hơn tổng các phần của nó.


Thiết lập

Tải mô hình

npm run download-model
# Tải Luna-Protocol-1.5B-Fine-Tuned-Qwen2.5.Q4_K_M.gguf

Hoặc thủ công từ HuggingFace.

Cấu hình

# config.yml
llama_model_path: "./models/Luna-Protocol-1.5B-Fine-Tuned-Qwen2.5.Q4_K_M.gguf"
few_shot_enabled: true
few_shot_examples:
  - user: "yo whats good"
    assistant: "nm just chillin, u"
  - user: "bored af"
    assistant: "lol same energy fr"
  - user: "hey how are you"
    assistant: "im doing pretty good tbh, just vibing"

Chạy

npm run dev                    # dev (tải lại nóng)
npm run build && npm start     # production
./start.sh                     # PM2 (production với llama-server)

Kết luận

Các mô hình Luna Protocol chứng minh rằng đối với AI hội thoại tập trung vào phong cách, ít hơn là nhiều hơn. Một mô hình 1.5B được huấn luyện trên 50k mẫu được chọn lọc kỹ lưỡng, được prime với vài ví dụ, vượt trội hơn mô hình 3B được huấn luyện trên hàng triệu ví dụ -- với một phần nhỏ chi phí bộ nhớ và gấp đôi tốc độ sinh.

Few-shot priming không chỉ là một tính năng tốt-để-có cho các mô hình nhỏ. Nó là cơ chế làm cho chúng khả thi cho các ứng dụng hội thoại thời gian thực. Các ví dụ không chỉ "giúp đỡ" -- chúng thay đổi cơ bản cách mô hình hoạt động, bằng cách khớp chính xác định dạng mà nó được huấn luyện.

Mã nguồn là mã nguồn mở, mô hình trên HuggingFace, và bộ dữ liệu công khai. Nếu bạn muốn xây dựng một bot hội thoại cảm giác như con người, công thức là: mô hình nhỏ, fine-tune hạn chế, few-shot priming mạnh.

Tài nguyên Liên kết
Kho GitHub fox3000foxy/luna-protocol-project
Mô hình (HuggingFace) fox3000foxy/Luna-Protocol-1.5B-Discord-Dialogues
Bộ dữ liệu Discord-Dialogues
Bài viết đầu tiên Luna Protocol: Tôi đã tạo một bot Discord tự động

Luna Protocol: ทำไมฉันถึง fine-tune โมเดล 1.5B บนตัวอย่าง Discord 50k ชิ้น และทำให้ few-shot priming กลายเป็นอาวุธลับ

โมเดลที่เล็กกว่าซึ่งเทรนบนข้อมูลน้อยกว่าสามารถทำงานได้ดีกว่าโมเดลที่ใหญ่กว่า -- ถ้าคุณรู้วิธี prime มัน นี่คือสาเหตุที่ Luna Protocol เปลี่ยนจาก Hermes 3B มาเป็น fine-tune Qwen 1.5B และทำไม few-shot priming ถึงกลายเป็นตัวเปลี่ยนเกมที่แท้จริง

Luna Protocol: ทำไมฉันถึง fine-tune โมเดล 1.5B บนตัวอย่าง Discord 50k ชิ้น และทำให้ few-shot priming กลายเป็นอาวุธลับ

ใน บทความแรก ฉันได้สร้างบอท Discord ที่จำลองพฤติกรรมมนุษย์ -- การนอน, การพิมพ์ผิด, การลังเล, การขี้ลืม, ข้อความที่เกิดขึ้นเอง ระบบพฤติกรรมนั้นแข็งแกร่ง LLM ที่อยู่เบื้องหลังคือโมเดล Hermes 3B ซึ่งถูก quantize เป็น Q8_0 กิน VRAM 3GB

มันใช้งานได้ แต่มันเกินความจำเป็น

บอท Discord ไม่ต้องการโมเดล 3B พารามิเตอร์เพื่อพูด "nm just chillin, u" สิ่งที่มันต้องการคือ ความสม่ำเสมอของสไตล์ -- ความสามารถในการรักษาน้ำเสียงสนทนาที่เฉพาะเจาะจง ข้อความแล้วข้อความเล่า โดยไม่ล่องลอยไปสู่โหมดผู้ช่วยองค์กร และปรากฏว่า โมเดลที่เล็กกว่าที่เทรนบนข้อมูลน้อยกว่า พร้อม prime ด้วยตัวอย่างสองสามชิ้น ทำได้ดีกว่าโมเดลที่ใหญ่กว่าที่พยายามบังคับผ่าน system prompt

บทความนี้เกี่ยวกับโมเดลทางการของ Luna Protocol: ทำไมมันถึงมีอยู่ ทำไมเป็น 1.5B แทนที่จะเป็น 3B ทำไมตัวอย่างเทรน 50k ชิ้นแทนที่จะเป็น 7.3M และทำไม few-shot priming ถึงเปลี่ยนจากสิ่งที่ดีถ้ามี กลายเป็นแกนกลางของแนวทางทั้งหมด


ปัญหากับโมเดล 3B

การตั้งค่าเดิมใช้ Discord-Micae-Hermes-3-3B.Q8_0.gguf -- โมเดล 3B พารามิเตอร์ที่ fine-tune บนข้อมูล Discord มันสร้างคำตอบที่ดี แต่:

เมตริก Hermes-3-3B Q8_0 เป้าหมาย
การใช้งาน VRAM ~3 GB < 1 GB
การสร้างโทเค็น ~30 tok/s ~60+ tok/s
ขนาดไฟล์โมเดล ~3.2 GB < 1 GB
เวลาเริ่มต้นเย็น ~8s ~3s

สำหรับบอทที่ทำงาน 24/7 บนเซิร์ฟเวอร์ธรรมดาๆ VRAM 3GB ถือว่าเยอะมาก และความเร็วในการสร้าง -- แม้จะใช้ได้สำหรับข้อความที่ไม่บ่อย -- รู้สึกช้าในช่วงที่มีการตอบกลับหลายครั้งหรือเมื่อหลายช่องทางทำงานพร้อมกัน

คำถามคือ: เราจะได้สไตล์ Discord-Dialogues เดิมด้วยพารามิเตอร์ครึ่งเดียวหรือไม่?


การตัดสินใจ fine-tune: ทำไม 50k ไม่ใช่ 7.3M

ชุดข้อมูล Discord-Dialogues มี 7.3M การแลกเปลี่ยน และ 17M เทิร์น มันเป็นคลังข้อมูลขนาดใหญ่ของการสนทนา Discord จริง วิธีการที่ชัดเจนคือการเทรนบนชุดข้อมูลทั้งหมด

ฉันทำตรงกันข้าม ฉันเทรนบน 50,000 ตัวอย่าง -- น้อยกว่า 1% ของข้อมูลที่มี

นี่คือสาเหตุ: ขนาดของชุดเทรนส่งผลโดยตรงต่อระดับที่โมเดล overfit ต่อการกระจายของชุดเทรน

โมเดลที่เทรนบน 7.3M ตัวอย่างเรียนรู้การกระจายทางสถิติที่เฉพาะเจาะจงมากของการสนทนา มันกลายเป็นเลิศในการสร้างการกระจายนั้นขึ้นมาใหม่ แต่มันก็กลายเป็น แข็งทื่อ -- มันมีความยืดหยุ่นน้อยลงในการปรับตัวกับรูปแบบใหม่ที่ให้มาที่เวลา inference

โมเดลที่เทรนบน 50k ตัวอย่างเรียนรู้น้ำเสียงและระดับภาษาทั่วไปของการสนทนา Discord (ไม่เป็นทางการ, สั้น, ตัวย่อ, ตัวพิมพ์เล็ก) แต่มันยังคงความยืดหยุ่นเพียงพอที่จะถูก นำทางโดยตัวอย่างในบริบท ตัวอย่าง few-shot ไม่ได้ต่อสู้กับการกระจายขนาดใหญ่ที่เรียนรู้มา -- มันเสริมการกระจายที่เบากว่า

นี่คือข้อมูลเชิงลึกหลัก: ข้อมูลเทรนที่จำกัดทำให้ few-shot priming มีประสิทธิภาพมากขึ้น


โมเดล: รายละเอียดทางเทคนิค

โมเดล Luna Protocol คือ fine-tune QLoRA ของ Qwen2.5-1.5B-Instruct:

พารามิเตอร์ ค่า
โมเดลฐาน unsloth/Qwen2.5-1.5B-Instruct-bnb-4bit
วิธีการ QLoRA (4-bit)
Rank LoRA r=16, lora_alpha=16
โมดูลเป้าหมาย q/k/v/o_proj, gate/up/down_proj
พารามิเตอร์ที่เทรนได้ 18,464,768 / 1,562,179,072 (1.18%)
ข้อมูลเทรน ~50,000 ตัวอย่าง (ชุดย่อยของ Discord-Dialogues)
ตัวกรอง 8-512 โทเค็นต่อตัวอย่าง
จำนวนรอบ 2-3
ฮาร์ดแวร์ Kaggle T4
เฟรมเวิร์ก Unsloth

ชุดข้อมูลเป็น fork ที่ผ่านการประมวลผลล่วงหน้าของ Discord-Dialogues กรองให้มีเฉพาะเทิร์น user/assistant ที่สะอาด -- ไม่มีข้อความระบบ ไม่มีเมตาดาต้า ไม่มีคำสั่งบอท สิ่งนี้สำคัญสำหรับตอนหลัง

การควอนไทซ์ที่มีให้เลือก

ไฟล์ การควอนไทซ์ ขนาด หมายเหตุ
Luna-Protocol-1.5B-Fine-Tuned-Qwen2.5.Q2_K.gguf Q2_K 676 MB เสื่อมคุณภาพอย่างเห็นได้ชัด -- ไม่แนะนำ
Luna-Protocol-1.5B-Fine-Tuned-Qwen2.5.Q4_K_M.gguf Q4_K_M 986 MB สมดุลขนาด/คุณภาพดี (แนะนำ)
Luna-Protocol-1.5B-Fine-Tuned-Qwen2.5.Q8_0.gguf Q8_0 1.65 GB ความเที่ยงตรงของสไตล์ดีที่สุด

โมเดลที่แนะนำคือ Q4_K_M -- ต่ำกว่า 1GB, เร็ว, และรักษาสไตล์การสนทนาได้ดี Q2_K เสื่อมคุณภาพมากเกินไปบนโมเดลเล็กขนาดนี้ Q8_0 มีคุณภาพดีที่สุดแต่ใช้หน่วยความจำมากกว่า 68%


ความก้าวหน้าของ few-shot priming

นี่คือส่วนที่เปลี่ยนแปลงทุกอย่าง

การ์ดโมเดล HuggingFace มีคำเตือน:

ด้วย prompt เปล่าๆ โดยไม่มีการ priming โมเดลนี้มีแนวโน้มที่จะกลับไปใช้น้ำเสียงผู้ช่วยเริ่มต้นของ Qwen การ prime สั้นๆ ด้วยตัวอย่างสองสามชิ้นสร้างความแตกต่างอย่างมาก

นี่ไม่ใช่บั๊ก -- มันเป็นผลโดยตรงจากวิธีที่ข้อมูลเทรนถูกจัดโครงสร้าง

ทำไม system prompt เพียงอย่างเดียวไม่ทำงาน

ข้อมูลเทรน Discord-Dialogues มีเฉพาะเทิร์น user/assistant ไม่มีตัวอย่างบทบาทระบบ ในชุดเทรน โมเดลไม่เคยถูกเทรนให้ทำตาม system prompt ในฐานะคำสั่งด้านสไตล์

เมื่อคุณให้ system prompt เช่น "ชื่อคุณคือ Luna พูดแบบสบายๆ" มันได้ยินคำสั่งแต่ไม่มีรูปแบบที่เรียนรู้มาอย่างแข็งแกร่งว่าจะแปลสิ่งนั้นเป็นเอาต์พุตอย่างไร มันกลับไปที่ค่าเริ่มต้นของ Qwen: ช่วยเหลือ มีโครงสร้าง เป็นทางการเล็กน้อย

ทำไมตัวอย่าง few-shot ถึงได้ผล

เมื่อคุณใส่ตัวอย่างการสนทนาในรูปแบบ ChatML เดียวกับที่โมเดลถูกเทรน (ใช้โครงสร้างเทิร์น user/assistant) บางอย่างก็เกิดขึ้น โมเดลจำรูปแบบจากข้อมูลเทรนของมันและปรับเอาต์พุตให้ตรงกัน

นี่คือลักษณะของ few-shot prime ในทางปฏิบัติ:

few_shot_examples:
  - user: "yo whats good"
    assistant: "nm just chillin, u"
  - user: "bored af"
    assistant: "lol same energy fr"
  - user: "hey how are you"
    assistant: "im doing pretty good tbh, just vibing"

ตัวอย่างเหล่านี้ถูกแทรกหลังจาก system prompt และก่อนการสนทนาจริง โมเดลมองเห็นพวกมันเป็นส่วนหนึ่งของประวัติการสนทนา ไม่ใช่เป็นคำสั่ง นี่คือความแตกต่างที่สำคัญ -- มันไม่ได้ถูก บอก ให้เป็นกันเอง แต่มันถูก แสดง ให้เห็นว่าการเป็นกันเองเป็นอย่างไร

ก่อนและหลัง

โดยไม่มี few-shot priming (system prompt เปล่า):

User: yo whats good
Bot: Hello! I am doing well, thank you for asking. How can I assist you today?

ด้วย few-shot priming (3 ตัวอย่าง):

User: yo whats good
Bot: nm just chillin, u

ความแตกต่างชัดเจน โมเดลไม่เพียงแค่สร้างคำที่แตกต่าง -- มันใช้ทะเบียนภาษาทั้งหมด: ตัวพิมพ์เล็ก, ตัวย่อ, น้ำเสียงสบายๆ, คำตอบสั้น มันจับคู่สไตล์ของตัวอย่าง ไม่ใช่สไตล์ของข้อมูลเทรนของ Qwen


หน่วยความจำและความเร็ว: ตัวเลขที่เป็นรูปธรรม

การเปลี่ยนจาก Hermes-3-3B เป็น Luna-Protocol-1.5B ให้ผลลัพธ์ที่วัดได้:

เมตริก Hermes-3-3B Q8_0 Luna-Protocol Q4_K_M การปรับปรุง
การใช้งาน VRAM ~3 GB ~986 MB น้อยลง 67%
ขนาดไฟล์โมเดล ~3.2 GB ~986 MB เล็กลง 69%
การสร้างโทเค็น ~30 tok/s ~60+ tok/s เร็วขึ้น 2 เท่า
เริ่มต้นเย็น ~8s ~3s เร็วขึ้น 62%
หน้าต่างบริบท 8192 8192 เท่าเดิม

ทำไมความเร็วที่เพิ่มขึ้นถึงเป็นจริง

โมเดลที่เล็กกว่าไม่ได้แค่ "ช้าลงน้อยกว่า" -- โดยพื้นฐานแล้วมันเร็วกว่าสำหรับ inference ด้วย 1.5B พารามิเตอร์แทนที่จะเป็น 3B:

  • การคูณเมทริกซ์น้อยลง ต่อโทเค็น: เลเยอร์ attention, เลเยอร์ FFN, และ projection เอาต์พุตล้วนเพิ่มเป็นเส้นตรงตามจำนวนพารามิเตอร์
  • การใช้แคชดีขึ้น: โมเดลที่เล็กกว่าใส่น้ำหนักได้มากขึ้นในแคช L2/L3
  • แรงดันแบนด์วิดท์หน่วยความจำต่ำลง: ไบต์น้อยลงที่ต้องอ่านจาก VRAM ต่อโทเค็น

บนการตั้งค่า CPU-only ธรรมดา (2 คอร์, ไม่มี GPU) โมเดล 1.5B สร้างโทเค็นด้วยความเร็วประมาณ 2 เท่า ของโมเดล 3B นี่คือความแตกต่างระหว่าง "รู้สึกเหมือนบอท" และ "รู้สึกเหมือนคนกำลังพิมพ์"

การแคช prompt ขยายความได้เปรียบ

Luna Protocol ใช้ llama-server โดยเปิดการแคช prompt (--cache-reuse 256) ซึ่งหมายความว่า:

  1. ข้อความแรกในเซสชันจ่ายต้นทุนการประมวลผล prompt ทั้งหมด (system prompt + ตัวอย่าง few-shot + ข้อความผู้ใช้)
  2. ข้อความถัดไปประมวลผลเฉพาะโทเค็น ใหม่ -- คำนำหน้าที่ถูกแคชถูกนำกลับมาใช้ใหม่
  3. ด้วยตัวอย่าง few-shot 5 ชิ้น (~50-150 โทเค็น) ต้นทุนเพิ่มเติมนั้นเล็กน้อยหลังจากคำขอแรก

ตัวอย่าง few-shot มีประสิทธิภาพ "ฟรี" หลังจากข้อความแรกในเซสชัน โมเดลได้รับคำแนะนำด้านสไตล์โดยมีต้นทุนส่วนเพิ่มเป็นศูนย์


การนำไปใช้: ทำงานอย่างไรในโค้ด

ระบบ few-shot ใน Luna Protocol สะอาดและเรียบง่าย สามไฟล์จัดการทุกอย่าง:

1. การกำหนดค่า (config.yml)

few_shot_enabled: true
few_shot_examples:
  - user: "yo whats good"
    assistant: "nm just chillin, u"
  - user: "bored af"
    assistant: "lol same energy fr"
  - user: "hey how are you"
    assistant: "im doing pretty good tbh, just vibing"
  - user: "whats up"
    assistant: "yooo not much, what about you"
  - user: "how was your day"
    assistant: "it was alright, nothing crazy happened lol"

การกำหนดค่าสามารถโหลดซ้ำได้แบบ hot เปลี่ยนตัวอย่าง, บันทึก, และบอทจะใช้สไตล์ใหม่ทันที -- ไม่ต้องรีสตาร์ท

2. การจัดรูปแบบและการแทรก (src/core/few-shot.ts)

ฟังก์ชัน formatFewShotExamples() แปลงตัวอย่าง YAML เป็นออบเจกต์ข้อความ ChatML:

export function formatFewShotExamples(
  examples: FewShotExample[],
  username = "user"
): Array<{ role: "user" | "assistant"; content: string }> {
  const messages = [];
  for (const example of examples) {
    messages.push({ role: "user", content: `${username}: ${example.user}` });
    messages.push({ role: "assistant", content: example.assistant });
  }
  return messages;
}

ฟังก์ชัน injectFewShotIntoConversation() วางพวกมันไว้หลัง system prompt ทันที:

export function injectFewShotIntoConversation(
  messages: Message[],
  fewShotMessages: Message[]
): Message[] {
  const systemMessage = messages[0];
  const userMessages = messages.slice(1);
  return [systemMessage, ...fewShotMessages, ...userMessages];
}

3. การบูรณาการ (src/core/llm-client.ts)

ก่อนการเรียก LLM ทุกครั้ง ตัวอย่าง few-shot จะถูกแทรกถ้าเปิดใช้งาน:

let finalMessages = messages;
if (FEW_SHOT_ENABLED && FEW_SHOT_EXAMPLES.length > 0) {
  const fewShotMessages = formatFewShotExamples(FEW_SHOT_EXAMPLES);
  finalMessages = injectFewShotIntoConversation(messages, fewShotMessages);
}

โมเดลได้รับ: [system_prompt] + [few_shot_examples] + [conversation_history]


การรักษาสไตล์ Discord-Dialogues

ชุดข้อมูล Discord-Dialogues ดั้งเดิมมีลายเซ็นการสนทนาที่เฉพาะเจาะจงมาก:

  • ข้อความสั้น: เฉลี่ย 32.8 โทเค็นต่อเทิร์น
  • ระดับภาษาไม่เป็นทางการ: ตัวย่อ, ตัวพิมพ์เล็ก, ไม่มีเครื่องหมายวรรคตอน
  • การโต้ตอบเร็ว: การแลกเปลี่ยนสั้นๆ หลายครั้งแทนการพูดคนเดียวยาว
  • ความไม่สมบูรณ์แบบตามธรรมชาติ: การพิมพ์ผิด, "lol", "fr", "ngl", "tbh"

โมเดล Luna-Protocol รักษาสไตล์นี้ผ่านสองกลไก:

1. Fine-tuning เปลี่ยนการกระจายฐาน

ตัวอย่างเทรน 50k สอนโมเดล ลายนิ้วมือทางสถิติ ของการสนทนา Discord มันเรียนรู้ว่าการตอบกลับมักจะสั้น ตัวพิมพ์เล็ก และไม่เป็นทางการ สิ่งนี้เปลี่ยนเอาต์พุตเริ่มต้นของโมเดลออกจากโหมดผู้ช่วยของ Qwen

2. Few-shot priming ล็อคมันไว้

ตัวอย่าง few-shot ตอกย้ำรูปแบบที่แน่นอนที่โมเดลเรียนรู้ระหว่าง fine-tuning พวกมันทำหน้าที่เป็น สมอของสไตล์ -- ถึงแม้โมเดลจะล่องลอยไปทางน้ำเสียงทางการเล็กน้อยระหว่างการสนทนายาว ตัวอย่างในบริบทก็ยังคงดึงมันกลับมา

การรวมกันมีพลังมากกว่ากลไกใดๆ เพียงอย่างเดียว:

  • Fine-tuning โดยไม่มี few-shot: โมเดล โดยทั่วไป เป็นกันเองแต่ไม่สม่ำเสมอ
  • Few-shot โดยไม่มี fine-tuning: โมเดลพยายามทำตามตัวอย่างแต่กลับไปโหมดผู้ช่วยซ้ำแล้วซ้ำเล่า
  • Fine-tuning + few-shot: โมเดล สม่ำเสมอ อยู่ในบุคลิก

ปรัชญา: โมเดลเล็กกว่า, prompting ฉลาดกว่า

ภูมิปัญญาดั้งเดิมในการปรับใช้ LLM คือ "ยิ่งใหญ่ยิ่งดี" พารามิเตอร์มากขึ้น, ข้อมูลเทรนมากขึ้น, VRAM มากขึ้น Luna Protocol ใช้แนวทางตรงกันข้าม:

  • 1.5B แทน 3B: ครึ่งหนึ่งของพารามิเตอร์, ครึ่งหนึ่งของหน่วยความจำ, ความเร็วสองเท่า
  • 50k ตัวอย่างแทน 7.3M: ข้อมูลเทรนน้อยลง, ความยืดหยุ่นมากขึ้นสำหรับการเรียนรู้ในบริบท
  • Few-shot priming แทน system prompt: แสดงให้โมเดลเห็นสิ่งที่คุณต้องการ อย่าแค่บอกมัน

นี่ไม่ใช่แค่การเพิ่มประสิทธิภาพทางเทคนิค -- มันเป็นปรัชญาการออกแบบ บอท Discord ไม่จำเป็นต้องเป็นผู้ช่วยอเนกประสงค์ มันต้องพูด "nm just chillin, u" อย่างสม่ำเสมอ รวดเร็ว และโดยไม่กินงบ VRAM ทั้งหมดของเซิร์ฟเวอร์คุณ

ผลลัพธ์: บอทที่ทำงานบน VPS ราคา $5/เดือน, สร้างโทเค็นเร็วพอที่จะรู้สึกเหมือนกำลังพิมพ์แบบเรียลไทม์, และรักษาบุคลิกที่สม่ำเสมอผ่านการผสมผสานของ fine-tuning และ few-shot priming ที่มากกว่าผลรวมของส่วนประกอบแต่ละส่วน


การตั้งค่า

ดาวน์โหลดโมเดล

npm run download-model
# ดาวน์โหลด Luna-Protocol-1.5B-Fine-Tuned-Qwen2.5.Q4_K_M.gguf

หรือด้วยตนเองจาก HuggingFace

กำหนดค่า

# config.yml
llama_model_path: "./models/Luna-Protocol-1.5B-Fine-Tuned-Qwen2.5.Q4_K_M.gguf"
few_shot_enabled: true
few_shot_examples:
  - user: "yo whats good"
    assistant: "nm just chillin, u"
  - user: "bored af"
    assistant: "lol same energy fr"
  - user: "hey how are you"
    assistant: "im doing pretty good tbh, just vibing"

รัน

npm run dev                    # dev (โหลดซ้ำแบบ hot)
npm run build && npm start     # production
./start.sh                     # PM2 (production กับ llama-server)

บทสรุป

โมเดล Luna Protocol พิสูจน์ว่าสำหรับ AI การสนทนาที่เน้นสไตล์ น้อยคือมากกว่า โมเดล 1.5B ที่เทรนบน 50k ตัวอย่างที่คัดสรรมาอย่างดี, ถูก prime ด้วยตัวอย่างสองสามชิ้น, ทำงานได้ดีกว่าโมเดล 3B ที่เทรนบนตัวอย่างนับล้าน -- ด้วยต้นทุนหน่วยความจำเพียงเศษเสี้ยวและความเร็วในการสร้างสองเท่า

Few-shot priming ไม่ใช่แค่สิ่งที่ดีถ้ามีสำหรับโมเดลเล็ก มันเป็นกลไกที่ทำให้โมเดลเหล่านั้นใช้งานได้สำหรับแอปพลิเคชันการสนทนาแบบเรียลไทม์ ตัวอย่างไม่ได้แค่ "ช่วย" -- มันเปลี่ยนวิธีที่โมเดลทำงานโดยพื้นฐาน โดยการจับคู่รูปแบบที่แน่นอนที่มันถูกเทรน

โค้ดเป็นโอเพนซอร์ส, โมเดลอยู่บน HuggingFace, และชุดข้อมูลเป็นสาธารณะ ถ้าคุณต้องการสร้างบอทสนทนาที่ให้ความรู้สึกเหมือนมนุษย์ สูตรคือ: โมเดลเล็ก, fine-tuning จำกัด, few-shot priming ที่แข็งแกร่ง

แหล่งข้อมูล ลิงก์
พื้นที่เก็บ GitHub fox3000foxy/luna-protocol-project
โมเดล (HuggingFace) fox3000foxy/Luna-Protocol-1.5B-Discord-Dialogues
ชุดข้อมูล Discord-Dialogues
บทความแรก Luna Protocol: ฉันสร้างบอท Discord อัตโนมัติ

Related Articles