Auf ai.google.dev ansehen | In Google Colab ausführen | Quelle auf GitHub ansehen |
Übersicht
CodeGemma ist eine Variante von Gemma, die auf Programmieraufgaben zugeschnitten ist. Dieses Tutorial baut auf dem Keras CodeGemma-Schnellstart auf und zeigt Ihnen weitere Möglichkeiten, wie CodeGemma Ihre Programmieraufgaben unterstützen kann.
Einrichtung
Zugriff auf CodeGemma erhalten
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 erhalten Sie Zugriff auf Gemma.
- Wählen Sie eine Colab-Laufzeit mit ausreichenden Ressourcen zum Ausführen des Gemma 7B-Modells aus.
- 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.
Laufzeit auswählen
Zum Ausführen der CodeGemma 7B-Modelle benötigen Sie ein kostenpflichtiges Colab Pro-Abo, das eine Laufzeit mit A100-GPU bietet.
- Wählen Sie rechts oben im Colab-Fenster ▾ aus (Zusätzliche Verbindungsoptionen).
- Wählen Sie Laufzeittyp ändern aus.
- Wählen Sie unter Hardwarebeschleuniger die Option A100 GPU aus.
API-Schlüssel konfigurieren
Um Gemma zu verwenden, müssen Sie Ihren Kaggle-Nutzernamen und einen Kaggle API-Schlüssel angeben.
Um einen Kaggle-API-Schlüssel zu generieren, gehen Sie in Ihrem Kaggle-Nutzerprofil zum Tab Account (Konto) und wählen Sie Create New Token (Neues Token erstellen) aus. Dadurch wird der Download einer kaggle.json
-Datei mit Ihren API-Anmeldedaten ausgelöst.
Wählen Sie in Colab im linken Bereich Secrets (🚀) aus und fügen Sie Ihren Kaggle-Nutzernamen und Ihren Kaggle API-Schlüssel hinzu. Speichern Sie Ihren Nutzernamen unter dem Namen KAGGLE_USERNAME
und Ihren API-Schlüssel unter dem Namen KAGGLE_KEY
.
Umgebungsvariablen festlegen
Legen Sie Umgebungsvariablen für KAGGLE_USERNAME
und KAGGLE_KEY
fest.
import os
from google.colab import userdata
os.environ["KAGGLE_USERNAME"] = userdata.get('KAGGLE_USERNAME')
os.environ["KAGGLE_KEY"] = userdata.get('KAGGLE_KEY')
Abhängigkeiten installieren
pip install -q -U keras-nlp
Backend auswählen
Keras ist eine Deep-Learning-API mit mehreren Frameworks, die auf einfache und nutzerfreundliche Weise entwickelt wurde. Mit Keras 3 können Sie Workflows auf einem von drei Back-Ends ausführen: TensorFlow, JAX oder PyTorch.
Konfigurieren Sie für diese Anleitung das Back-End für JAX.
os.environ["KERAS_BACKEND"] = "jax" # Or "tensorflow" or "torch".
Pakete importieren
Importieren Sie Keras und KerasNLP.
import keras_nlp
import keras
# Run at half precision.
keras.config.set_floatx("bfloat16")
CodeGemma 7B-Modellbeispiele
Dieser Abschnitt enthält Beispiele für die Verwendung des vortrainierten 7B-CodeGemma-Modells zur Unterstützung bei Programmieraufgaben.
Modell laden
KerasNLP bietet Implementierungen aller drei CodeGemma-Varianten (2B und 7B vortrainiert (PT) und 7B Instruction-tuned (IT)) mithilfe von GemmaCausalLM
, einem End-to-End-Gemma-Modell für kausale Sprachmodelle. Ein kausales Sprachmodell sagt das nächste Token basierend auf vorherigen Tokens voraus.
In diesem Beispiel wird das Modell code_gemma_7b_en
mit der Methode from_preset
geladen.
gemma_lm_7b = keras_nlp.models.GemmaCausalLM.from_preset("code_gemma_7b_en")
Downloading from https://www.kaggle.com/api/v1/models/keras/codegemma/keras/code_gemma_7b_en/1/download/config.json... 100%|██████████| 556/556 [00:00<00:00, 790kB/s] Downloading from https://www.kaggle.com/api/v1/models/keras/codegemma/keras/code_gemma_7b_en/1/download/model.weights.h5... 100%|██████████| 15.9G/15.9G [02:39<00:00, 107MB/s] Downloading from https://www.kaggle.com/api/v1/models/keras/codegemma/keras/code_gemma_7b_en/1/download/tokenizer.json... 100%|██████████| 401/401 [00:00<00:00, 587kB/s] Downloading from https://www.kaggle.com/api/v1/models/keras/codegemma/keras/code_gemma_7b_en/1/download/assets/tokenizer/vocabulary.spm... 100%|██████████| 4.04M/4.04M [00:00<00:00, 16.4MB/s]
gemma_lm_7b.summary()
Die Methode from_preset
instanziiert das Modell aus einer voreingestellten Architektur und Gewichtungen.
Codevervollständigung mit mehrzeiligem FIM
Die PT CodeGemma-Modelle werden mit Aufgaben zur Code-Füllung trainiert. Dieser Abschnitt zeigt Beispiele, in denen die mehrzeilige FIM-Funktion von CodeGemma verwendet wird, um Code an der angegebenen Cursorposition basierend auf dem umgebenden Kontext automatisch auszufüllen.
Definieren Sie zunächst Konstanten und eine Hilfsfunktion für die Prompt-Formatierung.
# Formatting control tokens to specify cursor location
BEFORE_CURSOR = "<|fim_prefix|>"
AFTER_CURSOR = "<|fim_suffix|>"
AT_CURSOR = "<|fim_middle|>"
FILE_SEPARATOR = "<|file_separator|>"
# Define model stop tokens
END_TOKEN = gemma_lm_7b.preprocessor.tokenizer.end_token
stop_tokens = (BEFORE_CURSOR, AFTER_CURSOR, AT_CURSOR, FILE_SEPARATOR, END_TOKEN)
stop_token_ids = tuple(gemma_lm_7b.preprocessor.tokenizer.token_to_id(x) for x in stop_tokens)
def format_completion_prompt(before, after):
return f"{BEFORE_CURSOR}{before}{AFTER_CURSOR}{after}{AT_CURSOR}"
Beispiel 1 – Fehlende Bedingung einfügen
Der Beispielcode unten zum Generieren der Fibonacci-Sequenz wird in folgenden Fällen nicht korrekt ausgeführt:n=1
:
def fibonacci(n: int) -> int:
if n == 0:
return 0
# The cursor is right before the e in the following line
else:
return fibonacci(n - 1) + fibonacci(n - 2)
Wenn sich der Cursor am Anfang der Zeile 4 befindet (wobei sich die else
-Klausel befindet), sieht der Inhalt vor und nach dem Cursor so aus:
before = """def fibonacci(n: int) -> int:\n if n == 0:\n return 0\n""" # Mind the spaces!
after = """\n else:\n return fibonacci(n - 1) + fibonacci(n-2)\n"""
prompt = format_completion_prompt(before, after)
print(prompt)
<|fim_prefix|>def fibonacci(n: int) -> int: if n == 0: return 0 <|fim_suffix|> else: return fibonacci(n - 1) + fibonacci(n-2) <|fim_middle|>
Führen Sie die Aufforderung aus.
print(gemma_lm_7b.generate(prompt, stop_token_ids=stop_token_ids, max_length=128))
<|fim_prefix|>def fibonacci(n: int) -> int: if n == 0: return 0 <|fim_suffix|> else: return fibonacci(n - 1) + fibonacci(n-2) <|fim_middle|>elif n == 1: return 1<|file_separator|>
Das Modell fügt die korrekte elif
-Konfiguration für n=1
an der Position des Cursors ein.
Beispiel 2: Vollständiger DFS-Durchlaufalgorithmus
Code zur automatischen Vervollständigung für einen DFS-Strukturdurchlaufalgorithmus (Deep-First Search).
before = """void dfs(node* root) {
if (root->left) {
dfs(root->left);
}"""
after = """\nprintf("%d", root->value);
}"""
prompt = format_completion_prompt(before, after)
print(prompt)
<|fim_prefix|>void dfs(node* root) { if (root->left) { dfs(root->left); }<|fim_suffix|> printf("%d", root->value); }<|fim_middle|>
Führen Sie die Aufforderung aus.
print(gemma_lm_7b.generate(prompt, stop_token_ids=stop_token_ids, max_length=128))
<|fim_prefix|>void dfs(node* root) { if (root->left) { dfs(root->left); }<|fim_suffix|> printf("%d", root->value); }<|fim_middle|> if (root->right) { dfs(root->right); }<|file_separator|>
Codegenerierung
CodeGemma 7B PT kann nicht nur Code einfügen, sondern auch mit Natural Language-Korpus trainiert werden. Damit können Sie das Modell auffordern, Code zu generieren.
generation_prompt= """Write a rust function to identify non-prime numbers.
Examples:
>>> is_not_prime(2)
False
>>> is_not_prime(10)
True
pub fn is_not_prime(n: i32) -> bool {"""
print(gemma_lm_7b.generate(generation_prompt, max_length=500))
Write a rust function to identify non-prime numbers. Examples: >>> is_not_prime(2) False >>> is_not_prime(10) True pub fn is_not_prime(n: i32) -> bool { if n <= 1 { return true; } for i in 2..n { if n % i == 0 { return true; } } false }
7 Mrd. IT-Modellbeispiele
In diesem Abschnitt wird das CodeGemma 7B Instruction-Tuned-Modell für fortgeschrittene Programmieraufgaben verwendet. Das IT-Modell von CodeGemma 7B wurde vom CodeGemma 7B PT-Modell durch überwachte Abstimmung des Codes und bestärkendes Lernen mit menschlichem Feedback abgeleitet. In diesem Abschnitt finden Sie Beispiele für die Verwendung dieses Modells für die offene Generierung.
IT-Modell laden
Laden Sie das Modell code_gemma_instruct_7b_en
mit der Methode from_preset
.
gemma_lm_7b_it = keras_nlp.models.GemmaCausalLM.from_preset("code_gemma_instruct_7b_en")
gemma_lm_7b_it.summary()
Downloading from https://www.kaggle.com/api/v1/models/keras/codegemma/keras/code_gemma_instruct_7b_en/1/download/config.json... 100%|██████████| 556/556 [00:00<00:00, 754kB/s] Downloading from https://www.kaggle.com/api/v1/models/keras/codegemma/keras/code_gemma_instruct_7b_en/1/download/model.weights.h5... 100%|██████████| 15.9G/15.9G [03:18<00:00, 86.2MB/s] Downloading from https://www.kaggle.com/api/v1/models/keras/codegemma/keras/code_gemma_instruct_7b_en/1/download/tokenizer.json... 100%|██████████| 401/401 [00:00<00:00, 593kB/s] Downloading from https://www.kaggle.com/api/v1/models/keras/codegemma/keras/code_gemma_instruct_7b_en/1/download/assets/tokenizer/vocabulary.spm... 100%|██████████| 4.04M/4.04M [00:00<00:00, 16.8MB/s]
IT-Modelle werden mit einem bestimmten Formatierer trainiert, der alle Beispiele zur Feinabstimmung von Anweisungen mit zusätzlichen Informationen versieht, um Rollen anzugeben und Wendungen in einer Unterhaltung abzugrenzen.
Definieren Sie zunächst Konstanten und eine Hilfsfunktion für die Prompt-Formatierung.
# Formatting control tokens for instruction tuning
START_OF_TURN_USER = "<start_of_turn>user"
END_OF_TURN = "<end_of_turn>"
START_OF_TURN_MODEL = "<start_of_turn>model"
# Formatting helper function
def format_instruction_prompt(context):
return f"{START_OF_TURN_USER}\n{context}{END_OF_TURN}\n{START_OF_TURN_MODEL}\n"
Codeübersetzung
context1 = """
You are an experienced C and Python programmer. Convert the following Python code into C.
```python
def factorial(n):
result = 1
for i in range(2, n + 1):
result *= i
return result
```\n"""
Formatieren Sie den Prompt.
prompt1 = format_instruction_prompt(context1)
print(prompt1)
<start_of_turn>user You are an experienced C and Python programmer. Convert the following Python code into C. ```python def factorial(n): result = 1 for i in range(2, n + 1): result *= i return result ``` <end_of_turn> <start_of_turn>model
Führen Sie die Aufforderung aus.
print(gemma_lm_7b_it.generate(prompt1, max_length=500))
<start_of_turn>user You are an experienced C and Python programmer. Convert the following Python code into C. ```python def factorial(n): result = 1 for i in range(2, n + 1): result *= i return result ``` <end_of_turn> <start_of_turn>model Here is the C code equivalent of the Python code: ```c int factorial(int n) { int result = 1; for (int i = 2; i <= n; i++) { result *= i; } return result; } ``` Here is a breakdown of the changes: * The function is declared with the `int` return type, as in Python. * The `for` loop is converted to a `for` loop with an `int` variable `i` initialized to 2 and incremented by 1 in each iteration. * The `range` function is replaced with a simple loop that iterates from 2 to `n` (inclusive). * The `result *= i` statement is used to multiply `result` by `i` in each iteration. * The `return` statement is used to return the final value of `result`.
Erkennung von Code-Sicherheitslücken
context2 = """
You are an experienced C++ programmer hunting for vulnerable code. Is the following code vulnerable? Explain your reasoning.
```cpp
int i;
unsigned int numWidgets;
Widget **WidgetList;
numWidgets = GetUntrustedSizeValue();
if ((numWidgets == 0) || (numWidgets > MAX_NUM_WIDGETS)) {
ExitError("Incorrect number of widgets requested!");
}
WidgetList = (Widget **) malloc(numWidgets * sizeof(Widget *));
printf("WidgetList ptr=%p\n", WidgetList);
for (i = 0; i < numWidgets; i++) {
WidgetList[i] = InitializeWidget();
}
WidgetList[numWidgets] = NULL;
showWidgets(WidgetList);
```\n"""
Formatieren Sie den Prompt.
prompt2 = format_instruction_prompt(context2)
print(prompt2)
<start_of_turn>user You are an experienced C++ programmer hunting for vulnerable code. Is the following code vulnerable? Explain your reasoning. ```cpp int i; unsigned int numWidgets; Widget **WidgetList; numWidgets = GetUntrustedSizeValue(); if ((numWidgets == 0) || (numWidgets > MAX_NUM_WIDGETS)) { ExitError("Incorrect number of widgets requested!"); } WidgetList = (Widget **) malloc(numWidgets * sizeof(Widget *)); printf("WidgetList ptr=%p ", WidgetList); for (i = 0; i < numWidgets; i++) { WidgetList[i] = InitializeWidget(); } WidgetList[numWidgets] = NULL; showWidgets(WidgetList); ``` <end_of_turn> <start_of_turn>model
print(gemma_lm_7b_it.generate(prompt2, max_length=1000))
<start_of_turn>user You are an experienced C++ programmer hunting for vulnerable code. Is the following code vulnerable? Explain your reasoning. ```cpp int i; unsigned int numWidgets; Widget **WidgetList; numWidgets = GetUntrustedSizeValue(); if ((numWidgets == 0) || (numWidgets > MAX_NUM_WIDGETS)) { ExitError("Incorrect number of widgets requested!"); } WidgetList = (Widget **) malloc(numWidgets * sizeof(Widget *)); printf("WidgetList ptr=%p ", WidgetList); for (i = 0; i < numWidgets; i++) { WidgetList[i] = InitializeWidget(); } WidgetList[numWidgets] = NULL; showWidgets(WidgetList); ``` <end_of_turn> <start_of_turn>model Yes, the code is vulnerable to a memory access error. **Reasoning:** * The code allocates memory for `WidgetList` using `malloc` based on the value of `numWidgets`. * However, the loop iterates from `0` to `numWidgets`, which is one element beyond the allocated memory. * This means that accessing `WidgetList[numWidgets]` will result in a memory access error, as it is outside the bounds of the allocated memory. **Example of Memory Access Error:** When `numWidgets` is 5, the code allocates memory for `WidgetList` as follows: ``` WidgetList = (Widget **) malloc(5 * sizeof(Widget *)); ``` The loop iterates from 0 to 4, accessing the following elements: * `WidgetList[0]` * `WidgetList[1]` * `WidgetList[2]` * `WidgetList[3]` * `WidgetList[4]` However, the code then attempts to access `WidgetList[5]`, which is outside the allocated memory range. This will result in a memory access error. **Solution:** To resolve this vulnerability, the loop should be modified to iterate from 0 to `numWidgets - 1`: ```cpp for (i = 0; i < numWidgets - 1; i++) { WidgetList[i] = InitializeWidget(); } ``` This ensures that the loop does not access elements beyond the allocated memory range.
Das Modell erkennt eine potenzielle Sicherheitslücke im Code und bietet Codeänderungen zur Behebung an.
Zusammenfassung
In dieser Anleitung wurden Sie durch die Verwendung von CodeGemma für eine Vielzahl von Programmieraufgaben geführt. Weitere Informationen zu CodeGemma:
- Die technischen Daten der CodeGemma-Modelle finden Sie auf der CodeGemma-Modellkarte.
- Weitere Informationen zur Verwendung von CodeGemma in VertexAI
- Kurzanleitung zu Keras CodeGemma