# CodeLlama

[Code Llama](https://huggingface.co/papers/2308.12950) 是一个基于 [Llama 2](./llama2) 的专用大型语言模型系列，专为编码任务设计。它提供多种变体——通用代码、Python 专用以及指令跟随变体——所有变体均提供 7B、13B、34B 和 70B 参数规模。Code Llama 模型可以生成、解释代码，甚至补全代码中缺失的部分（称为“infilling”）。尽管它是在 16K token 的序列上训练的，但它也能处理非常长的上下文，并稳定生成多达 100k token 的内容。

您可以在 [Code Llama](https://huggingface.co/collections/meta-llama/code-llama-family-661da32d0a9d678b6f55b933) 集合中找到所有原始的 Code Llama 检查点。

> [!TIP]
> 点击右侧边栏中的 Code Llama 模型，以查看更多将 Code Llama 应用于不同编码任务的示例。

下面的示例演示了如何使用 [Pipeline](/docs/transformers/v5.23.0/zh/main_classes/pipelines#transformers.Pipeline)、[AutoModel](/docs/transformers/v5.23.0/zh/model_doc/auto#transformers.AutoModel) 或命令行来生成代码。

```python
from transformers import pipeline

pipe = pipeline(
    "text-generation",
    model="meta-llama/CodeLlama-7b-hf",
    device_map=0
)

# basic code generation
result = pipe("# Function to calculate the factorial of a number\ndef factorial(n):", max_new_tokens=256)
print(result[0]['generated_text'])

# infilling
infill_result = pipe("def remove_non_ascii(s: str) -> str:\n    \"\"\" <FILL_ME>\n    return result", max_new_tokens=200)
print(infill_result[0]['generated_text'])
```

```python
from transformers import AutoModelForCausalLM, AutoTokenizer

tokenizer = AutoTokenizer.from_pretrained("meta-llama/CodeLlama-7b-hf")
model = AutoModelForCausalLM.from_pretrained(
    "meta-llama/CodeLlama-7b-hf",
    device_map="auto",
    attn_implementation="sdpa"
)

# basic code generation
prompt = "# Function to calculate the factorial of a number\ndef factorial(n):"
input_ids = tokenizer(prompt, return_tensors="pt").to(model.device)

output = model.generate(
    **input_ids,
    max_new_tokens=256,
    cache_implementation="static"
)
print(tokenizer.decode(output[0], skip_special_tokens=True))

# infilling
infill_prompt = "def remove_non_ascii(s: str) -> str:\n    \"\"\" <FILL_ME>\n    return result"
input_ids = tokenizer(infill_prompt, return_tensors="pt").to(model.device)

filled_output = model.generate(**input_ids, max_new_tokens=200)
filled_text = tokenizer.decode(filled_output[0], skip_special_tokens=True)
print(filled_text)
```

量化通过以较低精度表示权重来降低大模型的内存负担。有关更多可用的量化后端，请参阅 [量化](../quantization/overview) 概述。

以下示例使用 [bitsandbytes](../quantization/bitsandbytes) 仅将权重量化为 4 位。

```python
# pip install bitsandbytes
import torch

from transformers import AutoModelForCausalLM, BitsAndBytesConfig, CodeLlamaTokenizer

bnb_config = BitsAndBytesConfig(load_in_4bit=True, bnb_4bit_compute_dtype=torch.bfloat16, bnb_4bit_quant_type="nf4", bnb_4bit_use_double_quant=True)
tokenizer = CodeLlamaTokenizer.from_pretrained("meta-llama/CodeLlama-34b-hf")
model = AutoModelForCausalLM.from_pretrained(
   "meta-llama/CodeLlama-34b-hf",
   device_map="auto",
   quantization_config=bnb_config
)

prompt = "# Write a Python function to check if a string is a palindrome\ndef is_palindrome(s):"
input_ids = tokenizer(prompt, return_tensors="pt").to(model.device)

output = model.generate(**input_ids, max_new_tokens=200, cache_implementation="static")
print(tokenizer.decode(output[0], skip_special_tokens=True))
```

使用 [AttentionMaskVisualizer](https://github.com/huggingface/transformers/blob/beb9b5b02246b9b7ee81ddf938f93f44cfeaad19/src/transformers/utils/attention_visualizer.py#L139) 可以更直观地了解模型能够和不能关注哪些 token。

```python
from transformers.utils.attention_visualizer import AttentionMaskVisualizer

visualizer = AttentionMaskVisualizer("meta-llama/CodeLlama-7b-hf")
visualizer("""def func(a, b):
  return a + b""")
```

    

## 备注

- Infilling 功能仅在 7B 和 13B 基础模型中可用，在 Python、Instruct、34B 或 70B 模型中不可用。
- 在需要填充输入的位置使用 `<FILL_ME>` 标记。分词器会将该标记拆分，以生成遵循 [原始训练模式](https://github.com/facebookresearch/codellama/blob/cb51c14ec761370ba2e2bc351374a79265d0465e/llama/generation.py#L402) 的格式化输入字符串。这比自行准备模式更加稳健。

    ```py
    from transformers import LlamaForCausalLM, CodeLlamaTokenizer

    tokenizer = CodeLlamaTokenizer.from_pretrained("meta-llama/CodeLlama-7b-hf")
    model = LlamaForCausalLM.from_pretrained("meta-llama/CodeLlama-7b-hf", device_map="auto")
    PROMPT = '''def remove_non_ascii(s: str) -> str:
        """ <FILL_ME>
        return result
    '''
    input_ids = tokenizer(PROMPT, return_tensors="pt").to(model.device)["input_ids"]
    generated_ids = model.generate(input_ids, max_new_tokens=128)

    filling = tokenizer.batch_decode(generated_ids[:, input_ids.shape[1]:], skip_special_tokens = True)[0]
    print(PROMPT.replace("<FILL_ME>", filling))
    ```

- 使用 `bfloat16` 进行进一步训练或微调，使用 `float16` 进行推理。
- 在编码前缀或后缀时，`BOS` 字符不用于填充，仅在每个提示的开头使用。
- 分词器是一个基于 [SentencePiece](https://github.com/google/sentencepiece) 的字节对编码模型。在解码过程中，如果第一个 token 是单词的开头（例如，“Banana”），分词器不会在字符串前添加前缀空格。

## CodeLlamaTokenizer[[transformers.CodeLlamaTokenizer]]

#### transformers.CodeLlamaTokenizer[[transformers.CodeLlamaTokenizer]]

```python
transformers.CodeLlamaTokenizer(vocab: str | dict[str, int] | None = None, merges: str | list[str] | None = None, clean_up_tokenization_spaces = False, unk_token = '<unk>', bos_token = '<s>', eos_token = '</s>', prefix_token = '▁<PRE>', middle_token = '▁<MID>', suffix_token = '▁<SUF>', eot_token = '▁<EOT>', fill_token = '<FILL_ME>', additional_special_tokens = None, use_default_system_prompt: bool = False, add_prefix_space: bool | None = True, add_bos_token: bool = True, **kwargs)
```

[来源](https://github.com/huggingface/transformers/blob/v5.23.0/src/transformers/models/code_llama/tokenization_code_llama.py#L41)

**参数：**

clean_up_tokenization_spaces (`str`，*可选*，默认为 `False`)：是否在解码后清理空格。清理操作包括移除多余空格等潜在伪影。

unk_token (`str`，*可选*，默认为 `"<unk>"`)：未知标记。不在词汇表中的标记无法转换为 ID，因此会被设置为该标记。

bos_token (`str`，*可选*，默认为 `"<s>"`)：预训练期间使用的序列起始标记。可用作序列分类标记。

eos_token (`str`，*可选*，默认为 `"</s>"`)：序列结束标记。

prefix_token (`str`，*可选*，默认为 `"▁<PRE>"`)：用于填充的起始标记。

middle_token (`str`，*可选*，默认为 `"▁<MID>"`)：用于填充的中间标记。

suffix_token (`str`，*可选*，默认为 `"▁<SUF>"`)：用于填充的后缀标记。

eot_token (`str`，*可选*，默认为 `"▁<EOT>"`)：用于文本填充的文本结束标记。

fill_token (`str`，*可选*，默认为 `"<FILL_ME>"`)：用于将输入拆分为前缀和后缀的标记。

additional_special_tokens (`list[str]`, *可选*) : 分词器使用的额外特殊标记。

add_bos_token (`bool`，*可选*，默认为 `True`)：是否在序列开头添加序列起始标记。

add_eos_token (`bool`，*可选*，默认为 `False`)：是否在序列末尾添加序列结束标记。

use_default_system_prompt (`bool`, *可选*, 默认为 `False`) : 是否使用 Llama 的默认系统提示词。

add_prefix_space (`bool`, *可选*) : 是否向输入添加一个初始空格。这允许将开头的单词视为与其他单词一样处理。

vocab (`str`、`dict` 或 `list`，*可选*)：自定义词汇表。如果未提供，则从 vocab_file 加载词汇表。

merges (`str` 或 `list`，*可选*)：自定义合并列表。如果未提供，则从 merges_file 加载合并。

vocab_file (`str`, *可选*) : [SentencePiece](https://github.com/google/sentencepiece) 文件（通常具有 .model 扩展名），其中包含实例化分词器所需的词汇表。

构建一个 Llama 分词器。基于字节级 Byte-Pair-Encoding。

此处显著使用了 ByteFallback，且未进行任何归一化处理。

```python
>>> from transformers import CodeLlamaTokenizer

>>> tokenizer = CodeLlamaTokenizer.from_pretrained("hf-internal-testing/llama-tokenizer")
>>> tokenizer.encode("Hello this is a test")
[1, 15043, 445, 338, 263, 1243]
```

如果要更改 `bos_token` 或 `eos_token`，请确保在初始化模型时指定它们，或者调用 `tokenizer.update_post_processor()` 以确保后处理正确执行（否则编码序列中第一个 token 和最后一个 token 的值将不正确）。更多详细信息，请参阅 [post-processors] (https://huggingface.co/docs/tokenizers/api/post-processors) 文档。

该分词器继承自 [PreTrainedTokenizerFast](/docs/transformers/v5.23.0/zh/main_classes/tokenizer#transformers.TokenizersBackend)，后者包含了大部分主要方法。用户应参考该父类以获取有关这些方法的更多信息。默认配置与 [meta-llama/CodeLlama-7b-Instruct-hf](https://huggingface.co/meta-llama/CodeLlama-7b-Instruct-hf/blob/main/tokenizer_config.json) 相匹配，后者支持提示填充（prompt infilling）。

#### get_special_tokens_mask[[transformers.CodeLlamaTokenizer.get_special_tokens_mask]]

```python
get_special_tokens_mask(token_ids_0: list[int], token_ids_1: list[int] | None = None, already_has_special_tokens: bool = False)
```

[来源](https://github.com/huggingface/transformers/blob/v5.23.0/src/transformers/tokenization_utils_base.py#L1337)

**参数：**

token_ids_0 : （可能已格式化的）序列的 ID 列表。

token_ids_1 : 当 `already_has_special_tokens=True` 时未使用。在这种情况下，必须为 None。

already_has_special_tokens : 序列是否已使用特殊标记进行格式化。

**返回：** 一个包含 [0, 1] 范围内整数的列表

1 表示特殊标记，0 表示序列标记。

从未添加特殊标记的标记列表中检索序列 ID。

对于快速分词器，数据整理器会传入 `already_has_special_tokens=True` 来调用此方法，以在已格式化的序列上构建掩码。在这种情况下，我们通过检查元素是否属于 `all_special_ids` 来计算掩码。

#### update_post_processor[[transformers.CodeLlamaTokenizer.update_post_processor]]

```python
update_post_processor()
```

[来源](https://github.com/huggingface/transformers/blob/v5.23.0/src/transformers/tokenization_utils_tokenizers.py#L628)

使用当前的 `bos_token` 和 `eos_token` 更新底层的后处理器。

#### save_vocabulary[[transformers.CodeLlamaTokenizer.save_vocabulary]]

```python
save_vocabulary(save_directory: str, filename_prefix: str | None = None)
```

[来源](https://github.com/huggingface/transformers/blob/v5.23.0/src/transformers/tokenization_utils_tokenizers.py#L547)

## CodeLlamaTokenizerFast[[transformers.CodeLlamaTokenizer]]

#### transformers.CodeLlamaTokenizer[[transformers.CodeLlamaTokenizer]]

```python
transformers.CodeLlamaTokenizer(vocab: str | dict[str, int] | None = None, merges: str | list[str] | None = None, clean_up_tokenization_spaces = False, unk_token = '<unk>', bos_token = '<s>', eos_token = '</s>', prefix_token = '▁<PRE>', middle_token = '▁<MID>', suffix_token = '▁<SUF>', eot_token = '▁<EOT>', fill_token = '<FILL_ME>', additional_special_tokens = None, use_default_system_prompt: bool = False, add_prefix_space: bool | None = True, add_bos_token: bool = True, **kwargs)
```

[来源](https://github.com/huggingface/transformers/blob/v5.23.0/src/transformers/models/code_llama/tokenization_code_llama.py#L41)

**参数：**

clean_up_tokenization_spaces (`str`，*可选*，默认为 `False`)：是否在解码后清理空格。清理操作包括移除多余空格等潜在伪影。

unk_token (`str`，*可选*，默认为 `"<unk>"`)：未知标记。不在词汇表中的标记无法转换为 ID，因此会被设置为该标记。

bos_token (`str`，*可选*，默认为 `"<s>"`)：预训练期间使用的序列起始标记。可用作序列分类标记。

eos_token (`str`，*可选*，默认为 `"</s>"`)：序列结束标记。

prefix_token (`str`，*可选*，默认为 `"▁<PRE>"`)：用于填充的起始标记。

middle_token (`str`，*可选*，默认为 `"▁<MID>"`)：用于填充的中间标记。

suffix_token (`str`，*可选*，默认为 `"▁<SUF>"`)：用于填充的后缀标记。

eot_token (`str`，*可选*，默认为 `"▁<EOT>"`)：用于文本填充的文本结束标记。

fill_token (`str`，*可选*，默认为 `"<FILL_ME>"`)：用于将输入拆分为前缀和后缀的标记。

additional_special_tokens (`list[str]`, *可选*) : 分词器使用的额外特殊标记。

add_bos_token (`bool`，*可选*，默认为 `True`)：是否在序列开头添加序列起始标记。

add_eos_token (`bool`，*可选*，默认为 `False`)：是否在序列末尾添加序列结束标记。

use_default_system_prompt (`bool`, *可选*, 默认为 `False`) : 是否使用 Llama 的默认系统提示词。

add_prefix_space (`bool`, *可选*) : 是否向输入添加一个初始空格。这允许将开头的单词视为与其他单词一样处理。

vocab (`str`、`dict` 或 `list`，*可选*)：自定义词汇表。如果未提供，则从 vocab_file 加载词汇表。

merges (`str` 或 `list`，*可选*)：自定义合并列表。如果未提供，则从 merges_file 加载合并。

vocab_file (`str`, *可选*) : [SentencePiece](https://github.com/google/sentencepiece) 文件（通常具有 .model 扩展名），其中包含实例化分词器所需的词汇表。

构建一个 Llama 分词器。基于字节级 Byte-Pair-Encoding。

此处显著使用了 ByteFallback，且未进行任何归一化处理。

```python
>>> from transformers import CodeLlamaTokenizer

>>> tokenizer = CodeLlamaTokenizer.from_pretrained("hf-internal-testing/llama-tokenizer")
>>> tokenizer.encode("Hello this is a test")
[1, 15043, 445, 338, 263, 1243]
```

如果要更改 `bos_token` 或 `eos_token`，请确保在初始化模型时指定它们，或者调用 `tokenizer.update_post_processor()` 以确保后处理正确执行（否则编码序列中第一个 token 和最后一个 token 的值将不正确）。更多详细信息，请参阅 [post-processors] (https://huggingface.co/docs/tokenizers/api/post-processors) 文档。

该分词器继承自 [PreTrainedTokenizerFast](/docs/transformers/v5.23.0/zh/main_classes/tokenizer#transformers.TokenizersBackend)，后者包含了大部分主要方法。用户应参考该父类以获取有关这些方法的更多信息。默认配置与 [meta-llama/CodeLlama-7b-Instruct-hf](https://huggingface.co/meta-llama/CodeLlama-7b-Instruct-hf/blob/main/tokenizer_config.json) 相匹配，后者支持提示填充（prompt infilling）。

#### set_infilling_processor[[transformers.CodeLlamaTokenizer.set_infilling_processor]]

```python
set_infilling_processor(reset, suffix_first = False, add_special_tokens = True)
```

[来源](https://github.com/huggingface/transformers/blob/v5.23.0/src/transformers/models/code_llama/tokenization_code_llama.py#L229)

更新归一化器，以确保 `infilling` 的提示格式得到遵守。填充格式如下：如果 suffix_first 为真，则使用 "  {suf}  {pre}"，否则使用 "  {pre} {suf} "

如果 `reset` 设置为 `True`，则 `normalizer` 和 `post_processor` 将重置为其“正常”行为，即 normalizer 会添加前缀空格，而 `post_processor` 会为输入文本添加 `bos_token`。

