CodeGemma - 谷歌官方釋出的編碼大語言模型

釋出於 2024 年 4 月 9 日
在 GitHub 上更新

CodeGemma 是 Gemma 的一個開放版本家族,專門用於程式碼任務。我們很高興能與谷歌合作釋出該模型,並盡我們所能讓它更容易被大家使用。🤗

CodeGemma 有三個版本

  • 一個 2B 基礎模型,專門用於程式碼填充和開放式生成。
  • 一個 7B 基礎模型,同時使用程式碼填充和自然語言進行訓練。
  • 一個 7B 指令模型,使用者可以與其進行程式碼相關的對話。

我們與谷歌合作,確保 CodeGemma 能最佳地整合到 Hugging Face 生態系統中。你可以在 Hub 上找到這三個可立即使用的開放模型。在本次釋出的功能和整合中,我們有:

  • Hub 上的模型,附有模型卡和許可證。我們提供了適用於 transformers 庫的版本、用於谷歌原始程式碼庫的 checkpoints,以及社群可以量化的全精度 GGUF 檔案。
  • Transformers 整合
  • 與 Google Cloud 整合
  • 與推理端點整合
  • 程式碼基準測試

目錄

什麼是 CodeGemma?

CodeGemma 是谷歌推出的一系列專用於程式碼的大語言模型 (LLM),基於預訓練的 2B 和 7B Gemma checkpoints。CodeGemma 在此基礎上額外使用了 5000 億個主要為英語、數學和程式碼的 tokens 進行訓練,以提升其邏輯和數學推理能力,適用於程式碼補全和生成任務。

CodeGemma 2B 專門針對程式碼填充進行訓練,旨在實現快速的程式碼補全和生成,尤其適用於對延遲和/或隱私要求較高的場景。CodeGemma 7B 的訓練資料包含程式碼填充資料 (80%) 和自然語言。它可用於程式碼補全,以及程式碼和語言的理解與生成。CodeGemma 7B Instruct 是在 CodeGemma 7B 的基礎上為遵循指令而微調的。它專為對話式應用而設計,尤其是在程式碼、程式設計或數學推理等領域。所有模型的上下文視窗大小與其前身一樣,均為 8K tokens。

The CodeGemma family

此圖來自原始報告

評估結果

在 HumanEval 這個評估 Python 程式碼模型的熱門基準測試中,CodeGemma-7B 的效能優於同等規模的 7B 模型,僅次於 DeepSeek-Coder-7B。在 MultiPL-E(HumanEval 的多語言翻譯版本)對 Java、JavaScript 和 C++ 等其他程式語言的評估中,情況也是如此。根據技術報告,該模型在 7B 模型中,GSM8K 上的表現最佳。指令微調版本 CodeGemma-7B-it 在 HumanEval 和 MBPP 上對最主流的程式語言效能都有所提升 (參見論文表 5)。更多細節,您可以檢視 BigCode 排行榜 或下文的一些指標。

模型 預訓練大小 [token] Python JavaScript
10B+ 模型
StarCoder 2 15B 4,000B+ 44.15 44.24
Code Llama 13B 2,500B 35.07 38.26
7B 模型
DeepSeek Coder 7B 2,000B 45.83 45.9
CodeGemma 7B 額外 500B 的訓練 40.13 43.06
Code Llama 7B 2,500B 29.98 31.8
StarCoder 2 7B 3,500B+ 34.09 35.35
StarCoderBase 7B 3,000B+ 28.37 27.35
<3B 模型
CodeGemma 2B 額外 500B 的訓練 27.28 29.94
Stable Code 3B 1,300B 30.72 28.75
StarCoder 2 3B 3,000B+ 31.44 35.37
模型 預訓練大小 [token] Python JavaScript
10B+ 模型
Code Llama 13B 2,620B 50.6 40.92
Code Llama 13B 2,620B 42.89 40.66
7B 模型
CodeGemma 7B 500B 52.74 47.71
Code Llama 7B 2,620B 40.48 36.34
Code Llama 7B 2,620B 25.65 33.11

以下是原始報告中按語言分類的表格。

CodeGemma quality across languages

提示詞格式

CodeGemma 2B 和 CodeGemma 7B 使用填充(程式碼、註釋、文件字串、匯入語句)來完成程式碼。CodeGemma 是透過“中間填充”(fill-in-the-middle, FIM) 目標進行訓練的,你需要提供一個字首和一個字尾作為補全的上下文。以下 tokens 用於分隔輸入的不同部分:

  • <|fim_prefix|> 位於我們想要補全的程式碼之前的上下文中。
  • <|fim_suffix|> 位於字尾之前。你必須將此 token 準確地放在編輯器中游標所在的位置,因為這是模型將進行程式碼補全的地方。
  • <|fim_middle|> 是提示模型開始生成的提示符。

除此之外,還有一個 <|file_separator|>,用於提供多檔案上下文。我們將在 使用 Transformers 部分展示使用示例。

CodeGemma 7B Instruct 使用與基礎 Gemma Instruction-tuned 版本相同的提示格式,遵循以下對話結構:

<bos><start_of_turn>user
knock knock<end_of_turn>
<start_of_turn>model
who is there<end_of_turn>
<start_of_turn>user
LaMDA<end_of_turn>
<start_of_turn>model
LaMDA who?<end_of_turn>

與 Gemma 一樣,重現此格式最簡單的方法是使用 transformers 中提供的聊天模板。

使用 CodeGemma

演示

你可以輕鬆地在這個 Space 中或在下方嵌入的聊天機器人中試用 CodeGemma 模型(70 億引數!)

這個 playground 在底層使用了 Transformers 實現。你也可以複製這個 Space 供自己使用——它是自包含的,因此你可以檢視原始碼並根據需要進行修改!

使用 Transformers

透過 Transformers 4.39 版本,你可以使用 CodeGemma 並利用 Hugging Face 生態系統中的所有工具,例如:

  • 訓練和推理指令碼以及示例
  • 安全檔案格式 (safetensors)
  • 與 bitsandbytes (4 位量化)、PEFT (引數高效微調) 和 Flash Attention 2 等工具的整合
  • 用於模型生成執行的實用程式和輔助函式
  • 匯出模型以進行部署的機制

與 Gemma 模型一樣,CodeGemma 與 torch.compile() 相容,可以顯著提升推理速度。

彩蛋:我們為你準備了一個 Colab notebook,只需一鍵即可試用該模型,點選這裡

要使用 transformers 執行 CodeGemma,請確保使用最新的版本。

pip install --upgrade transformers

以下程式碼片段展示瞭如何使用 codegemma-2b 透過 transformers 進行程式碼補全。使用 float16 精度大約需要 6 GB 的 RAM,非常適合消費級 GPU 和裝置端應用。

from transformers import GemmaTokenizer, AutoModelForCausalLM
import torch

model_id = "google/codegemma-2b"
tokenizer = GemmaTokenizer.from_pretrained(model_id)
model = AutoModelForCausalLM.from_pretrained(
    model_id,
    torch_dtype=torch.float16
).to("cuda:0")

prompt = '''\
<|fim_prefix|>import datetime
def calculate_age(birth_year):
    """Calculates a person's age based on their birth year."""
    current_year = datetime.date.today().year
    <|fim_suffix|>
    return age<|fim_middle|>\
'''

inputs = tokenizer(prompt, return_tensors="pt").to(model.device)
prompt_len = inputs["input_ids"].shape[-1]
outputs = model.generate(**inputs, max_new_tokens=100)
print(tokenizer.decode(outputs[0][prompt_len:]))

請注意,<|fim_suffix|> token 出現在編輯器中游標應放置的位置,標記了生成的位置。<|fim_prefix|> 提供了游標之前的上下文,而直到 <|fim_middle|> 之前的部分是游標之後的額外上下文。如果游標位於檔案的開頭或結尾,這兩者之一可以為空。

上述程式碼可能返回類似以下內容:

age = current_year - birth_year<|file_separator|>test_calculate_age.py
<|fim_suffix|>
    assert calculate_age(1990) == 33
    assert calculate_age(1980) == 43
    assert calculate_age(1970) == 53
    assert calculate_age(1960) == 63
    assert calculate_age(1950) == 73

請注意在正確補全後還有額外的內容。對於 CodeGemma 7B 來說尤其如此,它更冗長,傾向於在補全後提供額外的程式碼或註釋。對於程式碼填充,我們必須忽略出現在 FIM tokens 或 EOS token 之後的所有內容。我們可以透過向 generate 函式提供一個終止符列表來提前停止生成,如下所示:

FIM_PREFIX = '<|fim_prefix|>'
FIM_SUFFIX = '<|fim_suffix|>'
FIM_MIDDLE = '<|fim_middle|>'
FIM_FILE_SEPARATOR = '<|file_separator|>'

terminators = tokenizer.convert_tokens_to_ids(
    [FIM_PREFIX, FIM_MIDDLE, FIM_SUFFIX, FIM_FILE_SEPARATOR]
)
terminators += [tokenizer.eos_token_id]

outputs = model.generate(
  **inputs,
  max_new_tokens=100,
  eos_token_id=terminators,
)

在這種情況下,一旦找到第一個分隔符,生成就會停止。

age = current_year - birth_year<|file_separator|>

關於精度的說明

原始的 CodeGemma checkpoints 是以 bfloat16 精度釋出的。如果你在載入模型時未指定 torch_dtype,PyTorch 會將其上轉換為 float32。轉換為 float16 使用完全沒有問題,並且在某些硬體上可能比 bfloat16 快得多。為了獲得最大精度,我們建議你使用 bfloat16 而不是 float32

你也可以自動量化模型,以 8 位或 4 位模式載入。4 位載入 CodeGemma 7B 大約需要 9 GB 記憶體執行,使其與許多消費級顯示卡以及 Google Colab 中的所有 GPU 相容。以下是如何以 4 位模式載入生成 pipeline:

pipeline = pipeline(
    "text-generation",
    model=model,
    model_kwargs={
        "torch_dtype": torch.float16,
        "quantization_config": {"load_in_4bit": True}
    },
)

與 Google Cloud 整合

你可以使用 Text Generation Inference 和 Transformers,透過 Vertex AI 或 Google Kubernetes Engine (GKE) 在 Google Cloud 上部署和訓練 Gemma。

要從 Hugging Face 部署 CodeGemma 模型,請訪問 模型頁面 並點選 Deploy -> Google Cloud。 這將帶你到 Google Cloud Console,在那裡你可以一鍵將 CodeGemma 部署到 Vertex AI 或 GKE,由 Text Generation Inference 提供支援。

你也可以直接透過 Vertex AI Model Garden 訪問 CodeGemma。

GCP Integration

與 Inference Endpoints 整合

你可以將 CodeGemma 部署在 Hugging Face 的 Inference Endpoints 上,它使用 Text Generation Inference 作為後端。 Text Generation Inference 是 Hugging Face 開發的生產就緒型推理容器,可輕鬆部署大型語言模型。它具有連續批處理、token 流式傳輸、用於在多個 GPU 上進行快速推理的張量並行、生產就緒的日誌記錄和追蹤等功能,並根據 Apache 2 許可證分發。

要部署 CodeGemma 模型,請訪問 模型頁面 並點選 Deploy -> Inference Endpoints 小部件。你可以在之前的部落格文章中瞭解更多關於使用 Hugging Face Inference Endpoints 部署 LLM 的資訊。請注意,T4s 不支援 bfloat16 格式,因此你需要使用不同的 GPU 選項。

from huggingface_hub import InferenceClient

client = InferenceClient(model=IE_ENDPOINT)

prompt = """\
<|fim_prefix|>import <|fim_suffix|>

if __name__ == '__main__':
  sys.exit(0)<|fim_middle|>\
"""

client.text_generation(prompt=prompt)

其他資源

社群

註冊登入 發表評論

© . This site is unofficial and not affiliated with Hugging Face, Inc.