Ллама 2 учится программировать

'Llama 2 learns programming' in English.

Введение

Code Llama – это семейство современных версий Llama 2 с открытым доступом, специализированных для работы с кодом, и мы с радостью представляем интеграцию в экосистему Hugging Face! Code Llama был выпущен с той же лицензией сообщества, которую имеет Llama 2, и доступен для коммерческого использования.

Сегодня мы рады представить:

  • Модели на хабе с их модельными картами и лицензией
  • Интеграцию с Transformers
  • Интеграцию с Text Generation Inference для быстрого и эффективного производственного вывода
  • Интеграцию с Inference Endpoints
  • Бенчмарки кода

Code LLMs – это захватывающий прогресс для программистов, потому что они могут повысить производительность с помощью автодополнения кода в средах разработки, заботиться о повторяющихся или надоедливых задачах, таких как написание документаций, или создавать модульные тесты.

Содержание

  • Введение
  • Содержание
  • Что такое Code Llama?
  • Как использовать Code Llama?
    • Демо
    • Transformers
      • Автодополнение кода
      • Заполнение кода
      • Диалоговые инструкции
      • 4-битная загрузка
    • Использование text-generation-inference и Inference Endpoints
  • Оценка
  • Дополнительные ресурсы

Что такое Code Llama?

Релиз Code Llama представляет собой семейство моделей с 7, 13 и 34 миллиардами параметров. Базовые модели инициализируются из Llama 2 и затем обучаются на 500 миллиардах токенов кода. Мета-донастроила эти базовые модели для двух разных вариантов: специалиста по Python (дополнительные 100 миллиардов токенов) и версию с донастройкой инструкций, которая может понимать естественноязыковые инструкции.

Модели демонстрируют современную производительность на языках Python, C++, Java, PHP, C#, TypeScript и Bash. Базовые варианты 7B и 13B, а также варианты с инструкциями поддерживают заполнение на основе окружающего контента, что делает их идеальными в качестве помощников по коду.

Code Llama была обучена с использованием окна контекста размером 16k. Кроме того, у трех вариантов моделей была донастройка на длинных контекстах, что позволило им работать с окном контекста до 100 000 токенов.

Увеличение окна контекста Llama 2 с 4k до 16k в Code Llama (которое может экстраполироваться до 100k) стало возможным благодаря последним достижениям в масштабировании RoPE. Сообщество выяснило, что позиционные эмбеддинги Llama могут быть интерполированы линейно или в частотной области, что упрощает переход к более крупному окну контекста с помощью донастройки. В случае Code Llama масштабирование в частотной области выполняется с использованием резерва: длина донастройки является долей масштабированной предобученной длины, что дает модели мощные возможности экстраполяции.

Все модели изначально обучались на 500 миллиардах токенов на практически дедуплицированном наборе данных публично доступного кода. Набор данных также содержит некоторые наборы данных на естественном языке, такие как обсуждения о коде и фрагменты кода. К сожалению, больше информации о наборе данных нет.

Для модели с инструкциями использовались два набора данных: набор данных для донастройки инструкций, собранный для Llama 2 Chat, и самодоностроенный набор данных. Самодоностроенный набор данных был создан с использованием Llama 2 для создания программных вопросов на собеседованиях, а затем использовался Code Llama для генерации модульных тестов и решений, которые затем оцениваются путем выполнения тестов.

Как использовать Code Llama?

Code Llama доступна в экосистеме Hugging Face, начиная с версии transformers 4.33. До выпуска transformers 4.33 установите его из основной ветки.

Демо

Вы можете легко попробовать модель Code Llama (13 миллиардов параметров!) в этом пространстве или во встроенной среде разработки ниже:

В этой среде разработки используется технология Text Generation Inference от Hugging Face, та же, которая используется в HuggingChat, и мы расскажем о ней подробнее в следующих разделах.

Transformers

С выходом версии transformers 4.33 вы можете использовать Code Llama и использовать все инструменты в экосистеме HF, такие как:

  • скрипты и примеры обучения и вывода
  • безопасный формат файла (safetensors)
  • интеграции с инструментами, такими как bitsandbytes (квантование 4 бита) и PEFT (эффективное настройка параметров)
  • утилиты и помощники для запуска генерации с моделью
  • механизмы экспорта моделей для развертывания

До выпуска transformers 4.33, пожалуйста, установите его из основной ветки.

!pip install git+https://github.com/huggingface/transformers.git@main accelerate

Завершение кода

Модели 7B и 13B могут использоваться для завершения текста/кода или заполнения пропусков. Ниже приведен фрагмент кода, использующий интерфейс pipeline для демонстрации завершения текста. Он работает на бесплатном уровне Colab, если вы выбираете GPU-рабочую среду.

from transformers import AutoTokenizer
import transformers
import torch

tokenizer = AutoTokenizer.from_pretrained("codellama/CodeLlama-7b-hf")
pipeline = transformers.pipeline(
    "text-generation",
    model="codellama/CodeLlama-7b-hf",
    torch_dtype=torch.float16,
    device_map="auto",
)

sequences = pipeline(
    'def fibonacci(',
    do_sample=True,
    temperature=0.2,
    top_p=0.9,
    num_return_sequences=1,
    eos_token_id=tokenizer.eos_token_id,
    max_length=100,
)
for seq in sequences:
    print(f"Результат: {seq['generated_text']}")

Это может привести к следующему выводу:

Результат: def fibonacci(n):
    if n == 0:
        return 0
    elif n == 1:
        return 1
    else:
        return fibonacci(n-1) + fibonacci(n-2)

def fibonacci_memo(n, memo={}):
    if n == 0:
        return 0
    elif n == 1:
        return

Code Llama специализируется на понимании кода, но сам по себе является языковой моделью. Вы можете использовать ту же стратегию генерации для автозаполнения комментариев или общего текста.

Заполнение кода

Это специализированная задача, особенная для моделей кода. Модель обучена генерировать код (включая комментарии), наилучшим образом соответствующий существующему префиксу и суффиксу. Это стратегия, обычно используемая помощниками по коду: их просят заполнить текущую позицию курсора, учитывая содержимое, которое появляется перед и после нее.

Эта задача доступна в вариантах base и instruction моделей 7B и 13B. Она не доступна для моделей 34B или версий Python.

Чтобы успешно использовать эту функцию, вам нужно обратить особое внимание на формат, используемый для обучения модели для этой задачи, так как он использует специальные разделители для идентификации различных частей подсказки. Давайте рассмотрим пример:

from transformers import AutoTokenizer, AutoModelForCausalLM
import transformers
import torch

model_id = "codellama/CodeLlama-7b-hf"
tokenizer = AutoTokenizer.from_pretrained(model_id)
model = AutoModelForCausalLM.from_pretrained(
    model_id,
    torch_dtype=torch.float16
).to("cuda")

prefix = 'def remove_non_ascii(s: str) -> str:\n    """ '
suffix = "\n    return result\n"

prompt = f"<PRE> {prefix} <SUF>{suffix} <MID>"
inputs = tokenizer(prompt, return_tensors="pt").to("cuda")

output = model.generate(
    inputs["input_ids"],
    max_new_tokens=200,
    do_sample=False,
)
output = output[0].to("cpu")
print(tokenizer.decode(output))

<s> <PRE> def remove_non_ascii(s: str) -> str:
    """ <SUF>
    return result
 <MID>
    Remove non-ASCII characters from a string.

    :param s: The string to remove non-ASCII characters from.
    :return: The string with non-ASCII characters removed.
    """
    result = ""
    for c in s:
        if ord(c) < 128:
            result += c <EOT></s>

Для использования завершения вам потребуется обработать вывод, чтобы обрезать текст между токенами <MID> и <EOT> – это то, что находится между префиксом и суффиксом, которые мы предоставили.

Инструкции для разговорных интерфейсов

Базовую модель можно использовать как для завершения текста, так и для заполнения пропусков, как описано выше. В релизе Code Llama также включена модель, обученная на инструкциях, которую можно использовать в разговорных интерфейсах.

Для подготовки входных данных для этой задачи мы должны использовать шаблон запроса, описанный в нашей статье блога Llama 2, который мы повторяем здесь:

<s>[INST] <<SYS>>
{{ system_prompt }}
<</SYS>>

{{ user_msg_1 }} [/INST] {{ model_answer_1 }} </s><s>[INST] {{ user_msg_2 }} [/INST]

Обратите внимание, что системный запрос является необязательным – модель будет работать и без него, но вы можете использовать его для дополнительной настройки ее поведения или стиля. Например, если вы всегда хотите получать ответы на JavaScript, вы можете указать это здесь. После системного запроса вам необходимо предоставить все предыдущие взаимодействия в разговоре: что спрашивал пользователь и что отвечала модель. Как и в случае с заполнением пропусков, необходимо обратить внимание на используемые разделители. Последний компонент ввода всегда должен быть новой инструкцией пользователя, которая будет сигналом для модели предоставить ответ.

Следующие фрагменты кода демонстрируют, как работает этот шаблон на практике.

  1. Первый запрос пользователя без системного запроса
user = 'In Bash, how do I list all text files in the current directory (excluding subdirectories) that have been modified in the last month?'

prompt = f"<s>[INST] {user.strip()} [/INST]"
inputs = tokenizer(prompt, return_tensors="pt", add_special_tokens=False).to("cuda")
  1. Первый запрос пользователя с системным запросом
system = "Provide answers in JavaScript"
user = "Write a function that computes the set of sums of all contiguous sublists of a given list."

prompt = f"<s><<SYS>>\\n{system}\\n<</SYS>>\\n\\n{user}"
inputs = tokenizer(prompt, return_tensors="pt", add_special_tokens=False).to("cuda")
  1. Продолжающийся разговор с предыдущими ответами

Процесс такой же, как и в Llama 2. Мы не использовали циклы и не обобщали этот примерный код для большей ясности:

system = "System prompt"
user_1 = "user_prompt_1"
answer_1 = "answer_1"
user_2 = "user_prompt_2"
answer_2 = "answer_2"
user_3 = "user_prompt_3"

prompt  = f"<<SYS>>\\n{system}\\n<</SYS>>\\n\\n{user_1}"
prompt  = f"<s>[INST] {prompt.strip()} [/INST] {answer_1.strip()} </s>"
prompt += f"<s>[INST] {user_2.strip()} [/INST] {answer_2.strip()} </s>"
prompt += f"<s>[INST] {user_3.strip()} [/INST]"

inputs = tokenizer(prompt, return_tensors="pt", add_special_tokens=False).to("cuda")

4-битовая загрузка

Интеграция Code Llama в Transformers означает, что вы получаете немедленную поддержку передовых функций, таких как 4-битовая загрузка. Это позволяет запускать модели с большим количеством параметров 32B на обычных графических процессорах, таких как карты nvidia 3090!

Вот как можно запустить вывод в режиме 4-битового режима:

from transformers import AutoTokenizer, AutoModelForCausalLM, BitsAndBytesConfig
import torch

model_id = "codellama/CodeLlama-34b-hf"
quantization_config = BitsAndBytesConfig(
   load_in_4bit=True,
   bnb_4bit_compute_dtype=torch.float16
)

tokenizer = AutoTokenizer.from_pretrained(model_id)
model = AutoModelForCausalLM.from_pretrained(
    model_id,
    quantization_config=quantization_config,
    device_map="auto",
)

prompt = 'def remove_non_ascii(s: str) -> str:\n    """ '
inputs = tokenizer(prompt, return_tensors="pt").to("cuda")

output = model.generate(
    inputs["input_ids"],
    max_new_tokens=200,
    do_sample=True,
    top_p=0.9,
    temperature=0.1,
)
output = output[0].to("cpu")
print(tokenizer.decode(output))

Использование генерации текста и конечных точек вывода

Генерация текста с использованием вывода – это контейнер для вывода готового к производству, разработанный Hugging Face для облегчения развертывания больших языковых моделей. Он имеет такие функции, как непрерывная пакетная обработка, потоковая передача токенов, тензорное параллелизм для быстрого вывода на нескольких GPU, а также готовый к производству журналирование и трассировка.

Вы можете попробовать использовать генерацию текста на своей собственной инфраструктуре, или вы можете использовать конечные точки вывода Hugging Face. Чтобы развернуть модель Codellama 2, перейдите на страницу модели и нажмите на виджет Deploy -> Inference Endpoints.

  • Для моделей 7B мы рекомендуем выбрать “GPU [VoAGI] – 1x Nvidia A10G”.
  • Для моделей 13B мы рекомендуем выбрать “GPU [xlarge] – 1x Nvidia A100”.
  • Для моделей 34B мы рекомендуем выбрать “GPU [1xlarge] – 1x Nvidia A100” с включенной квантованием bitsandbytes или “GPU [2xlarge] – 2x Nvidia A100”

Примечание: Вам может понадобиться запросить увеличение квоты по электронной почте api-enterprise@huggingface.co для доступа к A100s

Вы можете узнать больше о том, как развернуть LLM с использованием конечных точек вывода Hugging Face в нашем блоге. Блог содержит информацию о поддерживаемых гиперпараметрах и о том, как потоково передавать ответ с использованием Python и Javascript.

Оценка

Языковые модели для кода обычно тестируются на наборах данных, таких как HumanEval. Он состоит из программных задач, где модель представляется сигнатурой функции и докстрингом, и ей предлагается завершить тело функции. Предложенное решение затем проверяется путем выполнения набора предопределенных модульных тестов. Наконец, сообщается процент пройденных тестов, который описывает, сколько решений прошло все тесты. Процент pass@1 описывает, как часто модель генерирует проходящее решение при однократном запуске, в то время как pass@10 описывает, как часто хотя бы одно решение проходит из 10 предложенных кандидатов.

Хотя HumanEval является сравнительным тестом на Python, были предприняты значительные усилия для его перевода на другие языки программирования, что позволяет провести более всестороннюю оценку. Одним из таких подходов является MultiPL-E, который переводит HumanEval на десятки языков. Мы размещаем многопользовательскую таблицу лидеров по коду на его основе, чтобы позволить сообществу сравнивать модели на разных языках и оценивать, какая модель лучше подходит для их конкретного случая.

Примечание: Оценки, представленные в таблице выше, взяты из нашей таблицы лидеров по коду, где мы оцениваем все модели с одинаковыми настройками. Для получения более подробной информации, обратитесь к таблице лидеров.

Дополнительные ресурсы

  • Модели на Hub
  • Страница с документацией
  • Официальное объявление Meta
  • Руководство по ответственному использованию
  • Демонстрация