בונים LLM מאפס
מהמתמטיקה של attention ועד inference יעיל — בניית מודל לחלוטין משלך, שלב אחד אחרי השני.
מבוא: איך LLM באמת עובד
tokens, embeddings, attention, layers — המנגנון שמאחורי כל מודל מודרני. הוכחה ידנית של כל שלב.
כדי להבין באמת כיצד מודלי שפה ענקיים (LLMs) כמו Claude או Gemini מייצרים טקסט קוהרנטי, עלינו לקלף את שכבות האבסטרקטציה ולצלול למנגנון המתמטי שמניע אותם. בבסיסו, LLM אינו "חושב" במובן האנושי, אלא מתפקד כמנוע חיזוי סטטיסטי מתוחכם המבוסס על ארכיטקטורת Transformer. התהליך מתחיל ב-Tokenization, שבו טקסט חופשי מפורק ליחידות מידע בסיסיות (Tokens), אשר מתורגמות לוקטורים רב-ממדיים (Embeddings) המייצגים את המשמעות הסמנטית שלהם במרחב הגיאומטרי.
לב ה-Transformer הוא מנגנון ה-Self-Attention (קשב עצמי). מנגנון זה מאפשר לכל טוקן "להביט" על שאר הטוקנים במשפט ולחשב משקלים דינמיים המגדירים את מידת הרלוונטיות שלהם אליו. החישוב מתבצע באמצעות שלוש מטריצות: Queries (שאילתות), Keys (מפתחות) ו-Values (ערכים). מכפלת ה-Query ב-Key מייצרת ציון קשר, שעובר נרמול (Softmax) ומוכפל ב-Value. המידע המעובד הזה עובר דרך עשרות שכבות (Layers) של Feed-Forward Networks ו-Normalization, שבהן המודל מזקק ייצוגים מופשטים יותר ויותר של ההקשר. מחקרים עדכניים, כמו המחקר על בחירה אוטומטית של שכבות לזיהוי הזיות, מראים כי שכבות שונות במודל מתמחות בייצוגים שונים, וכי ניתן לזהות חוסר עקביות או הזיות על ידי ניתוח אקטיבציות בשכבות ספציפיות.
הבנת המנגנון הפנימי הזה קריטית לא רק עבור חוקרי בינה מלאכותית, אלא עבור כל מפתח שרוצה לבנות מערכות פרודקשן אמינות. כאשר אנו מעצבים ארכיטקטורות מורכבות כמו סוכני AI, אנו נתקלים במגבלות פיזיות של זיכרון ועיבוד. לדוגמה, במאמר העוסק בשאלה האם זיכרון של סוכנים הוא מסד נתונים, נבחנת הדרך שבה מודלים מאחזרים ומקודדים מידע ארוך טווח, דבר המושפע ישירות מאופן פעולת ה-Embeddings וחלון ההקשר (Context Window). בנוסף, בניתוח של הדליפה של Claude Code ניתן לראות כיצד הבנה מעמיקה של אופן פעולת המודל והאינטראקציה שלו עם סביבת העבודה מאפשרת בניית סוכנים יעילים במיוחד.
כדי להמחיש את החישוב הידני של מנגנון ה-Attention, נביט בקוד PyTorch פשוט המבצע את פעולת ה-Scaled Dot-Product Attention הבסיסית. זהו הלב הפועם של כל מודל שפה מודרני:
import torch
import torch.nn.functional as F
# 3 tokens, embedding size 4
q = torch.randn(1, 3, 4)
k = torch.randn(1, 3, 4)
v = torch.randn(1, 3, 4)
# Calculate Attention Scores
d_k = q.size(-1)
scores = torch.matmul(q, k.transpose(-2, -1)) / (d_k ** 0.5)
attention_weights = F.softmax(scores, dim=-1)
# Apply weights to Values
output = torch.matmul(attention_weights, v)
print("Output shape:", output.shape)
כדי לקחת את ההבנה הזו לשלב הבא, מומלץ לחקור פרויקטים שמממשים את התיאוריה הזו מאפס. במקום להסתמך על ספריות קצה גבוהות, התנסות מעשית בקוד פתוח תחשוף את האתגרים האמיתיים של אופטימיזציה וחישוב מבוזר.
הצעד הבא שלכם: הורידו והריצו את פרויקט nanoGPT של Karpathy. זהו מימוש נקי, קריא וקל להבנה של GPT ב-PyTorch. הריצו את קובץ ה-train.py על קובץ הטקסט של שייקספיר (ייקח לכם כ-3 דקות על GPU פשוט), ועקבו שורה אחר שורה אחרי האופן שבו ה-Embeddings, ה-Attention וה-Layers מתחברים יחד לכדי מודל שמייצר טקסט קוהרנטי מאפס. למי שרוצה לרדת לרמת החומרה ללא PyTorch כלל, מומלץ להעיף מבט ב-llm.c המממש GPT-2 ישירות ב-C/CUDA.
טוקנייזר: BPE מאפס
מימוש Byte Pair Encoding משלך. הבנה איך טקסט הופך לטוקנים ולמה זה משנה.
בעולם של מודלי שפה גדולים (LLMs), הטקסט שאנו קוראים אינו מוזן ישירות לרשת הנוירונים. במקום זאת, הוא עובר תהליך של טוקניזציה (Tokenization) – פירוק הטקסט ליחידות משמעותיות קטנות הנקראות טוקנים (Tokens). האלגוריתם הסטנדרטי והנפוץ ביותר כיום למשימה זו הוא Byte Pair Encoding (BPE). הבנת ה-BPE מאפס היא קריטית עבור מפתחי AI מתקדמים, שכן היא חושפת את "הקופסה השחורה" שבין הטקסט הגולמי לבין ה-Embeddings של המודל.
מדוע חשוב להבין ולממש BPE בעצמנו? רוב הבעיות המוזרות של מודלי שפה – כמו הקושי בהיפוך מילים, ספירת תווים או התמודדות עם שפות שאינן אנגלית – נובעות ישירות מהטוקנייזר. כאשר אנו מבינים כיצד הטוקנייזר מייצג טקסט כרצף של בייטים (Bytes) ואיך הוא ממזג אותם באופן איטרטיבי, אנו יכולים לתכנן מודלים יעילים יותר, לחסוך בעלויות הקשר (Context Window) ולמנוע באגים חמקמקים בזמן ייצור.
האלגוריתם עובד בצורה פשוטה אך גאונית: אנו מתחילים בייצוג הטקסט כרצף של בייטים בודדים (ערכים בין 0 ל-255). לאחר מכן, אנו סופרים את כל זוגות הבייטים הסמוכים הנפוצים ביותר בטקסט האימון שלנו, וממזגים את הזוג הנפוץ ביותר לטוקן חדש (למשל, מספר 256). אנו חוזרים על התהליך הזה שוב ושוב עד שאנו מגיעים לגודל המילון (Vocabulary Size) הרצוי.
הנה מימוש בסיסי בפייתון של שלב ספירת הזוגות ומיזוגם בתוך אלגוריתם BPE:
def get_stats(ids):
counts = {}
for pair in zip(ids, ids[1:]):
counts[pair] = counts.get(pair, 0) + 1
return counts
def merge(ids, pair, idx):
newids = []
i = 0
while i < len(ids):
if i < len(ids) - 1 and (ids[i], ids[i+1]) == pair:
newids.append(idx)
i += 2
else:
newids.append(ids[i])
i += 1
return newids
הבנה מעמיקה של טוקניזציה חיונית במיוחד כאשר עוסקים במערכות מורכבות הדורשות דיוק גבוה. לדוגמה, במחקר על אימות נוירו-סימבולי של פלטי LLM עבור דומיינים רגישי מידע, ייצוג הטוקנים משפיע ישירות על היכולת לאכוף חוקים לוגיים על הפלט. כמו כן, שינויים ועדכונים במנועי האינדוקס כמו llama-index-core 0.14.16 מדגישים את החשיבות של ניהול נכון של טקסט וטוקנים בשלבי ה-Parsing וה-Embedding של מסמכים.
הצעד הבא שלכם: כדי להבין את הנושא לעומק, מומלץ להתחיל עם הפרויקט minBPE של Karpathy. זהו מימוש מינימלי ונקי המאפשר לכם לבנות טוקנייזר משלכם (בדומה לזה של GPT-4) תוך פחות משעה. הורידו את הקוד, הריצו אותו על טקסט בעברית, וראו כיצד המילון נבנה ומייצג את השפה שלנו בצורה יעילה.
training loop מינימלי
אימון מודל GPT קטן על Shakespeare/Tiny Stories. forward pass, backward pass, optimizer, scheduler.
בעולם של מודלי שפה גדולים, קל ללכת לאיבוד מאחורי ספריות עיטוף (wrappers) ברמה גבוהה כמו Hugging Face. עם זאת, כדי להבין באמת כיצד מודל GPT לומד, עלינו לצלול אל ה-training loop (לולאת האימון) המינימלית. לולאה זו היא הלב הפועם של כל תהליך למידת מכונה: היא מזינה את המודל בנתונים, מעריכה את השגיאות שלו, ומעדכנת את הפרמטרים שלו בהתאם. הבנת המכניקה הזו ברמת ה-PyTorch הבסיסית חיונית לדיבאגינג, לאופטימיזציה של ביצועים ולפיתוח ארכיטקטורות מותאמות אישית.
לולאת אימון בסיסית מורכבת מארבעה שלבים מרכזיים החוזרים על עצמם בכל איטרציה (step). השלב הראשון הוא ה-forward pass, שבו אנו מזינים את ה-tokens של הטקסט (למשל, מתוך מאגר Shakespeare או Tiny Stories) אל תוך המודל ומקבלים את ה-logits (התחזיות). מתוך ה-logits הללו אנו מחשבים את ה-loss (לרוב Cross Entropy Loss) מול ה-targets (הטוקן הבא האמיתי). מיד לאחר מכן מגיע ה-backward pass: באמצעות הקריאה ל-loss.backward(), מנוע ה-Autograd של PyTorch מחשב את הנגזרות החלקיות (הגרדיאנטים) של ה-loss ביחס לכל אחד מהפרמטרים הניתנים לאימון במודל.
לאחר חישוב הגרדיאנטים, נכנס לתמונה ה-optimizer (כמו AdamW). תפקידו לעדכן את משקולות המודל בכיוון שמפחית את ה-loss, באמצעות הפעלת optimizer.step(). לפני המעבר לאיטרציה הבאה, חובה לאפס את הגרדיאנטים בעזרת optimizer.zero_grad(set_to_none=True) כדי למנוע הצטברות לא רצויה שלהם. כדי לשפר את היציבות ואת מהירות ההתכנסות, נהוג לשלב learning rate scheduler (כמו Cosine Decay). ה-scheduler משנה את קצב הלמידה לאורך זמן: הוא מתחיל נמוך (warmup), מגיע לשיא, ואז דועך בהדרגה ככל שהאימון מתקדם.
הנה דוגמה קלאסית ומינימלית ללולאת אימון ב-PyTorch:
import torch
model.train()
optimizer = torch.optim.AdamW(model.parameters(), lr=6e-4)
scheduler = torch.optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max=1000)
for step in range(max_steps):
inputs, targets = get_batch() # שליפת batch מתוך Shakespeare
logits, loss = model(inputs, targets) # Forward pass
loss.backward() # Backward pass
torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm=1.0)
optimizer.step() # Update weights
scheduler.step() # Update learning rate
optimizer.zero_grad(set_to_none=True) # Reset gradients
כדי לראות כיצד הקוד המינימלי הזה מתרחב למערכות פרודקשן אמיתיות, מומלץ לחקור את פרויקט nanoGPT של Andrej Karpathy. בקובץ train.py שלו תוכלו לראות בדיוק כיצד הלולאה הזו נבנית מאפס, כולל תמיכה ב-mixed precision (FP16/BF16) וחלוקה ל-validation. מקור מצוין נוסף להבנת הארכיטקטורה מקצה לקצה הוא הספר Build a LLM from Scratch מאת Sebastian Raschka, שמסביר צעד אחר צעד כיצד לחבר את חלקי הפאזל של ה-tokenizer, המודל ולולאת האימון.
הצעד הבא שלכם: הורידו את ה-repository של nanoGPT, הריצו את סקריפט הכנת הנתונים על קובץ ה-Shakespeare המינימלי (data/shakespeare_char/prepare.py), והפעילו את ה-training loop המקומית בעזרת train.py. עקבו אחר ירידת ה-loss בזמן אמת ונסו לשנות את ה-learning rate כדי לראות כיצד זה משפיע על קצב ההתכנסות של המודל.
Fine-tuning עם LoRA
מ-base model ל-assistant: SFT עם Llama/Qwen קטנים. unsloth + datasets קצרים.
תהליך ה-Fine-tuning (כיוונון עדין) הוא השלב הקריטי שבו אנו לוקחים מודל בסיס (Base Model) כמו Llama 3 או Qwen, אשר אומן רק לנחש את המילה הבאה, והופכים אותו לעוזר אישי (Assistant) המסוגל לענות לשאלות, לעקוב אחר הוראות ולשמור על פורמט שיחה קבוע. תהליך זה נקרא Supervised Fine-Tuning (SFT), והוא מאפשר לנו להטמיע במודל סגנון דיבור ספציפי, ידע ייחודי או יכולת עבודה מדויקת עם ממשקים חיצוניים.\n\nבעבר, כיוונון מלא של מודלי שפה דרש משאבי מחשוב עצומים וכרטיסי מסך (GPUs) יקרים במיוחד. טכנולוגיית LoRA (Low-Rank Adaptation) פותרת את הבעיה הזו על ידי הקפאת משקלי המודל המקוריים והוספת מטריצות קטנות ורזות (Low-Rank) לשכבות ה-Attention. במהלך האימון אנו מעדכנים רק את המטריצות הללו, מה שמפחית את מספר הפרמטרים המאומנים בלמעלה מ-99%, חוסך זיכרון וידאו (VRAM) ומאפשר להריץ אימונים מלאים על חומרה נגישה.\n\nכדי להתחיל לעבוד בצורה המהירה ביותר, מומלץ להשתמש בספריית unsloth. היא מציעה האצה של פי 2 במהירות האימון וחיסכון של כ-70% בזיכרון ה-GPU בזכות קרנלים מותאמים אישית ב-Triton. עבור פרויקטים מורכבים יותר הדורשים אימון מבוזר על מספר כרטיסי מסך, ספריות כמו axolotl או TRL של HuggingFace יספקו את הגמישות והכלים הדרושים לניהול פייפליין האימון.\n\nהנה דוגמה קצרצרה לאימוץ מודל Llama 3 בעזרת Unsloth:\n\n``python\nfrom unsloth import FastLanguageModel\nimport torch\n\n# 1. טעינת המודל והטוקנייזר עם תמיכת LoRA מובנית\nmodel, tokenizer = FastLanguageModel.from_pretrained(\n model_name="unsloth/llama-3-8b-Instruct-bnb-4bit",\n max_seq_length=2048,\n load_in_4bit=True,\n)\n\n# 2. הגדרת פרמטרי LoRA\nmodel = FastLanguageModel.get_peft_model(\n model, \n r=16, \n target_modules=["q_proj", "k_proj", "v_proj", "o_proj"],\n lora_alpha=16,\n lora_dropout=0,\n bias="none"\n)\n``\n\nאימון מוצלח אינו דורש מיליוני דוגמאות; לעיתים קרובות, דאטהסט איכותי וממוקד של כ-1,000 דוגמאות שיחה יספיק כדי לשנות לחלוטין את התנהגות המודל. כיוונון כזה קריטי במיוחד כאשר רוצים שהמודל יתממשק בצורה אמינה עם ספריות קוד מתקדמות, למשל לצורך הפקת פלטים מובנים ב-pydantic-ai v1.98.0 או לשילובו כסוכן חכם בתוך ארכיטקטורת סוכנים מרובים כמו LangGraph 1.2.1.\n\nהצעד הבא שלכם: פתחו את אחד ממחברות ה-Colab המוכנות של unsloth, טענו דאטהסט קטן בפורמט Alpaca (למשל, הוראות ומענים של שירות לקוחות או פורמט JSON ספציפי), והריצו אימון LoRA ראשון. בתוך פחות מ-20 דקות יהיה לכם מודל מותאם אישית שתוכלו להעלות ישירות ל-HuggingFace Hub.
post-training: RLHF / DPO
איך מודל בסיס הופך ל-chat assistant. השוואת RLHF (PPO) מול DPO. TRL ב-Python.
מודלי בסיס (Base Models) מצטיינים בניבוי הטוקן הבא על גבי קורפוס עצום של טקסט, אך הם אינם מותאמים מטבעם לשיחה אינטראקטיבית עם בני אדם. כדי להפוך מודל גולמי לעוזר אישי (Chat Assistant) מועיל, בטוח ומנומס, אנו נדרשים לשלב ה-Post-training. שלב זה מתמקד בהתאמת התנהגות המודל להעדפות אנושיות (Alignment), ומבוצע לרוב באמצעות שיטות של למידת חיזוק (Reinforcement Learning) או אופטימיזציה ישירה של העדפות.
השיטה הקלאסית, RLHF (שמבוססת לרוב על אלגוריתם PPO), דורשת אימון של מודל תגמול (Reward Model) נפרד שמדרג את תשובות המודל, ולאחר מכן הרצת לולאת RL מורכבת לעדכון המודל היוצר (Actor). תהליך זה נוטה לחוסר יציבות וצורך משאבי חישוב אדירים. לעומתה, שיטת DPO (Direct Preference Optimization) חוללה מהפכה בכך שהיא מייתרת את מודל התגמול ואת לולאת ה-RL. DPO מגדירה פונקציית הפסד (Loss) ישירה על זוגות של העדפות (תשובה מועדפת מול תשובה דחויה), ומאפשרת אופטימיזציה יציבה ומהירה בהרבה, הדומה לאימון מפוקח (SFT) רגיל.
עם זאת, הבחירה בין השתיים אינה חד-משמעית. בעוד ש-DPO מצוינת למשימות סגנון והעדפה כללית, מחקרים מראים כי במשימות חשיבה מורכבות ודיאלוגים רב-סבביים, למידת חיזוק אינטראקטיבית עדיין מחזיקה ביתרון משמעותי. לדוגמה, במאמר מאימון סטטי ל-RL אינטראקטיבי מכויל: הפחתת היסט התפלגות בדיאלוג רב-סבבים מוסבר כיצד RL אינטראקטיבי מפחית את היסט ההתפלגות (Distribution Shift) בשיחות ארוכות. כמו כן, מחקרים כמו עומק חשיבה ומורכבות סביבה מראים כיצד שילוב של סביבות למידה מבוססות כללים (RLVR) חיוני לפיתוח יכולות חשיבה לוגית מתקדמות במודלים.
כדי ליישם שיטות אלו בפועל, ספריית TRL (Transformer Reinforcement Learning) מבית Hugging Face מציעה פתרון אינטגרטיבי ונוח. הספרייה מספקת מחלקות ייעודיות כמו DPOTrainer ו-PPOTrainer המאפשרות לבצע את תהליך ה-Alignment בכמה שורות קוד בודדות, תוך תמיכה בטכניקות יעילות זיכרון כמו LoRA ו-DeepSpeed.
להלן דוגמה בסיסית להגדרת אימון DPO באמצעות TRL ב-Python:
from transformers import AutoModelForCausalLM, AutoTokenizer
from trl import DPOTrainer, DPOConfig
from datasets import load_dataset
model = AutoModelForCausalLM.from_pretrained("gpt2")
ref_model = AutoModelForCausalLM.from_pretrained("gpt2")
tokenizer = AutoTokenizer.from_pretrained("gpt2")
tokenizer.pad_token = tokenizer.eos_token
dataset = load_dataset("Anthropic/hh-rlhf", split="train[:100]")
training_args = DPOConfig(output_dir="./dpo_results", beta=0.1, max_length=512)
trainer = DPOTrainer(model, ref_model, args=training_args, train_dataset=dataset, tokenizer=tokenizer)
trainer.train()
הצעד הבא שלכם: כדי להתחיל להתנסות, מומלץ לשכפל את מאגר הקוד של TRL ולהריץ את סקריפט ה-DPO המובנה (examples/scripts/dpo.py) על גבי דאטהסט קטן כמו Anthropic/hh-rlhf. אם אתם מכוונים לאימון מודלים ענקיים על גבי מספר כרטיסי מסך, כדאי לבחון את OpenRLHF המציע תשתית מבוזרת ויציבה המשלבת את Ray ו-DeepSpeed.
Inference יעיל — KV cache, sampling, quantization
אופטימיזציות שמשנות סדרי גודל בביצועים: KV cache, beam vs greedy vs nucleus, INT8/4 quantization.
הרצת מודלי שפה גדולים (LLMs) בסביבת פרודקשן מציבה אתגרים עצומים של זיכרון ורוחב פס (Memory Bandwidth). בניגוד לשלב האימון (Training) שבו החישובים מתבצעים במקביל, שלב ה-Inference הוא אוטורגרסיבי (Auto-regressive) – המודל מייצר טוקן אחר טוקן, כאשר כל טוקן חדש דורש חישוב מחדש של כל ההקשר שקדם לו. כדי למנוע צווארי בקבוק אלו ולשפר את ה-Throughput ואת ה-Latency בסדרי גודל, אנו משתמשים בשלוש טכניקות אופטימיזציה מרכזיות: KV cache, Sampling מתקדם ו-Quantization (קוונטיזציה).
הטכניקה הבסיסית והחשובה ביותר היא KV cache (Key-Value cache). בכל צעד של יצירת טוקן, מנגנון ה-Attention צריך לחשב את ה-Keys וה-Values עבור כל הטוקנים הקודמים. במקום לחשב אותם מחדש בכל טוקן חדש (מה שיוצר סיבוכיות של $O(N^2)$ בזמן החישוב), אנו שומרים את ה-Keys וה-Values של הטוקנים הקודמים בזיכרון ה-GPU. פרויקטים מתקדמים כמו vLLM לקחו את זה צעד קדימה עם PagedAttention, המנהל את זיכרון ה-KV cache בדומה לניהול זיכרון וירטואלי במערכות הפעלה, ובכך מונע פרגמנטציה ומאפשר Batching דינמי ויעיל במיוחד.
כדי להתמודד עם מגבלת הזיכרון הפיזי (VRAM), אנו משתמשים ב-Quantization (דחיסת משקולות). מודלים מיוצגים במקור בפורמט FP16 או BF16 (שני בייטים לפרמטר). קוונטיזציה ל-INT8 או INT4 מאפשרת לדחוס את משקולות המודל פי 2 עד 4, כמעט ללא פגיעה בדיוק המודל. כלי כמו llama.cpp מאפשר להריץ מודלים ענקיים על חומרת קצה (כמו מעבדי Apple Silicon או אפילו CPU פשוט) בזכות מימוש יעיל במיוחד של קוונטיזציות מסוג GGUF.
היבט נוסף המשפיע על יעילות ואיכות ה-Inference הוא אסטרטגיית ה-Sampling. בעוד ש-Greedy Search בוחר תמיד את הטוקן בעל ההסתברות הגבוהה ביותר (מה שעלול להוביל ללולאות חזרתיות), ו-Beam Search שומר מספר מסלולים במקביל (יקר חישובית), שיטות מודרניות כמו Nucleus Sampling (Top-p) ו-Top-k מספקות את האיזון המושלם. הן מסננות את מרחב הטוקנים האפשריים בזמן אמת, ובכך חוסכות משאבי חישוב ומייצרות טקסט טבעי ומגוון יותר.
הנה דוגמה פשוטה לשימוש ב-vLLM להרצת Inference מהיר במיוחד עם הגדרות Sampling מתקדמות:
from vllm import LLM, SamplingParams
# אתחול המודל עם תמיכה מובנית ב-PagedAttention ו-KV cache אופטימלי
llm = LLM(model="facebook/opt-125m")
# הגדרת פרמטרי Sampling ליצירת טקסט איכותי ויעיל
sampling_params = SamplingParams(
temperature=0.7,
top_p=0.9,
max_tokens=100
)
prompts = ["The future of AI inference is"]
outputs = llm.generate(prompts, sampling_params)
for output in outputs:
print(f"Generated text: {output.outputs[0].text}")
הבנת האופטימיזציות האלו קריטית כאשר בונים מערכות AI מקומיות או מבוזרות. לדוגמה, בפודקאסט יצירת עוזר AI פרטי ב-Thunderbird נידונה החשיבות של הרצת מודלים מקומיים ביעילות על חומרת קצה מוגבלת. כמו כן, הדינמיקה בין מודלים פתוחים לסגורים, כפי שמתואר בפרק האגדה על מלחמות המודלים: פתוח vs סגור ב-2026, מושפעת ישירות מהיכולת של הקהילה להריץ מודלים פתוחים ביעילות מקומית באמצעות טכנולוגיות כמו llama.cpp ו-vLLM.
הצעד הבא שלך: כדי לחוות את עוצמת האופטימיזציה בעצמך, התקן את llama.cpp על המחשב האישי שלך. הורד מודל בפורמט GGUF (למשל Llama 3 בקוונטיזציה של Q4_K_M) והרד אותו דרך הטרמינל. שים לב להבדל במהירות ה-Inference (טוקנים לשנייה) בהשוואה להרצה של מודל לא מכווץ, וראה כיצד ה-KV cache המובנה שומר על ביצועים יציבים גם ככל שהצ'אט מתארך.