Membangun chatbot dengan Gemma

Lihat di ai.google.dev Berjalan di Google Colab Buka di Vertex AI Lihat sumber di GitHub

Model Bahasa Besar (LLM) seperti Gemma unggul dalam menghasilkan respons yang informatif, sehingga ideal untuk membangun asisten virtual dan chatbot.

Secara konvensional, LLM beroperasi secara stateless, artinya LLM tidak memiliki memori inheren untuk menyimpan percakapan sebelumnya. Setiap perintah atau pertanyaan diproses secara terpisah, mengabaikan interaksi sebelumnya. Namun, aspek penting dari percakapan alami adalah kemampuan untuk mempertahankan konteks dari interaksi sebelumnya. Untuk mengatasi batasan ini dan memungkinkan LLM mempertahankan konteks percakapan, LLM harus diberi informasi yang relevan secara eksplisit seperti histori percakapan (atau bagian terkait) ke dalam setiap perintah baru yang disampaikan kepada LLM.

Tutorial ini menunjukkan cara mengembangkan chatbot menggunakan varian model yang disesuaikan dengan instruksi dari Gemma.

Penyiapan

Penyiapan Gemma

Untuk menyelesaikan tutorial ini, Anda harus menyelesaikan petunjuk penyiapan terlebih dahulu di penyiapan Gemma. Petunjuk penyiapan Gemma menunjukkan kepada Anda cara melakukan hal berikut:

  • Dapatkan akses ke Gemma di kaggle.com.
  • Pilih runtime Colab dengan resource yang memadai untuk menjalankan model Gemma 2B.
  • Membuat dan mengkonfigurasi nama pengguna dan kunci API Kaggle.

Setelah Anda menyelesaikan penyiapan Gemma, lanjutkan ke bagian berikutnya, untuk menetapkan variabel lingkungan untuk lingkungan Colab Anda.

Menetapkan variabel lingkungan

Menetapkan variabel lingkungan untuk KAGGLE_USERNAME dan 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')

Menginstal dependensi

Instal Keras dan 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

Pilih backend

Keras adalah API deep learning multi-framework tingkat tinggi yang dirancang untuk kesederhanaan dan kemudahan penggunaan. Keras 3 memungkinkan Anda memilih backend: TensorFlow, JAX, atau PyTorch. Ketiganya akan berfungsi untuk tutorial ini.

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"

Mengimpor paket

Impor Keras dan KerasNLP.

import keras
import keras_nlp

# for reproducibility
keras.utils.set_random_seed(42)

Membuat instance model

KerasNLP menyediakan implementasi dari banyak arsitektur model populer. Dalam tutorial ini, Anda akan membuat instance model menggunakan GemmaCausalLM, model Gemma menyeluruh untuk pemodelan bahasa kausal. Model bahasa kausal memprediksi token berikutnya berdasarkan token sebelumnya.

Buat instance model menggunakan metode 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...

Fungsi GemmaCausalLM.from_preset() membuat instance model dari bobot dan arsitektur preset. Dalam kode di atas, string "gemma_1.1_instruct_2b_en" menentukan preset model Gemma 2B dengan 2 miliar parameter. Model Gemma dengan parameter 7B, 9B, dan 27B juga tersedia. Anda dapat menemukan string kode untuk model Gemma dalam listingan Variasi Model di Kaggle.

Gunakan metode summary untuk mendapatkan info selengkapnya tentang model tersebut:

gemma_lm.summary()

Seperti yang dapat Anda lihat dari ringkasan, model ini memiliki 2,5 miliar parameter yang dapat dilatih.

Menentukan fungsi bantuan pemformatan

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))

Membangun chatbot

Model gemma_1.1_instruct_2b_en yang disesuaikan dengan instruksi Gemma telah disesuaikan untuk memahami token belokan berikut:

<start_of_turn>user\n  ... <end_of_turn>\n
<start_of_turn>model\n ... <end_of_turn>\n

Tutorial ini menggunakan token tersebut untuk membangun chatbot. Lihat Petunjuk format dan sistem untuk informasi selengkapnya tentang token kontrol Gemma.

Membuat chat helper untuk mengelola status percakapan

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 dengan model

Mulailah mengobrol dengan model.

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))

🙋‍♂️

Jelaskan dalam beberapa kata, bagaimana cara menghitung semua bilangan prima hingga 1000?
🤖

Sieve of Eratosthenes adalah metode yang banyak digunakan untuk menghitung semua bilangan prima hingga batas tertentu. Proses ini melibatkan penandaan kelipatan setiap bilangan prima secara iteratif.

Lanjutkan percakapan.

message = "Now in Python! No numpy, please!"
display_chat(message, chat.send_message(message))

🙋‍♂️

Sekarang di Python! Tolong jangan numpy!
🤖

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))

🙋‍♂️

Terima kasih, berhasil. Bisakah Anda menjelaskan kodenya dalam bahasa Inggris biasa?
🤖

Kode yang disediakan menentukan fungsi prime yang memeriksa apakah suatu bilangan merupakan bilangan prima atau bukan.

Cara kerjanya:

  • Fungsi ini mengambil satu argumen, n, yang merupakan angka yang akan diperiksa.

  • Pertama-tama, perintah ini akan memeriksa apakah n kurang dari atau sama dengan 1. Jika ya, angka tersebut bukan prima, sehingga fungsi akan menampilkan False.

  • Kode ini kemudian memasuki loop yang melakukan iterasi melalui angka dari 2 ke akar kuadrat n.

  • Untuk setiap angka i, fungsi ini memeriksa apakah n habis dibagi secara merata dengan i (yaitu, n % i == 0).

  • Jika n habis dibagi dengan i, fungsi tersebut akan menampilkan False karena n tidak boleh menjadi prima jika memiliki pembagi.

  • Jika loop selesai tanpa menemukan pembagi untuk n, fungsi ini akan menampilkan True, yang menunjukkan bahwa n adalah bilangan prima.

Contoh Penggunaan:

>>> prime(2)
True
>>> prime(3)
True
>>> prime(4)
False
>>> prime(5)
True

Manfaat Kode Ini:

  • Ini adalah algoritma yang sederhana dan efisien untuk menemukan bilangan prima.
  • Banyak digunakan dalam berbagai aplikasi ilmu komputer dan matematika.
message = "Great! Now add those explanations as comments in the code."
display_chat(message, chat.send_message(message))

🙋‍♂️

Bagus. Sekarang tambahkan penjelasan itu sebagai komentar di dalam kode.
🤖

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

Uji respons yang dihasilkan dengan menjalankan kode yang dihasilkan:

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]

Gunakan metode get_history untuk melihat bagaimana semua konteks dipertahankan oleh class 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>

Ringkasan dan bacaan lebih lanjut

Dalam tutorial ini, Anda telah mempelajari cara melakukan chat dengan Gemma 2B Instruction Tuned menggunakan Keras di JAX.

Lihat panduan dan tutorial ini untuk mempelajari lebih lanjut tentang Gemma: