CodeGemma - 谷歌官方发布的编码大语言模型
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。
此图来自原始报告
评估结果
在 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 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。
与 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)