Обзор и Codelab для генерации текста с помощью Bloom

Оглавление

Что такое Bloom и почему мы должны действовать осторожно

Bloom — это новая многоязычная модель LLM (Large Language Model) с параметрами 176B от BigScience, открытой совместной работы Huggingface с сотнями исследователей и институтов по всему миру. Самым примечательным в Bloom, помимо разнообразия участников, является тот факт, что Bloom является полностью открытым исходным кодом, а Huggingface сделал свои полные (а также некоторые более мелкие) предварительно обученные модели доступными для общественности через API-интерфейс Transformers. Другие организации, проводящие исследования LLM, в том числе OpenAI, Meta и Google, решили оставить свои LLM в основном внутренними или ограничили доступ строго контролируемым группам закрытых бета-тестеров.

Следует обсудить опасность использования этих моделей в реальном мире, не говоря уже о том, чтобы сделать их общедоступными. Опасения варьируются от усиления несправедливой и системной предвзятости до ускорения распространения дезинформации в Интернете. Гораздо более компетентные голоса, чем у меня, и они продолжают выступать за более подотчетное человеку, прозрачное и справедливое развитие и использование этой технологии. Если вы не знакомы, я бы посоветовал вам сделать здесь паузу и потратить некоторое время на изучение работ таких людей, как Тимнит Гебру (Институт ДАИР), Маргарет Митчелл и команды Партнерство по ИИ, среди многих других.

Соответственно, я призываю всех придерживаться предполагаемого использования и помнить о рисках и ограничениях, изложенных в карточке модели Блума, когда вы будете продвигаться дальше этого вводного руководства в стиле Hello World.

Настройка вашей среды

Мы собираемся использовать версию общей модели Блума с параметрами 1,3 Б в PyTorch, выполняя логические выводы, используя только ЦП. Хотя я использую виртуальную машину Python 3 Jupyter Lab в сервисе Google Cloud Vertex, вы сможете работать практически в любой локальной или размещенной среде *nix Jupyter.

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

pip install venv
python -m venv .venv
source .venv/bin/activate

Далее мы установим пакеты, которые нам понадобятся, в нашу среду .venv:

pip install transformers
pip install torch torchvision torchaudio --extra-index-url https://download.pytorch.org/whl/cpu

Наконец, нам нужно выйти из нашего venv, зарегистрировать нашу новую среду в Jupyter Lab в качестве ядра и снова запустить ее:

deactivate
ipython kernel install --user --name=venv
source .venv/bin/activate

Когда вы перейдете к опции «Выбрать ядро» в Jupyter Lab, вы должны увидеть venv в качестве опции. Давайте выберем и подключимся к нему.

Загрузка предварительно обученного токенизатора и модели

Запуская наш блокнот-пример (также доступный на GitHub), мы сначала импортируем несколько модулей из пакетов, которые мы установили в venv ранее:

import transformers
from transformers import BloomForCausalLM
from transformers import BloomTokenizerFast
import torch

Теперь, к главному событию, мы загружаем предварительно обученный параметр Bloom 1.3B общего LLM. Хотя я точно не определил размер, кажется, что эта версия весов и смещений модели занимает около 1,5 ГБ места. Нам также необходимо получить токенизатор Блума. Это позволит нам превратить наш вводимый текст («подсказку») во вложение, которое Блум сможет понять:

model = BloomForCausalLM.from_pretrained("bigscience/bloom-1b3")
tokenizer = BloomTokenizerFast.from_pretrained("bigscience/bloom-1b3")

Говоря об этом, давайте установим некоторые глобальные переменные, включая наш текст подсказки:

prompt = "It was a dark and stormy night"
result_length = 50
inputs = tokenizer(prompt, return_tensors="pt")

Несколько заметок:

  • result_length калибрует размер ответа (в токенах), который мы получаем на приглашение от модели.
  • inputs содержит встроенное представление prompt, закодированное специально для использования PyTorch. Если бы мы использовали TensorFlow, мы бы прошли return_tensors="tf".

Запуск логического вывода: стратегии для улучшения ответов

Прежде чем мы отправим модель нашу подсказку, нам нужно подумать о том, какие стратегии декодирования/поиска могут лучше всего работать для нашего варианта использования. С авторегрессионными преобразователями (обученными для предсказания следующего токена) у нас есть несколько вариантов поиска в пространстве ответов для наиболее разумного вывода. Эта великолепная статья Патрика фон Платена (Huggingface) отлично объясняет детали и математические расчеты, лежащие в основе трех методов, которые мы будем пробовать, поэтому я не буду изобретать велосипед. Однако я дам вам версию TL; DR каждого:

  • Жадный поиск просто выбирает следующее слово на каждом временном шаге t+1, которое имеет наибольшую прогнозируемую вероятность следования за словом в момент t. Одна из основных проблем здесь заключается в том, что жадный поиск пропустит слова с высокой вероятностью в момент времени t+1, если ему предшествует слово с низкой вероятностью в момент времени t.
  • Beam Search отслеживает n-ю (num_beams) наиболее вероятную последовательность слов и выводит наиболее вероятную последовательность. Звучит здорово, но этот метод не работает, когда длина вывода может сильно варьироваться — как в случае генерации текста с открытым концом. Как жадный, так и лучевой поиск также производят выходные данные, распределение которых не очень хорошо согласуется с тем, как люди могут выполнять ту же задачу (т. Е. Оба могут создавать довольно повторяющийся скучный текст).
  • Выборка с Top-k + Top-p представляет собой комбинацию трех методов. Под выборкой мы подразумеваем, что следующее слово выбирается случайным образом на основе его условного распределения вероятностей (von Platen, 2020). В Top-k мы выбираем k наиболее вероятных слов, а затем перераспределяем вероятностную массу между ними перед следующим розыгрышем. Top-p добавляет к top-k дополнительное ограничение: мы выбираем из наименьшего набора слов, совокупная вероятность которых превышает p.

Теперь мы попробуем все 3 стратегии, чтобы сравнить результаты:

# Greedy Search
print(tokenizer.decode(model.generate(inputs["input_ids"], 
                       max_length=result_length
                      )[0]))

Ночь была темная и ненастная, дул сильный ветер. Снег
шел быстро, и земля была покрыта им.
Лошади примерзли к земле, а мужчины сбились в кучу

# Beam Search
print(tokenizer.decode(model.generate(inputs["input_ids"],
                       max_length=result_length, 
                       num_beams=2, 
                       no_repeat_ngram_size=2,
                       early_stopping=True
                      )[0]))

Ночь была темная и ненастная, дул сильный ветер. Я был
посреди дороги, когда услышал громкий треск. Он исходил из дома
на другой стороне дороги. Мужчина был

# Sampling Top-k + Top-p
print(tokenizer.decode(model.generate(inputs["input_ids"],
                       max_length=result_length, 
                       do_sample=True, 
                       top_k=50, 
                       top_p=0.9
                      )[0]))

Это была темная и штормливая ночь. Был почти полдень. Когда я вышла из машины и сняла обувь, ко мне подошел мужчина и сел. У него были усы, густые волосы и карие глаза. Он

Выводы и следующие шаги

Лично мне все эти результаты кажутся в основном разумными. Вы обнаружите, что по мере повторения и настройки параметров и подсказок некоторые стратегии могут давать более оптимальные результаты для вашего конкретного случая использования. На самом деле, создание подсказок, чтобы уговорить LLM сделать что-то полезное становится чем-то вроде искусства и науки.

В качестве бонуса несоответствие между термином ночь и выводом почти полдень в выборке top-k + top-pвыходных данных иллюстрирует ценный момент в что можно легко принять LLM за мыслящие машины с внутренними моделями мира, которые они используют для структурирования своих ответов (как люди). На самом деле нам не нужно глубокое обучение, большие данные или LLM, чтобы доказать, что люди все очеловечивают. Вместо этого мы должны видеть LLM такими, какие они есть: синтаксически правдоподобными генераторами предложений, которые следует развертывать с широко открытыми глазами (и большим количеством смягчающих инженерных решений и инклюзивного дизайна) в отношении их ограничений.

Имея это в виду, мое собственное путешествие с Блумом пойдет на несколько нитей вперед; в значительной степени сосредоточены на адаптации как генерации текста, так и головок классификации к задачам современного аудита. Конкретно:

  • Обобщение кода. Может ли Блум обобщить логику блока кода простым языком?
  • Перенос обучения для классификации токенов. Можно ли обучить Блум выявлению рисков и/или средств контроля в технологической документации?
  • Надежность. Какие гарантии, если таковые имеются, мы можем заложить в прогнозы Блума в отношении фактической точности сгенерированных сводок и классификаций?

Удачной генерации!

Рекомендации