跳到正文
原文
Hugging Face Blog·· 2024-04-09精选AI 评分62

Google 发布 CodeGemma 代码模型系列

CodeGemma - an official Google release for code LLMs

AI 导读

Google 发布开源代码模型系列 CodeGemma,基于预训练的 2B 和 7B Gemma checkpoint 进一步用 5000 亿 token 的英文、数学和代码数据训练,包含专注代码填充的 2B 基础模型、混合代码与自然语言的 7B 基础模型和面向对话的 7B Instruct 三个版本,上下文长度均为 8K。

推荐理由

原文给出三个规格的 CodeGemma 及其在 HumanEval 等基准上的对比数据和 FIM 提示词格式,便于评估其在代码补全场景的定位。

正文 · AI 翻译

CodeGemma 是 Gemma 的开源版本系列,专精于代码领域,我们非常高兴能与 Google 合作推出,使其尽可能易于获取。🤗

CodeGemma 提供三种版本:

  • 一个专注于填充和开放式生成的 2B 基础模型。
  • 一个同时接受代码填充和自然语言训练的 7B 基础模型。
  • 一个 7B 指令模型,用户可以与它进行关于代码的对话。

我们与 Google 合作,确保其能最佳地融入 HF Mirror 生态系统。您可以在 Hub 上找到这三个可直接使用的开放访问模型。在发布的功能和集成中,我们包括:

  • Hub 上的模型,附有模型卡片和许可证。既有适用于 transformers 库的版本,也有可用于 Google 原始代码库的检查点,以及社区可以进行量化的全精度 GGUF 文件。
  • Transformers 集成
  • Google Cloud 集成
  • Inference Endpoints 集成
  • 代码基准测试

目录

什么是 CodeGemma?

CodeGemma 是 Google 推出的一系列代码专家 LLM 模型,基于预训练的 2B 和 7B Gemma 检查点。CodeGemma 在额外 5000 亿个主要涵盖英语、数学和代码的数据标记上进一步训练,以提升逻辑和数学推理能力,适用于代码补全和生成。

CodeGemma 2B 专门针对代码填充进行训练,旨在实现快速的代码补全和生成,尤其是在延迟和/或隐私至关重要的场景中。CodeGemma 7B 的训练组合包括代码填充数据(80%)和自然语言。它可用于代码补全,以及代码和语言的理解与生成。CodeGemma 7B Instruct 在 CodeGemma 7B 的基础上针对指令遵循进行了微调。它旨在用于对话,尤其是在代码、编程或数学推理相关主题上。所有模型都具有与其前代相同的 8K 标记上下文大小。

The CodeGemma family

此图来自 原始报告

评估结果

CodeGemma-7B 在 HumanEval(一个流行的 Python 代码模型评估基准)上,除 DeepSeek-Coder-7B 外,表现优于同等规模的 7B 模型。在 MultiPL-E(HumanEval 的翻译版本)中对 Java、JavaScript 和 C++ 等其他编程语言的评估也是如此。根据技术报告,该模型在 7B 模型中在 GSM8K 上表现最佳。指令版本 CodeGemma-7B-it 在 HumanEval 和 MBPP 上对最流行的语言有所改进(参见论文表5)。更多详情,您可以查看 BigCode 排行榜 或下方的一些指标。

模型 预训练规模 [标记] Python JavaScript
100亿+ 模型
StarCoder 2 15B 4,000B+ 44.15 44.24
Code Llama 13B 2,500B 35.07 38.26
70亿 模型
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
<30亿 模型
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
模型 预训练规模 [标记] Python JavaScript
100亿+ 模型
Code Llama 13B 2,620B 50.6 40.92
Code Llama 13B 2,620B 42.89 40.66
70亿 模型
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 使用中间填充(FIM)目标对此任务进行了训练,其中您提供前缀和后缀作为补全的上下文。以下标记用于分隔输入的不同部分:

  • <|fim_prefix|> 位于我们要运行的补全之前的上下文之前。
  • <|fim_suffix|> 位于后缀之前。您必须将此标记放在编辑器中光标将定位的确切位置,因为这是模型将进行代码补全的位置。
  • <|fim_middle|> 是邀请模型运行生成的提示。

除此之外,还有 <|file_separator|>,它提供了多文件上下文。我们将在与 transformers 一起使用部分展示使用示例。

CodeGemma 7B Instruct 使用与基础 Gemma 指令调优版本相同的提示格式,遵循以下对话结构:

<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 或下面的嵌入式 Chatbot 中尝试 CodeGemma 模型(70 亿参数!):

在底层,这个 playground 使用 Transformers 实现。您也可以复制 Space 供自己使用——它是自包含的,因此您可以检查源代码并根据需要调整它!

使用 Transformers

使用 Transformers 4.39 版本,您可以使用 CodeGemma 并利用 HF Mirror 生态系统中的所有工具,例如:

  • 训练和推理脚本及示例
  • 安全文件格式(safetensors)
  • 与 bitsandbytes(4 位量化)、PEFT(参数高效微调)和 Flash Attention 2 等工具的集成
  • 用于运行模型生成的实用程序和辅助工具
  • 导出模型以进行部署的机制

与 Gemma 模型一样,CodeGemma 与 torch.compile() 兼容,可显著加速推理。

额外福利:我们制作了一个 Colab 笔记本,让您一键尝试该模型,在此处。

要使用 transformers 运行 CodeGemma,请确保使用最新版本:

pip install --upgrade transformers

以下代码片段展示了如何使用 transformers 中的 codegemma-2b 进行代码补全。它需要约 6 GB 的 RAM(使用 float16 精度),非常适合消费级 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|> 标记出现在编辑器中光标将放置的位置,标记了生成的位置。<|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 标记或 EOS 标记之后出现的所有内容。我们可以通过向 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 检查点以 bfloat16 精度发布。如果在加载模型时未指定 torch_dtype,PyTorch 会将它们上转为 float32。将其转换为 float16 完全可以正常使用,并且在某些硬件上可能比 bfloat16 快得多。为了获得最高精度,我们建议你使用 bfloat16 而不是 float32。

你还可以自动量化模型,以 8 位或 4 位模式加载。以 4 位加载 CodeGemma 7B 运行大约需要 9 GB 内存,使其与许多消费级显卡以及 Google Colab 中的所有 GPU 兼容。以下是以 4 位加载生成管道的方法:

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

与 Google Cloud 集成

你可以通过 Vertex AI 或 Google Kubernetes Engine (GKE),使用 Text Generation Inference 和 Transformers 在 Google Cloud 上部署和训练 Gemma。

要从 HF Mirror 部署 CodeGemma 模型,请转到 模型页面 并点击 Deploy -> Google Cloud. 这将带你进入 Google Cloud Console,在那里你可以一键在由 Text Generation Inference 提供支持的 Vertex AI 或 GKE 上部署 CodeGemma。

你也可以直接通过 Vertex AI Model Garden 访问 CodeGemma。

GCP Integration

与 Inference Endpoints 集成

你可以在 HF Mirror 的 Inference Endpoints 上部署 CodeGemma,其后端使用 Text Generation Inference。Text Generation Inference 是 HF Mirror 开发的生产就绪推理容器,可轻松部署大型语言模型。它具有连续批处理、令牌流式传输、用于在多 GPU 上快速推理的张量并行、生产就绪的日志记录和跟踪等功能,并在 Apache 2 许可证下分发。

要部署 CodeGemma 模型,请转到 模型页面 并点击 Deploy -> Inference Endpoints 小部件。你可以在之前的博客文章中了解更多关于 使用 HF Mirror Inference Endpoints 部署 LLM 的信息。请注意,T4 不支持 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)

其他资源

来源:Hugging Face Blog · hf-mirror.com