![]() |
![]() |
|
![]() |
Large Language Models (LLMs) wie Gemma liefern besonders informative Antworten und sind daher ideal für die Entwicklung von virtuellen Assistenten und Chatbots.
LLMs sind üblicherweise zustandslos, was bedeutet, dass ihnen ein inhärenter Speicher zum Speichern vergangener Unterhaltungen fehlt. Jede Aufforderung oder Frage wird unabhängig und ohne Berücksichtigung vorheriger Interaktionen verarbeitet. Ein entscheidender Aspekt eines natürlichen Gesprächs ist jedoch die Fähigkeit, den Kontext aus früheren Interaktionen zu bewahren. Um diese Einschränkung zu überwinden und LLMs zu ermöglichen, den Unterhaltungskontext aufrechtzuerhalten, müssen sie in jedem neuen Prompt, der dem LLM präsentiert wird, explizit relevante Informationen wie den Unterhaltungsverlauf (oder entsprechende Teile) erhalten.
In dieser Anleitung erfahren Sie, wie Sie einen Chatbot mit der auf Anweisungen abgestimmten Modellvariante von Gemma entwickeln.
Einrichtung
Gemma-Einrichtung
Um diese Anleitung abzuschließen, müssen Sie zuerst die Schritte unter Gemma-Einrichtung ausführen. In der Anleitung zur Einrichtung von Gemma erfahren Sie, wie Sie Folgendes tun können:
- Auf kaggle.com erhältst du Zugriff auf Gemma.
- Colab-Laufzeit mit ausreichenden Ressourcen zum Ausführen auswählen das Modell Gemma 2B.
- Generieren und konfigurieren Sie einen Kaggle-Nutzernamen und einen API-Schlüssel.
Nachdem Sie die Gemma-Einrichtung abgeschlossen haben, fahren Sie mit dem nächsten Abschnitt fort. Dort legen Sie Umgebungsvariablen für Ihre Colab-Umgebung fest.
Umgebungsvariablen festlegen
Legen Sie Umgebungsvariablen für KAGGLE_USERNAME
und KAGGLE_KEY
fest.
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')
Abhängigkeiten installieren
Installieren Sie Keras und 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
Backend auswählen
Keras ist eine Deep-Learning-API auf hoher Ebene mit mehreren Frameworks, die auf einfache und nutzerfreundliche Weise entwickelt wurde. Mit Keras 3 können Sie das Back-End auswählen: TensorFlow, JAX oder PyTorch. Alle drei funktionieren in dieser Anleitung.
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"
Pakete importieren
Importieren Sie Keras und KerasNLP.
import keras
import keras_nlp
# for reproducibility
keras.utils.set_random_seed(42)
Modell instanziieren
KerasNLP bietet Implementierungen vieler beliebter Modellarchitekturen. In dieser Anleitung instanziieren Sie das Modell mit GemmaCausalLM
, einem End-to-End-Gemma-Modell für kausale Language Models. Ein kausales Sprachmodell sagt das nächste Token basierend auf vorherigen Tokens voraus.
Instanziieren Sie das Modell mit der Methode from_preset
:
gemma_lm = keras_nlp.models.GemmaCausalLM.from_preset("gemma2_instruct_2b_en")
Die Funktion GemmaCausalLM.from_preset()
instanziiert das Modell aus einer voreingestellten Architektur und Gewichtungen. Im Code oben gibt der String "gemma2_instruct_2b_en"
die Voreinstellung für das Modell Gemma 2 2B mit 2 Milliarden Parametern an. Gemma-Modelle mit den Parametern 7B, 9B und 27B sind ebenfalls verfügbar. Sie finden die Codestrings für Gemma-Modelle in der Liste der Modellvarianten auf Kaggle.
Verwenden Sie die Methode summary
, um weitere Informationen zum Modell abzurufen:
gemma_lm.summary()
Wie Sie der Zusammenfassung entnehmen können, hat das Modell 2,6 Milliarden trainierbare Parameter.
Formatierungshilfefunktionen definieren
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))
Chatbot erstellen
Das auf die Gemma-Anweisung abgestimmte Modell „gemma2_instruct_2b_en
“ wurde optimiert, um die folgenden Rundentokens zu verstehen:
<start_of_turn>user\n ... <end_of_turn>\n
<start_of_turn>model\n ... <end_of_turn>\n
In dieser Anleitung werden diese Tokens verwendet, um den Chatbot zu erstellen. Weitere Informationen zu Gemma-Kontrolltokens finden Sie unter Formatierungs- und Systemanleitung.
Chatassistent zum Verwalten des Unterhaltungsstatus erstellen
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)
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=2048)
result = response.replace(prompt, "") # Extract only the new response
self.add_to_history_as_model(result)
return result
Mit dem Modell chatten
Chatten Sie mit dem Modell.
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))
🙋♂️
Beschreiben Sie mir in wenigen Worten, wie man alle Primzahlen bis 1.000 berechnet.🤖
Sieve von Eratosthenes.
Setzen Sie die Unterhaltung fort.
message = "Now in Python! No numpy, please!"
display_chat(message, chat.send_message(message))
🙋♂️
Jetzt in Python! Kein Schnickschnack, bitte!🤖
def sieve_of_eratosthenes(n): """Returns a list of prime numbers up to n.""" primes = [True] * (n + 1) primes[0] = primes[1] = False for i in range(2, int(n**0.5) + 1): if primes[i]: for j in range(i * i, n + 1, i): primes[j] = False return [i for i, is_prime in enumerate(primes) if is_prime] primes = sieve_of_eratosthenes(1000) print(primes)
Erklärung:
Initialisierung:
primes = [True] * (n + 1)
: Erstellt eine Listeprimes
mit booleschen Werten, wobei zuerst davon ausgegangen wird, dass alle Zahlen Primzahlen sind.primes[0] = primes[1] = False
: Legt 0 und 1 als „nicht für Prime“ fest.Iteration:
for i in range(2, int(n**0.5) + 1):
: Iteriert von 2 zur Quadratwurzel ausn
. Wir müssen nur die Quadratwurzel prüfen, da jede zusammengesetzte Zahl einen Primfaktor haben muss, der kleiner oder gleich ihrer Quadratwurzel ist.if primes[i]:
: Wenni
als Prime gekennzeichnet ist: <ph type="x-smartling-placeholder"></ph>
for j in range(i * i, n + 1, i):
: Kennzeichnet alle Vielfachen voni
als nicht Prime.Ergebnis:
return [i for i, is_prime in enumerate(primes) if is_prime]
: Erstellt eine Liste von Indexen, bei denenprimes[i]
„True“ ist und die Primzahlen darstellt.Wenn du irgendetwas genauer erklären möchtest, kannst du dich jederzeit gern wieder an mich wenden.
message = "Thank you, it works! Can you explain the code in French?"
display_chat(message, chat.send_message(message))
🙋♂️
Vielen Dank, es funktioniert! Kannst du den Code auf Französisch erklären?🤖
Bien sûr ! Voici une explication du code en français :
def sieve_of_eratosthenes(n): """Retourne une liste de nombres premiers jusqu'à n.""" primes = [True] * (n + 1) primes[0] = primes[1] = False for i in range(2, int(n**0.5) + 1): if primes[i]: for j in range(i * i, n + 1, i): primes[j] = False return [i for i, is_prime in enumerate(primes) if is_prime] primes = sieve_of_eratosthenes(1000) print(primes)
Erläuterung:
Initialisierung:
primes = [True] * (n + 1)
: Crée une listeprimes
de valeurs booléennes, initialement supposant que tous les nombres sont premiers.primes[0] = primes[1] = False
: Définit 0 et 1 für Nicht-Premieren.Iterationen:
for i in range(2, int(n**0.5) + 1):
: Itère de 2 jusqu'à la racine carrée den
. Nous ne devons vérifier que jusqu'à la racine carrée car tout nombre composite doit avoir unfacteur premier inférieur ou égal à sa racine carrée.if primes[i]:
: Sii
est considéré comme premier: <ph type="x-smartling-placeholder"></ph>
for j in range(i * i, n + 1, i):
: Marquer tous les multiples dei
würdigen Nicht-Premieren.Ergebnis:
return [i for i, is_prime in enumerate(primes) if is_prime]
: Crée une liste des indices oùprimes[i]
est vrai, représentant les nombres premiers.N'hésitez pas à me demander si vous avez besoin d'une explication plus détaillée de quelque hat entschieden!
message = "Great! Now add those explanations as comments in the code."
display_chat(message, chat.send_message(message))
🙋♂️
Sehr gut! Fügen Sie diese Erklärungen jetzt als Kommentare in den Code ein.🤖
def sieve_of_eratosthenes(n): """Retourne une liste de nombres premiers jusqu'à n.""" # Initialise une liste de boolean avec True pour tous les nombres de 0 à n primes = [True] * (n + 1) # Définit 0 et 1 comme non-premiers primes[0] = primes[1] = False # Itère de 2 à la racine carrée de n for i in range(2, int(n**0.5) + 1): # Si i est considéré comme premier if primes[i]: # Itère sur tous les multiples de i for j in range(i * i, n + 1, i): # Définit les multiples de i comme non-premiers primes[j] = False # Retourne la liste des indices des nombres premiers return [i for i, is_prime in enumerate(primes) if is_prime] primes = sieve_of_eratosthenes(1000) print(primes)
Erläuterung:
- Initialisierung: <ph type="x-smartling-placeholder">
</ph>
primes = [True] * (n + 1)
: Crée une listeprimes
de valeurs booléennes, initialement supposant que tous les nombres sont premiers.primes[0] = primes[1] = False
: Définit 0 et 1 für Nicht-Premieren.- Iterationen: <ph type="x-smartling-placeholder">
</ph>
for i in range(2, int(n**0.5) + 1):
: Itère de 2 jusqu'à la racine carrée den
. Nous ne devons vérifier que jusqu'à la racine carrée car tout nombre composite doit avoir unfacteur premier inférieur ou égal à sa racine carrée.if primes[i]:
: Sii
est considéré comme premier: <ph type="x-smartling-placeholder"></ph>
for j in range(i * i, n + 1, i):
: Marquer tous les multiples dei
würdigen Nicht-Premieren.- Ergebnis: <ph type="x-smartling-placeholder">
</ph>
return [i for i, is_prime in enumerate(primes) if is_prime]
: Crée une liste des indices oùprimes[i]
est vrai, représentant les nombres premiers.
Testen Sie die generierte Antwort, indem Sie den generierten Code ausführen:
def sieve_of_eratosthenes(n):
"""Retourne une liste de nombres premiers jusqu'à n."""
# Initialise une liste de boolean avec True pour tous les nombres de 0 à n
primes = [True] * (n + 1)
# Définit 0 et 1 comme non-premiers
primes[0] = primes[1] = False
# Itère de 2 à la racine carrée de n
for i in range(2, int(n**0.5) + 1):
# Si i est considéré comme premier
if primes[i]:
# Itère sur tous les multiples de i
for j in range(i * i, n + 1, i):
# Définit les multiples de i comme non-premiers
primes[j] = False
# Retourne la liste des indices des nombres premiers
return [i for i, is_prime in enumerate(primes) if is_prime]
primes = sieve_of_eratosthenes(1000)
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]
Verwenden Sie die Methode get_history
, um zu sehen, wie der gesamte Kontext von der Klasse Chat
beibehalten wurde.
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 **Sieve of Eratosthenes.** <end_of_turn><start_of_turn>user Now in Python! No numpy, please!<end_of_turn> <start_of_turn>model ```python def sieve_of_eratosthenes(n): """Returns a list of prime numbers up to n.""" primes = [True] * (n + 1) primes[0] = primes[1] = False for i in range(2, int(n**0.5) + 1): if primes[i]: for j in range(i * i, n + 1, i): primes[j] = False return [i for i, is_prime in enumerate(primes) if is_prime] primes = sieve_of_eratosthenes(1000) print(primes) ``` **Explanation:** 1. **Initialization:** - `primes = [True] * (n + 1)`: Creates a list `primes` of boolean values, initially assuming all numbers are prime. - `primes[0] = primes[1] = False`: Sets 0 and 1 as non-prime. 2. **Iteration:** - `for i in range(2, int(n**0.5) + 1):`: Iterates from 2 to the square root of `n`. We only need to check up to the square root because any composite number must have a prime factor less than or equal to its square root. - `if primes[i]:`: If `i` is marked as prime: - `for j in range(i * i, n + 1, i):`: Marks all multiples of `i` as non-prime. 3. **Result:** - `return [i for i, is_prime in enumerate(primes) if is_prime]`: Creates a list of indices where `primes[i]` is True, representing the prime numbers. Let me know if you'd like a more detailed explanation of any part! <end_of_turn><start_of_turn>user Thank you, it works! Can you explain the code in French?<end_of_turn> <start_of_turn>model Bien sûr ! Voici une explication du code en français : ```python def sieve_of_eratosthenes(n): """Retourne une liste de nombres premiers jusqu'à n.""" primes = [True] * (n + 1) primes[0] = primes[1] = False for i in range(2, int(n**0.5) + 1): if primes[i]: for j in range(i * i, n + 1, i): primes[j] = False return [i for i, is_prime in enumerate(primes) if is_prime] primes = sieve_of_eratosthenes(1000) print(primes) ``` **Explication:** 1. **Initialisation:** - `primes = [True] * (n + 1)`: Crée une liste `primes` de valeurs booléennes, initialement supposant que tous les nombres sont premiers. - `primes[0] = primes[1] = False`: Définit 0 et 1 comme non-premiers. 2. **Itération:** - `for i in range(2, int(n**0.5) + 1):`: Itère de 2 jusqu'à la racine carrée de `n`. Nous ne devons vérifier que jusqu'à la racine carrée car tout nombre composite doit avoir un facteur premier inférieur ou égal à sa racine carrée. - `if primes[i]:`: Si `i` est considéré comme premier: - `for j in range(i * i, n + 1, i):`: Marquer tous les multiples de `i` comme non-premiers. 3. **Resultat:** - `return [i for i, is_prime in enumerate(primes) if is_prime]`: Crée une liste des indices où `primes[i]` est vrai, représentant les nombres premiers. N'hésitez pas à me demander si vous avez besoin d'une explication plus détaillée de quelque chose! <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 sieve_of_eratosthenes(n): """Retourne une liste de nombres premiers jusqu'à n.""" # Initialise une liste de boolean avec True pour tous les nombres de 0 à n primes = [True] * (n + 1) # Définit 0 et 1 comme non-premiers primes[0] = primes[1] = False # Itère de 2 à la racine carrée de n for i in range(2, int(n**0.5) + 1): # Si i est considéré comme premier if primes[i]: # Itère sur tous les multiples de i for j in range(i * i, n + 1, i): # Définit les multiples de i comme non-premiers primes[j] = False # Retourne la liste des indices des nombres premiers return [i for i, is_prime in enumerate(primes) if is_prime] primes = sieve_of_eratosthenes(1000) print(primes) ``` **Explication:** * **Initialisation:** * `primes = [True] * (n + 1)`: Crée une liste `primes` de valeurs booléennes, initialement supposant que tous les nombres sont premiers. * `primes[0] = primes[1] = False`: Définit 0 et 1 comme non-premiers. * **Itération:** * `for i in range(2, int(n**0.5) + 1):`: Itère de 2 jusqu'à la racine carrée de `n`. Nous ne devons vérifier que jusqu'à la racine carrée car tout nombre composite doit avoir un facteur premier inférieur ou égal à sa racine carrée. * `if primes[i]:`: Si `i` est considéré comme premier: * `for j in range(i * i, n + 1, i):`: Marquer tous les multiples de `i` comme non-premiers. * **Resultat:** * `return [i for i, is_prime in enumerate(primes) if is_prime]`: Crée une liste des indices où `primes[i]` est vrai, représentant les nombres premiers. <end_of_turn>
Zusammenfassung und weitere Informationen
In dieser Anleitung haben Sie erfahren, wie Sie mit Keras auf JAX mit dem abgestimmten Modell Gemma 2B Instruction chatten.
In diesen Leitfäden und Tutorials erfahren Sie mehr über Gemma: