![]() |
![]() |
|
![]() |
מודלים גדולים של שפה (LLMs) כמו Gemma מצטיינים ביצירת תשובות אינפורמטיביות, ולכן הם אידיאליים לפיתוח עוזרים דיגיטליים וצ'אט בוטים וירטואליים.
באופן מקובל, מודלים מסוג LLM פועלים בצורה ללא שמירת מצב, כלומר אין להם זיכרון מובנה לשמירת שיחות קודמות. כל הנחיה או שאלה מעובדות בנפרד, בלי להתייחס לאינטראקציות קודמות. עם זאת, היבט קריטי בשיחה טבעית הוא היכולת לשמור על הקשר מאינטראקציות קודמות. כדי להתגבר על המגבלה הזו וכדי לאפשר ל-LLM לשמור על הקשר לשיחה, צריך לספק להם באופן מפורש מידע רלוונטי כמו היסטוריית השיחות (או חלקים רלוונטיים) בכל הנחיה חדשה שמוצגת ל-LLM.
במדריך הזה תלמדו איך לפתח צ'אט בוט באמצעות וריאנט של מודל Gemma שמכוונן לפי הוראות.
הגדרה
הגדרת Gemma
כדי להשלים את המדריך, צריך קודם לבצע את הוראות ההגדרה שמפורטות במאמר הגדרת Gemma. בהוראות ההגדרה של Gemma מוסבר איך לבצע את הפעולות הבאות:
- אפשר לקבל גישה ל-Gemma בכתובת kaggle.com.
- בוחרים זמן ריצה של Colab עם מספיק משאבים כדי להריץ את המודל Gemma 2B.
- יצירה והגדרה של שם משתמש ומפתח API ב-Kaggle.
אחרי שמשלימים את ההגדרה של Gemma, עוברים לקטע הבא, שבו מגדירים משתני סביבה לסביבת Colab.
הגדרה של משתני סביבה
הגדרה של משתני סביבה בשביל KAGGLE_USERNAME
ו-KAGGLE_KEY
.
import os
from google.colab import userdata
# Note: `userdata.get` is a Colab API. If you're not using Colab, set the env
# vars as appropriate for your system.
os.environ["KAGGLE_USERNAME"] = userdata.get('KAGGLE_USERNAME')
os.environ["KAGGLE_KEY"] = userdata.get('KAGGLE_KEY')
יחסי תלות בהתקנות
מתקינים את Keras ו-KerasNLP.
# Install Keras 3 last. See https://keras.io/getting_started/ for more details.
pip install -q tensorflow-cpu
pip install -q -U keras-nlp tensorflow-hub
pip install -q -U keras>=3
pip install -q -U tensorflow-text
בחירת קצה עורפי
Keras הוא ממשק API ללמידה עמוקה (Deras) ברמה גבוהה של כמה פריימים, שנועד לפשט וקלות שימוש. ב-Keras 3 אפשר לבחור את הקצה העורפי: TensorFlow, JAX או PyTorch. כל השלושה יתאימו למדריך הזה.
import os
# Select JAX as the backend
os.environ["KERAS_BACKEND"] = "jax"
# Pre-allocate 100% of TPU memory to minimize memory fragmentation
os.environ["XLA_PYTHON_CLIENT_MEM_FRACTION"] = "1.0"
ייבוא חבילות
לייבא את Keras ו-KerasNLP.
import keras
import keras_nlp
# for reproducibility
keras.utils.set_random_seed(42)
יצירת המודל
ב-KerasNLP יש הטמעות של ארכיטקטורות מודלים פופולריות. במדריך הזה תיצרו את המודל באמצעות GemmaCausalLM
, מודל Gemma מקצה לקצה לבניית מודל שפה סיבתי. מודל שפה סיבתי חוזה את האסימון הבא על סמך אסימונים קודמים.
יוצרים מופע של המודל באמצעות השיטה from_preset
:
gemma_lm = keras_nlp.models.GemmaCausalLM.from_preset("gemma_1.1_instruct_2b_en")
Attaching 'metadata.json' from model 'keras/gemma/keras/gemma_1.1_instruct_2b_en/3' to your Colab notebook... Attaching 'metadata.json' from model 'keras/gemma/keras/gemma_1.1_instruct_2b_en/3' to your Colab notebook... Attaching 'task.json' from model 'keras/gemma/keras/gemma_1.1_instruct_2b_en/3' to your Colab notebook... Attaching 'config.json' from model 'keras/gemma/keras/gemma_1.1_instruct_2b_en/3' to your Colab notebook... Attaching 'metadata.json' from model 'keras/gemma/keras/gemma_1.1_instruct_2b_en/3' to your Colab notebook... Attaching 'metadata.json' from model 'keras/gemma/keras/gemma_1.1_instruct_2b_en/3' to your Colab notebook... Attaching 'config.json' from model 'keras/gemma/keras/gemma_1.1_instruct_2b_en/3' to your Colab notebook... Attaching 'config.json' from model 'keras/gemma/keras/gemma_1.1_instruct_2b_en/3' to your Colab notebook... Attaching 'model.weights.h5' from model 'keras/gemma/keras/gemma_1.1_instruct_2b_en/3' to your Colab notebook... Attaching 'metadata.json' from model 'keras/gemma/keras/gemma_1.1_instruct_2b_en/3' to your Colab notebook... Attaching 'metadata.json' from model 'keras/gemma/keras/gemma_1.1_instruct_2b_en/3' to your Colab notebook... Attaching 'preprocessor.json' from model 'keras/gemma/keras/gemma_1.1_instruct_2b_en/3' to your Colab notebook... Attaching 'tokenizer.json' from model 'keras/gemma/keras/gemma_1.1_instruct_2b_en/3' to your Colab notebook... Attaching 'tokenizer.json' from model 'keras/gemma/keras/gemma_1.1_instruct_2b_en/3' to your Colab notebook... Attaching 'assets/tokenizer/vocabulary.spm' from model 'keras/gemma/keras/gemma_1.1_instruct_2b_en/3' to your Colab notebook...
הפונקציה GemmaCausalLM.from_preset()
יוצרת את המודל מארכיטקטורה ומשקולות מוגדרות מראש. בקוד שלמעלה, המחרוזת "gemma_1.1_instruct_2b_en"
מציינת את ההגדרה הקבועה מראש של מודל Gemma 2B עם 2 מיליארד פרמטרים. יש גם מודלים של Gemma עם פרמטרים של 7B, 9B ו-27B. מחרוזות הקוד של דגמים של Gemma מופיעים בכרטיסי המוצר של וריאציית המודל ב-Kaggle.
משתמשים בשיטה summary
כדי לקבל מידע נוסף על המודל:
gemma_lm.summary()
כמו שאפשר לראות בסיכום, למודל יש 2.5 מיליארד פרמטרים שניתן לאמן.
הגדרת פונקציות עזר לעיצוב
from IPython.display import Markdown
import textwrap
def display_chat(prompt, text):
formatted_prompt = "<font size='+1' color='brown'>🙋♂️<blockquote>" + prompt + "</blockquote></font>"
text = text.replace('•', ' *')
text = textwrap.indent(text, '> ', predicate=lambda _: True)
formatted_text = "<font size='+1' color='teal'>🤖\n\n" + text + "\n</font>"
return Markdown(formatted_prompt+formatted_text)
def to_markdown(text):
text = text.replace('•', ' *')
return Markdown(textwrap.indent(text, '> ', predicate=lambda _: True))
פיתוח הצ'אט בוט
המודל gemma_1.1_instruct_2b_en
שעבר כוונון לפי הוראה של Gemma עבר כוונון עדין כדי להבין את אסימוני הפנייה הבאים:
<start_of_turn>user\n ... <end_of_turn>\n
<start_of_turn>model\n ... <end_of_turn>\n
במדריך הזה נשתמש באסימונים האלה כדי לבנות את הצ'אט בוט. למידע נוסף על אסימוני בקרה של Gemma, אפשר לעיין בהוראות להגדרה ולמערכת.
יצירת עוזר דיגיטלי בצ'אט לניהול מצב השיחה
class ChatState():
"""
Manages the conversation history for a turn-based chatbot
Follows the turn-based conversation guidelines for the Gemma family of models
documented at https://ai.google.dev/gemma/docs/formatting
"""
__START_TURN_USER__ = "<start_of_turn>user\n"
__START_TURN_MODEL__ = "<start_of_turn>model\n"
__END_TURN__ = "<end_of_turn>\n"
def __init__(self, model, system=""):
"""
Initializes the chat state.
Args:
model: The language model to use for generating responses.
system: (Optional) System instructions or bot description.
"""
self.model = model
self.system = system
self.history = []
def add_to_history_as_user(self, message):
"""
Adds a user message to the history with start/end turn markers.
"""
self.history.append(self.__START_TURN_USER__ + message + self.__END_TURN__)
def add_to_history_as_model(self, message):
"""
Adds a model response to the history with start/end turn markers.
"""
self.history.append(self.__START_TURN_MODEL__ + message + self.__END_TURN__)
def get_history(self):
"""
Returns the entire chat history as a single string.
"""
return "".join([*self.history])
def get_full_prompt(self):
"""
Builds the prompt for the language model, including history and system description.
"""
prompt = self.get_history() + self.__START_TURN_MODEL__
if len(self.system)>0:
prompt = self.system + "\n" + prompt
return prompt
def send_message(self, message):
"""
Handles sending a user message and getting a model response.
Args:
message: The user's message.
Returns:
The model's response.
"""
self.add_to_history_as_user(message)
prompt = self.get_full_prompt()
response = self.model.generate(prompt, max_length=1024)
result = response.replace(prompt, "") # Extract only the new response
self.add_to_history_as_model(result)
return result
שיחה בצ'אט עם המודל
מתחילים להתכתב בצ'אט עם המודל.
chat = ChatState(gemma_lm)
message = "Tell me, in a few words, how to compute all prime numbers up to 1000?"
display_chat(message, chat.send_message(message))
🙋♂️
איך לחשב את כל המספרים הראשוניים עד 1000?🤖
ה-Seve of Eratosthenes היא שיטה נפוצה לחישוב כל המספרים הראשוניים עד לגבול נתון. היא כוללת סימון חזרתי של מכפלות של כל מספר ראשוני.
ממשיכים את השיחה.
message = "Now in Python! No numpy, please!"
display_chat(message, chat.send_message(message))
🙋♂️
עכשיו ב-Python! בלי מספרי,🤖
def prime(n): if n <= 1: return False for i in range(2, int(n**0.5) + 1): if n % i == 0: return False return True
message = "Thank you, it works! Can you explain the code in plain English?"
display_chat(message, chat.send_message(message))
🙋♂️
תודה, זה עובד! יש לך אפשרות להסביר את הקוד באנגלית פשוטה?🤖
הקוד שסופק מגדיר פונקציה
prime
שבודקת אם מספר נתון הוא ראשוני או לא.איך זה עובד:
הפונקציה לוקחת ארגומנט יחיד,
n
, שהוא המספר לבדיקה.קודם צריך לבדוק אם
n
קטן מ-1 או שווה לו. אחרת, המספר אינו ראשוני, ולכן הפונקציה מחזירהFalse
.לאחר מכן היא נכנסת ללולאה שחוזרת על עצמה באמצעות מספרים מ-2 עד לשורש הריבועי של
n
.עבור כל מספר
i
, הפונקציה בודקת אםn
מתחלקת באופן שווה ב-i
(כלומר,n % i == 0
).אם
n
מתחלק ב-i
, הפונקציה מחזירהFalse
כיn
לא יכול להיות ראשוני אם יש לו מחלק.אם הלולאה הושלמה מבלי למצוא מחלקים עבור
n
, הפונקציה מחזירהTrue
, שמציינת ש-n
הוא מספר ראשוני.שימוש לדוגמה:
>>> prime(2) True >>> prime(3) True >>> prime(4) False >>> prime(5) True
יתרונות הקוד הזה:
- זהו אלגוריתם פשוט ויעיל למציאת מספרים ראשוניים.
- משתמשים בה במגוון אפליקציות במדעי המחשב ובמתמטיקה.
message = "Great! Now add those explanations as comments in the code."
display_chat(message, chat.send_message(message))
🙋♂️
מעולה! עכשיו צריך להוסיף את ההסברים האלה כתגובות בקוד.🤖
def prime(n): """ Checks whether a given number is prime or not. Args: n: The number to check. Returns: True if n is prime, False otherwise. """ # Check if n is less than or equal to 1. if n <= 1: return False # Iterate through numbers from 2 to the square root of n. for i in range(2, int(n**0.5) + 1): # Check if n is divisible by i. if n % i == 0: return False # If the loop completes without finding any divisors for n, then n is prime. return True
כדי לבדוק את התגובה שנוצרה, מריצים את הקוד שנוצר:
def is_prime(n):
"""
Checks if a number is prime.
Args:
n: The number to check.
Returns:
True if n is prime, False otherwise.
"""
# If n is less than or equal to 1, it is not prime.
if n <= 1:
return False
# Iterate through all the numbers from 2 to the square root of n.
for i in range(2, int(n**0.5) + 1):
# If n is divisible by any of the numbers in the range from 2 to the square root of n, it is not prime.
if n % i == 0:
return False
# If no divisors are found, n is prime.
return True
# Initialize an empty list to store prime numbers.
primes = []
# Iterate through all the numbers from 2 to 1000.
for i in range(2, 1001):
# If the number is prime, add it to the list.
if is_prime(i):
primes.append(i)
# Print the prime numbers.
print(primes)
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997]
אפשר להשתמש בשיטה get_history
כדי לראות איך כל ההקשר נשמר על ידי המחלקה Chat
.
print(chat.get_history())
<start_of_turn>user Tell me, in a few words, how to compute all prime numbers up to 1000?<end_of_turn> <start_of_turn>model The Sieve of Eratosthenes is a widely used method to compute all prime numbers up to a given limit. It involves iteratively marking out multiples of each prime number.<end_of_turn> <start_of_turn>user Now in Python! No numpy, please!<end_of_turn> <start_of_turn>model ```python def prime(n): if n <= 1: return False for i in range(2, int(n**0.5) + 1): if n % i == 0: return False return True ```<end_of_turn> <start_of_turn>user Thank you, it works! Can you explain the code in plain English?<end_of_turn> <start_of_turn>model The provided code defines a function `prime` that checks whether a given number is prime or not. **How it works:** - The function takes a single argument, `n`, which is the number to check. - It first checks if `n` is less than or equal to 1. If it is, the number is not prime, so the function returns `False`. - It then enters a loop that iterates through numbers from 2 to the square root of `n`. - For each number `i`, it checks if `n` is divisible evenly by `i` (i.e., `n % i == 0`). - If `n` is divisible by `i`, the function returns `False` because `n` cannot be prime if it has a divisor. - If the loop completes without finding any divisors for `n`, the function returns `True`, indicating that `n` is a prime number. **Example Usage:** ```python >>> prime(2) True >>> prime(3) True >>> prime(4) False >>> prime(5) True ``` **Benefits of this Code:** - It is a simple and efficient algorithm for finding prime numbers. - It is widely used in various computer science and mathematical applications.<end_of_turn> <start_of_turn>user Great! Now add those explanations as comments in the code.<end_of_turn> <start_of_turn>model ```python def prime(n): """ Checks whether a given number is prime or not. Args: n: The number to check. Returns: True if n is prime, False otherwise. """ # Check if n is less than or equal to 1. if n <= 1: return False # Iterate through numbers from 2 to the square root of n. for i in range(2, int(n**0.5) + 1): # Check if n is divisible by i. if n % i == 0: return False # If the loop completes without finding any divisors for n, then n is prime. return True ```<end_of_turn>
סיכום וקריאה נוספת
במדריך הזה למדתם איך להתכתב בצ'אט עם המודל המכוונן לפי הנחיות Gemma 2B באמצעות Keras ב-JAX.
כדי לקבל מידע נוסף על Gemma, כדאי לעיין במדריכים ובמדריכים האלה: