From 5ff4f2cd4422a684dd240166fe6f6c8acb940e83 Mon Sep 17 00:00:00 2001 From: Artyom Boyko Date: Sun, 4 Feb 2024 12:31:12 +0300 Subject: [PATCH] Made a full translation of Chapter 2. --- .../_toctree-checkpoint.yml | 201 ---------- .../_toctree-checkpoint.yml | 204 ---------- .../.ipynb_checkpoints/1-checkpoint.mdx | 25 -- .../.ipynb_checkpoints/2-checkpoint.mdx | 353 ------------------ chapters/ru/chapter2/3.mdx | 84 ++--- chapters/ru/chapter2/4.mdx | 116 +++--- chapters/ru/chapter2/5.mdx | 74 ++-- chapters/ru/chapter2/6.mdx | 50 +-- chapters/ru/chapter2/7.mdx | 20 +- chapters/ru/chapter2/8.mdx | 178 ++++----- 10 files changed, 261 insertions(+), 1044 deletions(-) delete mode 100644 chapters/en/.ipynb_checkpoints/_toctree-checkpoint.yml delete mode 100644 chapters/ru/.ipynb_checkpoints/_toctree-checkpoint.yml delete mode 100644 chapters/ru/chapter2/.ipynb_checkpoints/1-checkpoint.mdx delete mode 100644 chapters/ru/chapter2/.ipynb_checkpoints/2-checkpoint.mdx diff --git a/chapters/en/.ipynb_checkpoints/_toctree-checkpoint.yml b/chapters/en/.ipynb_checkpoints/_toctree-checkpoint.yml deleted file mode 100644 index c8364cc6d..000000000 --- a/chapters/en/.ipynb_checkpoints/_toctree-checkpoint.yml +++ /dev/null @@ -1,201 +0,0 @@ -- title: 0. Setup - sections: - - local: chapter0/1 - title: Introduction - -- title: 1. Transformer models - sections: - - local: chapter1/1 - title: Introduction - - local: chapter1/2 - title: Natural Language Processing - - local: chapter1/3 - title: Transformers, what can they do? - - local: chapter1/4 - title: How do Transformers work? - - local: chapter1/5 - title: Encoder models - - local: chapter1/6 - title: Decoder models - - local: chapter1/7 - title: Sequence-to-sequence models - - local: chapter1/8 - title: Bias and limitations - - local: chapter1/9 - title: Summary - - local: chapter1/10 - title: End-of-chapter quiz - quiz: 1 - -- title: 2. Using 🤗 Transformers - sections: - - local: chapter2/1 - title: Introduction - - local: chapter2/2 - title: Behind the pipeline - - local: chapter2/3 - title: Models - - local: chapter2/4 - title: Tokenizers - - local: chapter2/5 - title: Handling multiple sequences - - local: chapter2/6 - title: Putting it all together - - local: chapter2/7 - title: Basic usage completed! - - local: chapter2/8 - title: End-of-chapter quiz - quiz: 2 - -- title: 3. Fine-tuning a pretrained model - sections: - - local: chapter3/1 - title: Introduction - - local: chapter3/2 - title: Processing the data - - local: chapter3/3 - title: Fine-tuning a model with the Trainer API or Keras - local_fw: { pt: chapter3/3, tf: chapter3/3_tf } - - local: chapter3/4 - title: A full training - - local: chapter3/5 - title: Fine-tuning, Check! - - local: chapter3/6 - title: End-of-chapter quiz - quiz: 3 - -- title: 4. Sharing models and tokenizers - sections: - - local: chapter4/1 - title: The Hugging Face Hub - - local: chapter4/2 - title: Using pretrained models - - local: chapter4/3 - title: Sharing pretrained models - - local: chapter4/4 - title: Building a model card - - local: chapter4/5 - title: Part 1 completed! - - local: chapter4/6 - title: End-of-chapter quiz - quiz: 4 - -- title: 5. The 🤗 Datasets library - sections: - - local: chapter5/1 - title: Introduction - - local: chapter5/2 - title: What if my dataset isn't on the Hub? - - local: chapter5/3 - title: Time to slice and dice - - local: chapter5/4 - title: Big data? 🤗 Datasets to the rescue! - - local: chapter5/5 - title: Creating your own dataset - - local: chapter5/6 - title: Semantic search with FAISS - - local: chapter5/7 - title: 🤗 Datasets, check! - - local: chapter5/8 - title: End-of-chapter quiz - quiz: 5 - -- title: 6. The 🤗 Tokenizers library - sections: - - local: chapter6/1 - title: Introduction - - local: chapter6/2 - title: Training a new tokenizer from an old one - - local: chapter6/3 - title: Fast tokenizers' special powers - - local: chapter6/3b - title: Fast tokenizers in the QA pipeline - - local: chapter6/4 - title: Normalization and pre-tokenization - - local: chapter6/5 - title: Byte-Pair Encoding tokenization - - local: chapter6/6 - title: WordPiece tokenization - - local: chapter6/7 - title: Unigram tokenization - - local: chapter6/8 - title: Building a tokenizer, block by block - - local: chapter6/9 - title: Tokenizers, check! - - local: chapter6/10 - title: End-of-chapter quiz - quiz: 6 - -- title: 7. Main NLP tasks - sections: - - local: chapter7/1 - title: Introduction - - local: chapter7/2 - title: Token classification - - local: chapter7/3 - title: Fine-tuning a masked language model - - local: chapter7/4 - title: Translation - - local: chapter7/5 - title: Summarization - - local: chapter7/6 - title: Training a causal language model from scratch - - local: chapter7/7 - title: Question answering - - local: chapter7/8 - title: Mastering NLP - - local: chapter7/9 - title: End-of-chapter quiz - quiz: 7 - -- title: 8. How to ask for help - sections: - - local: chapter8/1 - title: Introduction - - local: chapter8/2 - title: What to do when you get an error - - local: chapter8/3 - title: Asking for help on the forums - - local: chapter8/4 - title: Debugging the training pipeline - local_fw: { pt: chapter8/4, tf: chapter8/4_tf } - - local: chapter8/5 - title: How to write a good issue - - local: chapter8/6 - title: Part 2 completed! - - local: chapter8/7 - title: End-of-chapter quiz - quiz: 8 - -- title: 9. Building and sharing demos - new: true - subtitle: I trained a model, but how can I show it off? - sections: - - local: chapter9/1 - title: Introduction to Gradio - - local: chapter9/2 - title: Building your first demo - - local: chapter9/3 - title: Understanding the Interface class - - local: chapter9/4 - title: Sharing demos with others - - local: chapter9/5 - title: Integrations with the Hugging Face Hub - - local: chapter9/6 - title: Advanced Interface features - - local: chapter9/7 - title: Introduction to Blocks - - local: chapter9/8 - title: Gradio, check! - - local: chapter9/9 - title: End-of-chapter quiz - quiz: 9 - -- title: Course Events - sections: - - local: events/1 - title: Live sessions and workshops - - local: events/2 - title: Part 2 release event - - local: events/3 - title: Gradio Blocks party diff --git a/chapters/ru/.ipynb_checkpoints/_toctree-checkpoint.yml b/chapters/ru/.ipynb_checkpoints/_toctree-checkpoint.yml deleted file mode 100644 index 46b889425..000000000 --- a/chapters/ru/.ipynb_checkpoints/_toctree-checkpoint.yml +++ /dev/null @@ -1,204 +0,0 @@ -- title: 0. Установка - sections: - - local: chapter0/1 - title: Введение - -- title: 1. Трансформеры - sections: - - local: chapter1/1 - title: Введение - - local: chapter1/2 - title: Обработка естественного языка - - local: chapter1/3 - title: "Трансформеры: на что они способны?" - - local: chapter1/4 - title: Как работают трансформеры? - - local: chapter1/5 - title: Модели-кодировщики - - local: chapter1/6 - title: Модели-декодировщики - - local: chapter1/7 - title: Модели "seq2seq" - - local: chapter1/8 - title: Предвзятости и ограничения - - local: chapter1/9 - title: Итоги - - local: chapter1/10 - title: Проверка знаний - -- title: 2. Использование 🤗 Transformers - sections: - - local: chapter2/1 - title: Введение - - local: chapter2/2 - title: За конвейером - - local: chapter2/3 - title: Модели - - local: chapter2/4 - title: Токенизаторы - - local: chapter2/5 - title: Обработка множественных последовательностей - - local: chapter2/6 - title: Собираем все воедино - - local: chapter2/7 - title: Базовое использование завершено! - - local: chapter2/8 - title: Итоговый тест по главе - quiz: 2 - -- title: 3. Fine-tuning предобученной модели - sections: - - local: chapter3/1 - title: Введение - - local: chapter3/2 - title: Предобработка данных - - local: chapter3/3 - title: Fine-tuning модели с использованием Trainer API - local_fw: { pt: chapter3/3, tf: chapter3/3_tf } - - local: chapter3/4 - title: Полное обучение модели - - local: chapter3/5 - title: Fine-tuning, итоги! - - local: chapter3/6 - title: Итоговый тест по главе - quiz: 3 - -- title: 4. Hugging Face Hub - sections: - - local: chapter4/1 - title: Hugging Face Hub - - local: chapter4/2 - title: Использование предобученных моделей - - local: chapter4/3 - title: Публикация предобученных моделей в общий доступ - - local: chapter4/4 - title: Создание карточки модели - - local: chapter4/5 - title: Первая часть завершена! - - local: chapter4/6 - title: Итоговый тест по главе - quiz: 4 - -- title: 5. Библиотека 🤗 Datasets - sections: - - local: chapter5/1 - title: Введение - - local: chapter5/2 - title: Что делать, если моего датасета на нет на Hub? - - local: chapter5/3 - title: Препарируем 🤗 Datasets - - local: chapter5/4 - title: Big data? 🤗 Datasets спешат на помощь! - - local: chapter5/6 - title: Семантический поиск с помощью FAISS - - local: chapter5/7 - title: 🤗 Datasets, итоги! - - local: chapter5/8 - title: Тест по главе 5 - -- title: 6. Бибилиотека 🤗 Tokenizers - sections: - - local: chapter6/1 - title: Введение - - local: chapter6/2 - title: Обучение нового токенизатора на основе старого - - local: chapter6/3 - title: Особые возможности быстрых токенизаторов - - local: chapter6/3b - title: Быстрые токенизаторы в QA конвейере - - local: chapter6/4 - title: Нормализация и предварительная токенизация - - local: chapter6/5 - title: Токенизация Byte-Pair Encoding - - local: chapter6/6 - title: Токенизация WordPiece - - local: chapter6/7 - title: Токенизация Unigram - - local: chapter6/8 - title: Создание токенизатора, блок за блоком - - local: chapter6/9 - title: Токенизаторы, проверка! - - local: chapter6/10 - title: Тест в конце главы - quiz: 6 - -- title: 7. Основные задачи NLP - sections: - - local: chapter7/1 - title: Введение - - local: chapter7/2 - title: Классификация токенов - - local: chapter7/3 - title: Дообучение модели маскированного языкового моделирования - - local: chapter7/4 - title: Перевод - - local: chapter7/5 - title: Суммаризация - - local: chapter7/6 - title: Обучение каузальной языковой модели с нуля - - local: chapter7/7 - title: Ответы на вопросы - - local: chapter7/8 - title: Освоение NLP - - local: chapter7/9 - title: Тест в конце главы - quiz: 7 - -- title: 8. Как попросить о помощи - sections: - - local: chapter8/1 - title: Введение - - local: chapter8/2 - title: Что делать, если возникла ошибка - - local: chapter8/3 - title: Обращение за помощью на форумах - - local: chapter8/4_tf - title: Отладка обучения - - local: chapter8/4 - title: Отладка обучения - local_fw: { pt: chapter8/4, tf: chapter8/4_tf } - - local: chapter8/5 - title: Как написать хорошее сообщение об ошибке (issue) - - local: chapter8/6 - title: Часть 2 завершена! - - local: chapter8/7 - title: Тест в конце главы - quiz: 8 - -- title: 9. Создание и распространение демо - new: true - subtitle: Я обучил модель, но как мне ее продемонстрировать? - sections: - - local: chapter9/1 - title: Введение в Gradio - - local: chapter9/2 - title: Создание вашего первого демо - - local: chapter9/3 - title: Понимание класса Interface - - local: chapter9/4 - title: Делимся демонстрациями с другими - - local: chapter9/5 - title: Интеграция с Hugging Face Hub - - local: chapter9/6 - title: Расширенные возможности Interface - - local: chapter9/7 - title: Введение в Gradio Blocks - - local: chapter9/8 - title: Gradio, проверка! - - local: chapter9/9 - title: Тест в конце главы - quiz: 9 - -- title: События курса - sections: - - local: events/1 - title: Встречи и семинары - - local: events/2 - title: Событие посвященное выходу 2 части курса - - local: events/3 - title: Вечеринка Gradio Blocks - -- title: Глоссарий - sections: - - local: glossary/1 - title: Глоссарий diff --git a/chapters/ru/chapter2/.ipynb_checkpoints/1-checkpoint.mdx b/chapters/ru/chapter2/.ipynb_checkpoints/1-checkpoint.mdx deleted file mode 100644 index 94add379c..000000000 --- a/chapters/ru/chapter2/.ipynb_checkpoints/1-checkpoint.mdx +++ /dev/null @@ -1,25 +0,0 @@ -# Введение[[introduction]] - - - -Как вы видели в [Главе 1](../chapter1), модели трансформеров обычно очень большие. С миллионами и десятками *миллиардов* параметров, обучение и развертывание этих моделей - сложная задача. Кроме того, поскольку новые модели выходят практически ежедневно и каждая из них имеет свою собственную реализацию, попробовать их все - задача не из легких. - -Для решения этой проблемы была создана библиотека 🤗 Transformers. Ее цель - предоставить единый API, с помощью которого можно загрузить, обучить и сохранить любую модель Transformer. Основными особенностями библиотеки являются: - -- **Простота использования**: Скачать, загрузить и использовать современную модель NLP для инференса можно всего в две строчки кода. -- **Гибкость**: По своей сути все модели представляют собой простые классы PyTorch `nn.Module` или TensorFlow `tf.keras.Model` и могут быть обработаны как любые другие модели в соответствующих фреймворках машинного обучения (ML). -- **Простота**: В библиотеке почти нет абстракций. Концепция "Все в одном файле" является основной: прямой проход модели полностью определяется в одном файле, так что сам код понятен и доступен для изменения. - -Эта последняя особенность делает 🤗 Transformers совершенно непохожей на другие ML-библиотеки. Модели не строятся на основе модулей -которые совместно используются в разных файлах; вместо этого каждая модель имеет свои собственные слои. Помимо того, что это делает модели более доступными и понятными, это позволяет легко экспериментировать с одной моделью, не затрагивая другие. - -Эта глава начнется со сквозного примера, в котором мы используем модель и токенизатор вместе, чтобы воссоздать функцию `pipeline()`, представленную в [Главе 1](../chapter1). Далее мы обсудим API модели: мы погрузимся в модель и классы конфигурации, покажем, как загрузить модель и как она обрабатывает числовые данные для вывода прогнозов. - -Затем мы рассмотрим API токенизатора, который является другим основным компонентом функции `pipeline()`. Токенизаторы берут на себя первый и последний шаги препроцессинга, обработку преобразования текста в числовые входы для нейронной сети и обратное преобразование в текст, когда это необходимо. Наконец, мы покажем вам, как обрабатывать несколько предложений, передавая их в модель в подготовленном батче, затем завершим все это более подробным рассмотрением высокоуровневой функции `tokenizer()`. - - -⚠️ Чтобы воспользоваться всеми возможностями, доступными в Model Hub и 🤗 Transformers, мы рекомендуем создать учетную запись. - \ No newline at end of file diff --git a/chapters/ru/chapter2/.ipynb_checkpoints/2-checkpoint.mdx b/chapters/ru/chapter2/.ipynb_checkpoints/2-checkpoint.mdx deleted file mode 100644 index baa4fdc28..000000000 --- a/chapters/ru/chapter2/.ipynb_checkpoints/2-checkpoint.mdx +++ /dev/null @@ -1,353 +0,0 @@ - - -# За конвейером[[behind-the-pipeline]] - -{#if fw === 'pt'} - - - -{:else} - - - -{/if} - - -Это первый раздел, в котором содержание немного отличается в зависимости от того, используете ли вы PyTorch или TensorFlow. Переключите переключатель в верхней части заголовка, чтобы выбрать платформу, которую вы предпочитаете! - - -{#if fw === 'pt'} - -{:else} - -{/if} - -Давайте начнем с полноценного примера и посмотрим, что произошло за кулисами, когда мы выполнили следующий код в [Главе 1](../chapter1): - -```python -from transformers import pipeline - -classifier = pipeline("sentiment-analysis") -classifier( - [ - "I've been waiting for a HuggingFace course my whole life.", - "I hate this so much!", - ] -) -``` - -и получил: - -```python out -[{'label': 'POSITIVE', 'score': 0.9598047137260437}, - {'label': 'NEGATIVE', 'score': 0.9994558095932007}] -``` - -Как мы видели в [Главе 1] (../chapter1), этот конвейер объединяет три этапа: предобработку, пропуск входных данных через модель и постобработку: - -
-The full NLP pipeline: tokenization of text, conversion to IDs, and inference through the Transformer model and the model head. - -
- -Давайте быстро пройдемся по каждому из них. - -## Предобработка с помощью токенизатора[[preprocessing-with-a-tokenizer]] - -Как и другие нейронные сети, модели Transformer не могут напрямую обрабатывать сырой текст, поэтому первым шагом нашего конвейера является преобразование текстовых данных в числа, которые сможет воспринимать модель. Для этого мы используем *токенизатор*, который будет отвечать за: - -- Разбиение входных данных на слова, подслова или символы (например, пунктуацию), которые называются *токенами* -- Сопоставление каждого токена с целым числом -- Добавление дополнительных входных данных, которые могут быть полезны для модели - -Вся эта предобработка должна быть выполнена точно так же, как и при предварительном обучении модели, поэтому сначала нам нужно загрузить эту информацию из [Model Hub](https://huggingface.co/models). Для этого мы используем класс `AutoTokenizer` и его метод `from_pretrained()`. Используя имя контрольной точки нашей модели, он автоматически получает данные, ассоциированные с токенизатором модели, и кэширует их (таким образом, они скачиваются только в первый раз, когда вы выполняете приведенный ниже код). - -Поскольку контрольной точкой по умолчанию конвейера `sentiment-analysis` является `distilbert-base-uncased-finetuned-sst-2-english` (вы можете посмотреть ее карточку модели [здесь](https://huggingface.co/distilbert-base-uncased-finetuned-sst-2-english)), мы выполняем следующее: - -```python -from transformers import AutoTokenizer - -checkpoint = "distilbert-base-uncased-finetuned-sst-2-english" -tokenizer = AutoTokenizer.from_pretrained(checkpoint) -``` - -Когда у нас есть токенизатор, мы можем напрямую передать ему наши предложения и получить в ответ словарь, готовый к передаче в нашу модель! Осталось только преобразовать список входных идентификаторов в тензоры. - -Вы можете использовать 🤗 Transformers, не задумываясь о том, какой ML-фреймворк используется в качестве бэкенда; это может быть PyTorch или TensorFlow, или Flax для некоторых моделей. Однако модели Transformer принимают на вход только *тензоры*. Если вы впервые слышите о тензорах, то можете считать их массивами NumPy. Массив NumPy может быть скаляром (0D), вектором (1D), матрицей (2D) или иметь больше измерений. По сути, это тензор; тензоры других ML-фреймворков ведут себя аналогично, и их обычно так же просто инстанцировать, как и массивы NumPy. - -Чтобы указать тип тензоров, которые мы хотим получить в ответ (PyTorch, TensorFlow или обычный NumPy), мы используем аргумент `return_tensors`: - -{#if fw === 'pt'} -```python -raw_inputs = [ - "I've been waiting for a HuggingFace course my whole life.", - "I hate this so much!", -] -inputs = tokenizer(raw_inputs, padding=True, truncation=True, return_tensors="pt") -print(inputs) -``` -{:else} -```python -raw_inputs = [ - "I've been waiting for a HuggingFace course my whole life.", - "I hate this so much!", -] -inputs = tokenizer(raw_inputs, padding=True, truncation=True, return_tensors="tf") -print(inputs) -``` -{/if} - -Не беспокойтесь пока о дополнении и усечении, мы расскажем об этом позже. Главное, что нужно запомнить: вы можете передать одно предложение или список предложений, а также указать тип тензоров, которые вы хотите получить в ответ (если тип не указан, то в результате вы получите список списков). - -{#if fw === 'pt'} - -Вот как выглядят результаты в виде тензоров PyTorch: - -```python out -{ - 'input_ids': tensor([ - [ 101, 1045, 1005, 2310, 2042, 3403, 2005, 1037, 17662, 12172, 2607, 2026, 2878, 2166, 1012, 102], - [ 101, 1045, 5223, 2023, 2061, 2172, 999, 102, 0, 0, 0, 0, 0, 0, 0, 0] - ]), - 'attention_mask': tensor([ - [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], - [1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0] - ]) -} -``` -{:else} - -Вот как выглядят результаты в виде тензоров TensorFlow: - -```python out -{ - 'input_ids': , - 'attention_mask': -} -``` -{/if} - -Сам результат представляет собой словарь, содержащий два ключа, `input_ids` и `attention_mask`. `input_ids` содержит две строки целых чисел (по одной на каждое предложение), которые являются уникальными идентификаторами токенов в каждом предложении. Мы объясним, что такое `attention_mask` позже в этой главе. - -## Проходя сквозь модель[[going-through-the-model]] - -{#if fw === 'pt'} -Мы можем загрузить нашу предварительно обученную модель так же, как мы это делали с нашим токенизатором. 🤗 Transformers предоставляет класс `AutoModel`, у которого также есть метод `from_pretrained()`: - -```python -from transformers import AutoModel - -checkpoint = "distilbert-base-uncased-finetuned-sst-2-english" -model = AutoModel.from_pretrained(checkpoint) -``` -{:else} -Мы можем загрузить нашу предварительно обученную модель так же, как мы это делали с нашим токенизатором. 🤗 Transformers предоставляет класс `TFAutoModel`, в котором также есть метод `from_pretrained`: - -```python -from transformers import TFAutoModel - -checkpoint = "distilbert-base-uncased-finetuned-sst-2-english" -model = TFAutoModel.from_pretrained(checkpoint) -``` -{/if} - -В этом фрагменте кода мы загрузили ту же контрольную точку, которую использовали в нашем конвейере ранее (на самом деле она уже должна была быть кэширована), и инстанцировали модель с ее помощью. - -Эта архитектура содержит только базовый модуль Transformer: при наличии некоторых входных данных он выводит то, что мы будем называть *скрытыми состояниями (hidden states)*, также известными как *признаки (features)*. Для каждого входа модели мы получим высокоразмерный вектор, представляющий **контекстное понимание этого входа моделью Transformer**. - -Если вы не поняли смысла, не волнуйтесь. Мы объясним всё это позже. - -Хотя эти скрытые состояния могут быть полезны сами по себе, обычно они являются входными данными для другой части модели, известной как *голова (head)*. В [Главе 1](../chapter1) различные задачи могли быть выполнены с помощью одной и той же архитектуры, но каждая из этих задач будет связана с разной головой. - -### Многомерный вектор?[[a-high-dimensional-vector]] - -Вектор, возвращаемый модулем Transformer, обычно большой. Обычно он имеет три измерения: - -- **Размер батча (Batch size)**: Количество последовательностей, обрабатываемых за один раз (в нашем примере - 2). -- **Длина последовательности (Sequence length)**: Длина числового представления последовательности (в нашем примере - 16). -- **Скрытый размер (Hidden size)**: Размерность вектора каждого входа модели. - -О нем говорят как о "высокоразмерном" из-за последнего значения. Скрытый размер может быть очень большим (768 - обычное явление для небольших моделей, а в больших моделях он может достигать 3072 и более). - -Мы можем убедиться в этом, если подадим в нашу модель входные данные, которые мы подвергли предобработке: - -{#if fw === 'pt'} -```python -outputs = model(**inputs) -print(outputs.last_hidden_state.shape) -``` - -```python out -torch.Size([2, 16, 768]) -``` -{:else} -```py -outputs = model(inputs) -print(outputs.last_hidden_state.shape) -``` - -```python out -(2, 16, 768) -``` -{/if} - -Обратите внимание, что выходы моделей 🤗 Transformers ведут себя как `namedtuple` или словари. Вы можете обращаться к элементам по атрибутам (как мы это делали), по ключу (`outputs["last_hidden_state"]`) или даже по индексу, если вы точно знаете, где находится искомый элемент (`outputs[0]`). - -### Головы моделей: Извлечение смысла из чисел[[model-heads-making-sense-out-of-numbers]] - -Головы модели принимают на вход высокоразмерный вектор скрытых состояний и проецируют его на другое измерение. Обычно они состоят из одного или нескольких линейных слоев: - -
-A Transformer network alongside its head. - -
- -Выход модели Transformer передается непосредственно в головку модели для обработки. - -На этой диаграмме модель представлена слоем эмбеддингов и последующими слоями. Слой эмбеддингов преобразует каждый входной идентификатор в токенизированном входе в вектор, который представляет соответствующий токен. Последующие слои манипулируют этими векторами с помощью механизма внимания, чтобы получить окончательное представление предложений. - -Существует множество различных архитектур 🤗 Transformers, каждая из которых предназначена для решения определенной задачи. Вот неполный список: - -- `*Model` (извлечение скрытых состояний) -- `*ForCausalLM` -- `*ForMaskedLM` -- `*ForMultipleChoice` -- `*ForQuestionAnswering` -- `*ForSequenceClassification` -- `*ForTokenClassification` -- и другие 🤗 - -{#if fw === 'pt'} -Для нашего примера нам понадобится модель с головой классификации последовательности (чтобы иметь возможность классифицировать предложения как положительные или отрицательные). Поэтому мы будем использовать не класс `AutoModel`, а `AutoModelForSequenceClassification`: - -```python -from transformers import AutoModelForSequenceClassification - -checkpoint = "distilbert-base-uncased-finetuned-sst-2-english" -model = AutoModelForSequenceClassification.from_pretrained(checkpoint) -outputs = model(**inputs) -``` -{:else} -Для нашего примера нам понадобится модель с головой классификации последовательности (чтобы иметь возможность классифицировать предложения как положительные или отрицательные). Поэтому мы будем использовать не класс `TFAutoModel`, а `TFAutoModelForSequenceClassification`: - -```python -from transformers import TFAutoModelForSequenceClassification - -checkpoint = "distilbert-base-uncased-finetuned-sst-2-english" -model = TFAutoModelForSequenceClassification.from_pretrained(checkpoint) -outputs = model(inputs) -``` -{/if} - -Теперь, если мы посмотрим на форму наших выходов, размерность будет гораздо ниже: голова модели принимает на вход высокоразмерные векторы, которые мы видели ранее, и возвращает векторы, содержащие два значения (по одному на метку): - -```python -print(outputs.logits.shape) -``` - -{#if fw === 'pt'} -```python out -torch.Size([2, 2]) -``` -{:else} -```python out -(2, 2) -``` -{/if} - -Поскольку у нас всего два предложения и две метки, результат, полученный с помощью нашей модели, имеет форму 2 x 2. - -## Постобработка вывода[[postprocessing-the-output]] - -Значения, которые мы получаем на выходе из нашей модели, не всегда имеют смысл сами по себе. Давайте посмотрим: - -```python -print(outputs.logits) -``` - -{#if fw === 'pt'} -```python out -tensor([[-1.5607, 1.6123], - [ 4.1692, -3.3464]], grad_fn=) -``` -{:else} -```python out - -``` -{/if} - -Наша модель спрогнозировала `[-1.5607, 1.6123]` для первого предложения и `[ 4.1692, -3.3464]` для второго. Это не вероятности, а *логиты*, сырые, ненормированные оценки, выведенные последним слоем модели. Чтобы преобразовать их в вероятности, они должны пройти через слой [SoftMax](https://en.wikipedia.org/wiki/Softmax_function) (все модели 🤗 Transformers выводят логиты, поскольку функция потерь для обучения обычно объединяет последнюю функцию активации, такую как SoftMax, с фактической функцией потерь, такой как кросс-энтропия): - -{#if fw === 'pt'} -```py -import torch - -predictions = torch.nn.functional.softmax(outputs.logits, dim=-1) -print(predictions) -``` -{:else} -```py -import tensorflow as tf - -predictions = tf.math.softmax(outputs.logits, axis=-1) -print(predictions) -``` -{/if} - -{#if fw === 'pt'} -```python out -tensor([[4.0195e-02, 9.5980e-01], - [9.9946e-01, 5.4418e-04]], grad_fn=) -``` -{:else} -```python out -tf.Tensor( -[[4.01951671e-02 9.59804833e-01] - [9.9945587e-01 5.4418424e-04]], shape=(2, 2), dtype=float32) -``` -{/if} - -Теперь мы видим, что модель спрогнозировала `[0.0402, 0.9598]` для первого предложения и `[0.9995, 0.0005]` для второго. Это узнаваемые оценки вероятности. - -Чтобы получить метки, соответствующие каждой позиции, мы можем обратиться к атрибуту `id2label` в конфигурации модели ( более подробно об этом в следующем разделе): - -```python -model.config.id2label -``` - -```python out -{0: 'NEGATIVE', 1: 'POSITIVE'} -``` - -Теперь мы можем сделать вывод, что модель спрогнозировала следующее: - -- Первое предложение: NEGATIVE: 0.0402, POSITIVE: 0.9598 -- Второе предложение: NEGATIVE: 0.9995, POSITIVE: 0.0005 - -Мы успешно воспроизвели три этапа конвейера: предобработку с помощью токенизаторов, прохождение входных данных через модель и постобработку! Теперь давайте уделим немного времени тому, чтобы углубиться в каждый из этих этапов. - - - -✏️ **Попробуйте! ** Выберите два (или более) собственных текста и пропустите их через конвейер `sentiment-analysis`. Затем повторите описанные здесь шаги и убедитесь, что вы получили те же результаты! - - diff --git a/chapters/ru/chapter2/3.mdx b/chapters/ru/chapter2/3.mdx index acc653704..56f2b19d9 100644 --- a/chapters/ru/chapter2/3.mdx +++ b/chapters/ru/chapter2/3.mdx @@ -1,6 +1,6 @@ -# Models[[models]] +# Модели[[models]] {#if fw === 'pt'} @@ -29,46 +29,46 @@ {/if} {#if fw === 'pt'} -In this section we'll take a closer look at creating and using a model. We'll use the `AutoModel` class, which is handy when you want to instantiate any model from a checkpoint. +В этом разделе мы подробно рассмотрим создание и использование модели. Мы будем использовать класс `AutoModel`, который удобен, когда вы хотите инстанцировать любую модель из контрольной точки. -The `AutoModel` class and all of its relatives are actually simple wrappers over the wide variety of models available in the library. It's a clever wrapper as it can automatically guess the appropriate model architecture for your checkpoint, and then instantiates a model with this architecture. +Класс `AutoModel` и все его представители на самом деле являются простыми обертками для широкого спектра моделей, доступных в библиотеке. Это умная обертка, поскольку она может автоматически определить архитектуру модели, подходящую для вашей контрольной точки, а затем инстанцировать модель с этой архитектурой. {:else} -In this section we'll take a closer look at creating and using a model. We'll use the `TFAutoModel` class, which is handy when you want to instantiate any model from a checkpoint. +В этом разделе мы подробно рассмотрим создание и использование модели. Мы будем использовать класс `TFAutoModel`, который удобен, когда вы хотите инстанцировать любую модель из контрольной точки. -The `TFAutoModel` class and all of its relatives are actually simple wrappers over the wide variety of models available in the library. It's a clever wrapper as it can automatically guess the appropriate model architecture for your checkpoint, and then instantiates a model with this architecture. +Класс `TFAutoModel` и все его родственники на самом деле являются простыми обертками для широкого спектра моделей, доступных в библиотеке. Это умная обертка, поскольку она может автоматически определить подходящую архитектуру модели для вашей контрольной точки, а затем инстанцировать модель с этой архитектурой. {/if} -However, if you know the type of model you want to use, you can use the class that defines its architecture directly. Let's take a look at how this works with a BERT model. +Однако если вы знаете тип модели, которую хотите использовать, вы можете напрямую использовать класс, определяющий ее архитектуру. Давайте рассмотрим, как это работает на примере модели BERT. -## Creating a Transformer[[creating-a-transformer]] +## Создание Transformer[[creating-a-transformer]] -The first thing we'll need to do to initialize a BERT model is load a configuration object: +Первое, что нам нужно сделать для инициализации модели BERT, - загрузить объект конфигурации: {#if fw === 'pt'} ```py from transformers import BertConfig, BertModel -# Building the config +# Создание конфигурации config = BertConfig() -# Building the model from the config +# Создание модели на основе конфигурации model = BertModel(config) ``` {:else} ```py from transformers import BertConfig, TFBertModel -# Building the config +# Создание конфигурации config = BertConfig() -# Building the model from the config +# Создание модели на основе конфигурации model = TFBertModel(config) ``` {/if} -The configuration contains many attributes that are used to build the model: +Конфигурация содержит множество атрибутов, которые используются для создания модели: ```py print(config) @@ -86,11 +86,11 @@ BertConfig { } ``` -While you haven't seen what all of these attributes do yet, you should recognize some of them: the `hidden_size` attribute defines the size of the `hidden_states` vector, and `num_hidden_layers` defines the number of layers the Transformer model has. +Хотя вы еще не видели, что делают все эти атрибуты, вы должны узнать некоторые из них: атрибут `hidden_size` определяет размер вектора `hidden_states`, а `num_hidden_layers` определяет количество слоев в модели Transformer. -### Different loading methods[[different-loading-methods]] +### Различные методы загрузки[[different-loading-methods]] -Creating a model from the default configuration initializes it with random values: +При создании модели из конфигурации по умолчанию она инициализируется случайными значениями: {#if fw === 'pt'} ```py @@ -99,7 +99,7 @@ from transformers import BertConfig, BertModel config = BertConfig() model = BertModel(config) -# Model is randomly initialized! +# Модель инициализируется случайным образом!! ``` {:else} ```py @@ -108,13 +108,13 @@ from transformers import BertConfig, TFBertModel config = BertConfig() model = TFBertModel(config) -# Model is randomly initialized! +# Модель инициализируется случайным образом! ``` {/if} -The model can be used in this state, but it will output gibberish; it needs to be trained first. We could train the model from scratch on the task at hand, but as you saw in [Chapter 1](/course/chapter1), this would require a long time and a lot of data, and it would have a non-negligible environmental impact. To avoid unnecessary and duplicated effort, it's imperative to be able to share and reuse models that have already been trained. +Модель можно использовать и в таком состоянии, но она будет выдавать тарабарщину; сначала ее нужно обучить. Мы могли бы обучить модель с нуля для конкретной задачи, но, как вы видели в [Главе 1](../chapter1), это потребовало бы много времени и большого количества данных, а также оказало бы немалое влияние на окружающую среду. Чтобы избежать ненужных и дублирующих усилий, крайне важно иметь возможность обмениваться уже обученными моделями и повторно их использовать. -Loading a Transformer model that is already trained is simple — we can do this using the `from_pretrained()` method: +Загрузить уже обученную модель Transformer очень просто - мы можем сделать это с помощью метода `from_pretrained()`: {#if fw === 'pt'} ```py @@ -123,7 +123,7 @@ from transformers import BertModel model = BertModel.from_pretrained("bert-base-cased") ``` -As you saw earlier, we could replace `BertModel` with the equivalent `AutoModel` class. We'll do this from now on as this produces checkpoint-agnostic code; if your code works for one checkpoint, it should work seamlessly with another. This applies even if the architecture is different, as long as the checkpoint was trained for a similar task (for example, a sentiment analysis task). +Как вы видели ранее, мы можем заменить `BertModel` на эквивалентный класс `AutoModel`. В дальнейшем мы будем поступать именно так, поскольку таким образом мы получаем код, не зависящий от контрольных точек; если ваш код работает на одной контрольной точке, он должен без проблем работать и на другой. Это касается даже разных архитектур, если контрольная точка была обучена для схожей задачи (например, задачи анализа настроений). {:else} ```py @@ -132,27 +132,27 @@ from transformers import TFBertModel model = TFBertModel.from_pretrained("bert-base-cased") ``` -As you saw earlier, we could replace `TFBertModel` with the equivalent `TFAutoModel` class. We'll do this from now on as this produces checkpoint-agnostic code; if your code works for one checkpoint, it should work seamlessly with another. This applies even if the architecture is different, as long as the checkpoint was trained for a similar task (for example, a sentiment analysis task). +Как вы видели ранее, мы можем заменить `TFBertModel` на эквивалентный класс `TFAutoModel`. В дальнейшем мы будем поступать именно так, поскольку таким образом мы получаем код, не зависящий от контрольных точек; если ваш код работает на одной контрольной точке, он должен без проблем работать и на другой. Это касается даже разных архитектур, если контрольная точка была обучена для схожей задачи (например, задачи анализа настроений). {/if} -In the code sample above we didn't use `BertConfig`, and instead loaded a pretrained model via the `bert-base-cased` identifier. This is a model checkpoint that was trained by the authors of BERT themselves; you can find more details about it in its [model card](https://huggingface.co/bert-base-cased). +В приведенном выше примере кода мы не использовали `BertConfig`, а вместо этого загрузили предварительно обученную модель через идентификатор `bert-base-cased`. Это контрольная точка модели, которая была обучена самими авторами BERT; более подробную информацию о ней можно найти в ее [карточке модели](https://huggingface.co/bert-base-cased). -This model is now initialized with all the weights of the checkpoint. It can be used directly for inference on the tasks it was trained on, and it can also be fine-tuned on a new task. By training with pretrained weights rather than from scratch, we can quickly achieve good results. +Теперь эта модель инициализирована всеми весами контрольной точки. Ее можно использовать непосредственно для инференса на задачах, для которых она была обучена, а также для дообучения на новой задаче. Обучаясь с предварительно подготовленными весами, а не с нуля, мы можем быстро добиться хороших результатов. -The weights have been downloaded and cached (so future calls to the `from_pretrained()` method won't re-download them) in the cache folder, which defaults to *~/.cache/huggingface/transformers*. You can customize your cache folder by setting the `HF_HOME` environment variable. +Веса были загружены и кэшированы (чтобы последующие вызовы метода `from_pretrained()` не загружали их заново) в папке кэша, которая по умолчанию находится в *~/.cache/huggingface/transformers*. Вы можете настроить папку кэша, установив переменную окружения `HF_HOME`. -The identifier used to load the model can be the identifier of any model on the Model Hub, as long as it is compatible with the BERT architecture. The entire list of available BERT checkpoints can be found [here](https://huggingface.co/models?filter=bert). +Идентификатор, используемый для загрузки модели, может быть идентификатором любой модели на Model Hub, если она совместима с архитектурой BERT. Полный список доступных контрольных точек BERT можно найти [здесь](https://huggingface.co/models?filter=bert). -### Saving methods[[saving-methods]] +### Методы сохранения[[saving-methods]] -Saving a model is as easy as loading one — we use the `save_pretrained()` method, which is analogous to the `from_pretrained()` method: +Сохранить модель так же просто, как и загрузить ее - мы используем метод `save_pretrained()`, который аналогичен методу `from_pretrained()`: ```py model.save_pretrained("directory_on_my_computer") ``` -This saves two files to your disk: +При этом на диск сохраняются два файла: {#if fw === 'pt'} ``` @@ -168,29 +168,29 @@ config.json tf_model.h5 ``` {/if} -If you take a look at the *config.json* file, you'll recognize the attributes necessary to build the model architecture. This file also contains some metadata, such as where the checkpoint originated and what 🤗 Transformers version you were using when you last saved the checkpoint. +Если вы посмотрите на файл *config.json*, то узнаете атрибуты, необходимые для построения архитектуры модели. Этот файл также содержит некоторые метаданные, такие как место создания контрольной точки и версию 🤗 Transformers, которую вы использовали при последнем сохранении контрольной точки. {#if fw === 'pt'} -The *pytorch_model.bin* file is known as the *state dictionary*; it contains all your model's weights. The two files go hand in hand; the configuration is necessary to know your model's architecture, while the model weights are your model's parameters. +Файл *pytorch_model.bin* известен как *словарь состояний (state dictionary)*; он содержит все веса вашей модели. Эти два файла неразрывно связаны друг с другом; конфигурация необходима для того, чтобы знать архитектуру модели, а веса модели - это ее параметры. {:else} -The *tf_model.h5* file is known as the *state dictionary*; it contains all your model's weights. The two files go hand in hand; the configuration is necessary to know your model's architecture, while the model weights are your model's parameters. +Файл *tf_model.h5* известен как *словарь состояний (state dictionary)*; он содержит все веса вашей модели. Эти два файла неразрывно связаны друг с другом; конфигурация необходима для того, чтобы знать архитектуру модели, а веса модели - это ее параметры. {/if} -## Using a Transformer model for inference[[using-a-transformer-model-for-inference]] +## Использование модели Transformer для инференса[[using-a-transformer-model-for-inference]] -Now that you know how to load and save a model, let's try using it to make some predictions. Transformer models can only process numbers — numbers that the tokenizer generates. But before we discuss tokenizers, let's explore what inputs the model accepts. +Теперь, когда вы знаете, как загружать и сохранять модель, давайте попробуем использовать ее для прогнозирования. Модели Transformer могут обрабатывать только числа - числа, которые генерирует токенизатор. Но прежде чем мы обсудим токенизаторы, давайте узнаем, какие входные данные (входы) принимает модель. -Tokenizers can take care of casting the inputs to the appropriate framework's tensors, but to help you understand what's going on, we'll take a quick look at what must be done before sending the inputs to the model. +Токенизаторы могут позаботиться о приведении входных данных к тензорам соответствующего фреймворка, но чтобы помочь вам понять, что происходит, мы кратко рассмотрим, что нужно сделать перед передачей входных данных в модель. -Let's say we have a couple of sequences: +Допустим, у нас есть несколько последовательностей: ```py sequences = ["Hello!", "Cool.", "Nice!"] ``` -The tokenizer converts these to vocabulary indices which are typically called *input IDs*. Each sequence is now a list of numbers! The resulting output is: +Токенизатор преобразует их в индексы словаря, которые обычно называются *идентификаторами входов (input IDs)*. Теперь каждая последовательность представляет собой список чисел! В результате на выходе получаем: ```py no-format encoded_sequences = [ @@ -200,7 +200,7 @@ encoded_sequences = [ ] ``` -This is a list of encoded sequences: a list of lists. Tensors only accept rectangular shapes (think matrices). This "array" is already of rectangular shape, so converting it to a tensor is easy: +Это список закодированных последовательностей: список списков. Тензоры принимают только прямоугольную форму (подумайте о матрицах). Этот "массив" уже имеет прямоугольную форму, поэтому преобразовать его в тензор очень просто: {#if fw === 'pt'} ```py @@ -216,13 +216,13 @@ model_inputs = tf.constant(encoded_sequences) ``` {/if} -### Using the tensors as inputs to the model[[using-the-tensors-as-inputs-to-the-model]] +### Использование тензоров в качестве входов в модель[[using-the-tensors-as-inputs-to-the-model]] -Making use of the tensors with the model is extremely simple — we just call the model with the inputs: +Использовать тензоры с моделью очень просто - мы просто вызываем модель с входами: ```py output = model(model_inputs) ``` -While the model accepts a lot of different arguments, only the input IDs are necessary. We'll explain what the other arguments do and when they are required later, -but first we need to take a closer look at the tokenizers that build the inputs that a Transformer model can understand. +Хотя модель принимает множество различных аргументов, только идентификаторы входов являются необходимыми. О том, что делают остальные аргументы и когда они нужны, мы расскажем позже, +но сначала нам нужно подробнее рассмотреть токенизаторы, которые формируют входные данные (входы), которые может понять модель Transformer. diff --git a/chapters/ru/chapter2/4.mdx b/chapters/ru/chapter2/4.mdx index 30167ddbd..1c1a9ce2a 100644 --- a/chapters/ru/chapter2/4.mdx +++ b/chapters/ru/chapter2/4.mdx @@ -1,6 +1,6 @@ -# Tokenizers[[tokenizers]] +# Токенизаторы[[tokenizers]] {#if fw === 'pt'} @@ -24,30 +24,30 @@ -Tokenizers are one of the core components of the NLP pipeline. They serve one purpose: to translate text into data that can be processed by the model. Models can only process numbers, so tokenizers need to convert our text inputs to numerical data. In this section, we'll explore exactly what happens in the tokenization pipeline. +Токенизаторы - один из основных компонентов конвейера NLP. Они служат одной цели: преобразовать текст в данные, которые могут быть обработаны моделью. Модели могут обрабатывать только числа, поэтому токенизаторы должны преобразовывать наш текст в числовые данные. В этом разделе мы рассмотрим, что именно происходит в конвейере токенизации. -In NLP tasks, the data that is generally processed is raw text. Here's an example of such text: +В задачах NLP данные, которые обычно подвергаются обработке, представляют собой необработанный текст. Вот пример такого текста: ``` Jim Henson was a puppeteer ``` -However, models can only process numbers, so we need to find a way to convert the raw text to numbers. That's what the tokenizers do, and there are a lot of ways to go about this. The goal is to find the most meaningful representation — that is, the one that makes the most sense to the model — and, if possible, the smallest representation. +Однако модели могут обрабатывать только числа, поэтому нам нужно найти способ преобразовать исходный текст в числа. Этим занимаются токенизаторы, и существует множество способов сделать это. Цель состоит в том, чтобы найти наиболее осмысленное представление - то есть то, которое имеет наибольший смысл для модели, - и, если возможно, наименьшее представление. -Let's take a look at some examples of tokenization algorithms, and try to answer some of the questions you may have about tokenization. +Давайте рассмотрим несколько примеров алгоритмов токенизации и постараемся ответить на некоторые вопросы, которые могут у вас возникнуть по токенизации. -## Word-based[[word-based]] +## На основе слов[[word-based]] -The first type of tokenizer that comes to mind is _word-based_. It's generally very easy to set up and use with only a few rules, and it often yields decent results. For example, in the image below, the goal is to split the raw text into words and find a numerical representation for each of them: +Первый тип токенайзера, который приходит на ум, - это _на основе слов (word-based)_. Как правило, ее очень легко настроить и использовать с помощью всего нескольких правил, и она часто дает достойные результаты. Например, на изображении ниже цель состоит в том, чтобы разбить исходный текст на слова и найти для каждого из них числовое представление:
An example of word-based tokenization.
-There are different ways to split the text. For example, we could use whitespace to tokenize the text into words by applying Python's `split()` function: +Разделить текст можно разными способами. Например, мы можем использовать пробельные символы, чтобы разделить текст на слова, применив функцию Python `split()`: ```py tokenized_text = "Jim Henson was a puppeteer".split() @@ -58,72 +58,72 @@ print(tokenized_text) ['Jim', 'Henson', 'was', 'a', 'puppeteer'] ``` -There are also variations of word tokenizers that have extra rules for punctuation. With this kind of tokenizer, we can end up with some pretty large "vocabularies," where a vocabulary is defined by the total number of independent tokens that we have in our corpus. +Существуют также разновидности токенизаторов слов, которые содержат дополнительные правила для пунктуации. Используя такой токенизатор, мы можем получить довольно большие "словари", где словарь определяется общим количеством независимых токенов, которые есть в нашем корпусе. -Each word gets assigned an ID, starting from 0 and going up to the size of the vocabulary. The model uses these IDs to identify each word. +Каждому слову присваивается идентификатор, начиная с 0 и заканчивая размером словаря. Модель использует эти идентификаторы для идентификации каждого слова. -If we want to completely cover a language with a word-based tokenizer, we'll need to have an identifier for each word in the language, which will generate a huge amount of tokens. For example, there are over 500,000 words in the English language, so to build a map from each word to an input ID we'd need to keep track of that many IDs. Furthermore, words like "dog" are represented differently from words like "dogs", and the model will initially have no way of knowing that "dog" and "dogs" are similar: it will identify the two words as unrelated. The same applies to other similar words, like "run" and "running", which the model will not see as being similar initially. +Если мы хотим полностью покрыть язык с помощью токенизатора, основанного на словах, нам понадобится идентификатор для каждого слова в языке, что приведет к созданию огромного количества токенов. Например, в английском языке более 500 000 слов, поэтому, чтобы построить карту соответствия каждого слова входному идентификатору, нам нужно будет отслеживать такое количество идентификаторов. Кроме того, такие слова, как "dog", представляются иначе, чем слова типа "dogs", и модель изначально не будет знать, что "dog" и "dogs" похожи: она определит эти два слова как несвязанные. То же самое относится и к другим похожим словам, например "run" и "running", которые модель изначально не будет воспринимать как похожие. -Finally, we need a custom token to represent words that are not in our vocabulary. This is known as the "unknown" token, often represented as "[UNK]" or "<unk>". It's generally a bad sign if you see that the tokenizer is producing a lot of these tokens, as it wasn't able to retrieve a sensible representation of a word and you're losing information along the way. The goal when crafting the vocabulary is to do it in such a way that the tokenizer tokenizes as few words as possible into the unknown token. +Наконец, нам нужен специальный токен для обозначения слов, которых нет в нашем словаре. Это так называемый "unknown" токен, часто представляемый как "[UNK]" или "<unk>". Обычно это плохой знак, если вы видите, что токенизатор выдает много таких токенов, поскольку он не смог получить разумное представление слова, и вы теряете информацию на этом этапе. При создании словаря целью является сделать это таким образом, чтобы токенизатор как можно меньше слов токенизировал как неизвестный токен. -One way to reduce the amount of unknown tokens is to go one level deeper, using a _character-based_ tokenizer. +Один из способов уменьшить количество неизвестных токенов - это пойти на один уровень глубже, используя _основанный на символах (character-based)_ токенизатор. -## Character-based[[character-based]] +## На основе символов[[character-based]] -Character-based tokenizers split the text into characters, rather than words. This has two primary benefits: +Токенизаторы на основе символов (character-based) разбивают текст на символы, а не на слова. Это дает два основных преимущества: -- The vocabulary is much smaller. -- There are much fewer out-of-vocabulary (unknown) tokens, since every word can be built from characters. +- Словарь намного меньше. +- Неизвестных токенов гораздо меньше, поскольку каждое слово может быть образовано из символов. -But here too some questions arise concerning spaces and punctuation: +Но и здесь возникают некоторые вопросы, связанные с пробелами и пунктуацией:
An example of character-based tokenization.
-This approach isn't perfect either. Since the representation is now based on characters rather than words, one could argue that, intuitively, it's less meaningful: each character doesn't mean a lot on its own, whereas that is the case with words. However, this again differs according to the language; in Chinese, for example, each character carries more information than a character in a Latin language. +Такой подход тоже не идеален. Поскольку представление теперь основано на символах, а не на словах, можно утверждать, что интуитивно оно менее осмысленно: каждый символ сам по себе мало что значит, в то время как в случае со словами это не так. Однако это опять же зависит от языка: например, в Китайском языке каждый символ несет больше информации, чем символ в латинском языке. -Another thing to consider is that we'll end up with a very large amount of tokens to be processed by our model: whereas a word would only be a single token with a word-based tokenizer, it can easily turn into 10 or more tokens when converted into characters. +Еще один момент, который следует учитывать, - это то, что в итоге мы получим очень большое количество токенов для обработки нашей моделью: если при использовании токенизатора, основанного на словах, слово будет состоять только из одного токена, то при преобразовании в символы оно может легко превратиться в 10 или более токенов. -To get the best of both worlds, we can use a third technique that combines the two approaches: *subword tokenization*. +Чтобы получить лучшее из обоих миров, мы можем использовать третью технику, которая объединяет эти два подхода: *токенизацию по подсловам (subword tokenization)*. -## Subword tokenization[[subword-tokenization]] +## Токенизация по подсловам[[subword-tokenization]] -Subword tokenization algorithms rely on the principle that frequently used words should not be split into smaller subwords, but rare words should be decomposed into meaningful subwords. +Алгоритмы токенизации подслов (subword tokenization) основываются на принципе, согласно которому часто используемые слова не должны разбиваться на более мелкие подслова, а редкие слова должны быть разложены на значимые подслова. -For instance, "annoyingly" might be considered a rare word and could be decomposed into "annoying" and "ly". These are both likely to appear more frequently as standalone subwords, while at the same time the meaning of "annoyingly" is kept by the composite meaning of "annoying" and "ly". +Например, "annoyingly" может считаться редким словом и может быть разложено на "annoying" и "ly". Оба они, скорее всего, будут чаще появляться как самостоятельные подслова, но в то же время значение " annoyingly" сохраняется за счет составного значения "annoying" и "ly". -Here is an example showing how a subword tokenization algorithm would tokenize the sequence "Let's do tokenization!": +Вот пример, показывающий, как алгоритм токенизации подслов будет токенизировать последовательность "Let's do tokenization!":
A subword tokenization algorithm.
-These subwords end up providing a lot of semantic meaning: for instance, in the example above "tokenization" was split into "token" and "ization", two tokens that have a semantic meaning while being space-efficient (only two tokens are needed to represent a long word). This allows us to have relatively good coverage with small vocabularies, and close to no unknown tokens. +Эти подслова в конечном итоге несут в себе большой семантический смысл: например, в приведенном выше примере "tokenization" было разделено на "token" и "ization" - два токена, которые несут в себе семантический смысл и при этом занимают мало места (для представления длинного слова требуется всего два токена). Это позволяет нам получить относительно хорошее покрытие при небольшом размере словаря и почти полном отсутствии неизвестных токенов. -This approach is especially useful in agglutinative languages such as Turkish, where you can form (almost) arbitrarily long complex words by stringing together subwords. +Этот подход особенно полезен в агглютинативных языках, таких как турецкий, где вы можете образовывать (почти) произвольно длинные сложные слова, соединяя подслова. -### And more![[and-more]] +### И не только![[and-more]] -Unsurprisingly, there are many more techniques out there. To name a few: +Неудивительно, что существует множество других техник. Вот лишь некоторые из них: -- Byte-level BPE, as used in GPT-2 -- WordPiece, as used in BERT -- SentencePiece or Unigram, as used in several multilingual models +- Byte-level BPE, на уровне байтов, используется в GPT-2 +- WordPiece, используемый в BERT +- SentencePiece или Unigram, используемый в нескольких многоязычных моделях -You should now have sufficient knowledge of how tokenizers work to get started with the API. +Теперь у вас должно быть достаточно знаний о том, как работают токенизаторы, чтобы приступить к работе с API. -## Loading and saving[[loading-and-saving]] +## Загрузка и сохранение[[loading-and-saving]] -Loading and saving tokenizers is as simple as it is with models. Actually, it's based on the same two methods: `from_pretrained()` and `save_pretrained()`. These methods will load or save the algorithm used by the tokenizer (a bit like the *architecture* of the model) as well as its vocabulary (a bit like the *weights* of the model). +Загрузка и сохранение токенизаторов так же проста, как и в случае с моделями. Фактически, они основаны на тех же двух методах: `from_pretrained()` и `save_pretrained()`. Эти методы загружают или сохраняют алгоритм, используемый токенизатором (что-то вроде *архитектуры* модели), а также его словарь (что-то вроде *весов* модели). -Loading the BERT tokenizer trained with the same checkpoint as BERT is done the same way as loading the model, except we use the `BertTokenizer` class: +Загрузка токенизатора BERT, обученного на той же контрольной точке, что и BERT, выполняется так же, как и загрузка модели, за исключением того, что мы используем класс `BertTokenizer`: ```py from transformers import BertTokenizer @@ -132,10 +132,10 @@ tokenizer = BertTokenizer.from_pretrained("bert-base-cased") ``` {#if fw === 'pt'} -Similar to `AutoModel`, the `AutoTokenizer` class will grab the proper tokenizer class in the library based on the checkpoint name, and can be used directly with any checkpoint: +Подобно `AutoModel`, класс `AutoTokenizer` будет захватывать нужный класс токенизатора в библиотеке, основываясь на имени контрольной точки, и может быть использован непосредственно с любой контрольной точкой: {:else} -Similar to `TFAutoModel`, the `AutoTokenizer` class will grab the proper tokenizer class in the library based on the checkpoint name, and can be used directly with any checkpoint: +Подобно `TFAutoModel`, класс `AutoTokenizer` захватит нужный класс токенизатора в библиотеке, основываясь на имени контрольной точки, и может быть использован непосредственно с любой контрольной точкой: {/if} @@ -145,7 +145,7 @@ from transformers import AutoTokenizer tokenizer = AutoTokenizer.from_pretrained("bert-base-cased") ``` -We can now use the tokenizer as shown in the previous section: +Теперь мы можем использовать токенизатор, как показано в предыдущем разделе: ```python tokenizer("Using a Transformer network is simple") @@ -157,29 +157,29 @@ tokenizer("Using a Transformer network is simple") 'attention_mask': [1, 1, 1, 1, 1, 1, 1, 1, 1]} ``` -Saving a tokenizer is identical to saving a model: +Сохранение токенизатора идентично сохранению модели: ```py tokenizer.save_pretrained("directory_on_my_computer") ``` -We'll talk more about `token_type_ids` in [Chapter 3](/course/chapter3), and we'll explain the `attention_mask` key a little later. First, let's see how the `input_ids` are generated. To do this, we'll need to look at the intermediate methods of the tokenizer. +Подробнее о `token_type_ids` мы поговорим в [Главе 3](../chapter3), а ключ `attention_mask` мы объясним чуть позже. Сначала давайте посмотрим, как генерируются `input_ids`. Для этого нам понадобится рассмотреть промежуточные методы токенизатора. -## Encoding[[encoding]] +## Кодирование[[encoding]] -Translating text to numbers is known as _encoding_. Encoding is done in a two-step process: the tokenization, followed by the conversion to input IDs. +Перевод текста в числа называется _кодированием (encoding)_. Кодирование выполняется в два этапа: токенизация, а затем преобразование во входные идентификаторы. -As we've seen, the first step is to split the text into words (or parts of words, punctuation symbols, etc.), usually called *tokens*. There are multiple rules that can govern that process, which is why we need to instantiate the tokenizer using the name of the model, to make sure we use the same rules that were used when the model was pretrained. +Как мы уже видели, первым шагом является разбиение текста на слова (или части слов, знаки препинания и т. д.), обычно называемые *токенами*. Существует множество правил, которые могут управлять этим процессом, поэтому нам нужно инстанцировать токенизатор, используя имя модели, чтобы убедиться, что мы используем те же правила, которые были использованы во время предварительного обучения модели. -The second step is to convert those tokens into numbers, so we can build a tensor out of them and feed them to the model. To do this, the tokenizer has a *vocabulary*, which is the part we download when we instantiate it with the `from_pretrained()` method. Again, we need to use the same vocabulary used when the model was pretrained. +Второй шаг - преобразование этих токенов в числа, чтобы мы могли построить из них тензор и передать его в модель. Для этого у токенизатора есть *словарь*, который мы загружаем, когда инстанцируем его с помощью метода `from_pretrained()`. Опять же, нам нужно использовать тот же словарь, который использовался при предварительном обучении модели. -To get a better understanding of the two steps, we'll explore them separately. Note that we will use some methods that perform parts of the tokenization pipeline separately to show you the intermediate results of those steps, but in practice, you should call the tokenizer directly on your inputs (as shown in the section 2). +Чтобы лучше понять эти два этапа, мы рассмотрим их по отдельности. Обратите внимание, что мы будем использовать некоторые методы, выполняющие части конвейера токенизации отдельно, чтобы показать вам промежуточные результаты этих шагов, но на практике вы должны вызывать токенизатор непосредственно на ваших входных данных (как показано в разделе 2). -### Tokenization[[tokenization]] +### Токенизация[[tokenization]] -The tokenization process is done by the `tokenize()` method of the tokenizer: +Процесс токенизации выполняется методом `tokenize()` токенизатора: ```py from transformers import AutoTokenizer @@ -192,17 +192,17 @@ tokens = tokenizer.tokenize(sequence) print(tokens) ``` -The output of this method is a list of strings, or tokens: +Результатом работы этого метода является список строк, или токенов: ```python out ['Using', 'a', 'transform', '##er', 'network', 'is', 'simple'] ``` -This tokenizer is a subword tokenizer: it splits the words until it obtains tokens that can be represented by its vocabulary. That's the case here with `transformer`, which is split into two tokens: `transform` and `##er`. +Этот токенизатор является токенизатором подслов: он разбивает слова до тех пор, пока не получит токены, которые могут быть представлены в его словаре. В данном случае слово `transformer` разбивается на два токена: `transform` и `##er`. -### From tokens to input IDs[[from-tokens-to-input-ids]] +### От токенов к идентификаторам входа[[from-tokens-to-input-ids]] -The conversion to input IDs is handled by the `convert_tokens_to_ids()` tokenizer method: +Преобразование во входные идентификаторы выполняется методом токенизатора `convert_tokens_to_ids()`: ```py ids = tokenizer.convert_tokens_to_ids(tokens) @@ -214,17 +214,17 @@ print(ids) [7993, 170, 11303, 1200, 2443, 1110, 3014] ``` -These outputs, once converted to the appropriate framework tensor, can then be used as inputs to a model as seen earlier in this chapter. +Эти выходы, преобразованные в тензор соответствующего фреймворка, могут быть использованы в качестве входов в модель, как было показано ранее в этой главе. -✏️ **Try it out!** Replicate the two last steps (tokenization and conversion to input IDs) on the input sentences we used in section 2 ("I've been waiting for a HuggingFace course my whole life." and "I hate this so much!"). Check that you get the same input IDs we got earlier! +✏️ **Попробуйте! ** Повторите два последних шага (токенизацию и преобразование во входные идентификаторы) на входных предложениях, которые мы использовали в разделе 2 ("I've been waiting for a HuggingFace course my whole life." и "I hate this so much!"). Убедитесь, что вы получили те же самые входные идентификаторы, которые мы получали ранее! -## Decoding[[decoding]] +## Декодирование[[decoding]] -*Decoding* is going the other way around: from vocabulary indices, we want to get a string. This can be done with the `decode()` method as follows: +*Декодирование* происходит наоборот: из индексов словаря мы хотим получить строку. Это можно сделать с помощью метода `decode()` следующим образом: ```py decoded_string = tokenizer.decode([7993, 170, 11303, 1200, 2443, 1110, 3014]) @@ -235,6 +235,6 @@ print(decoded_string) 'Using a Transformer network is simple' ``` -Note that the `decode` method not only converts the indices back to tokens, but also groups together the tokens that were part of the same words to produce a readable sentence. This behavior will be extremely useful when we use models that predict new text (either text generated from a prompt, or for sequence-to-sequence problems like translation or summarization). +Обратите внимание, что метод `decode` не только преобразует индексы обратно в токены, но и группирует токены, которые были частью одних и тех же слов, чтобы создать читаемое предложение. Такое поведение будет очень полезно, когда мы будем использовать модели, прогнозирующие новый текст (либо текст, сгенерированный из подсказки (prompt), либо для решения задачи преобразования последовательности-в-последовательность (sequence-to-sequence), такой как перевод или резюмирование). -By now you should understand the atomic operations a tokenizer can handle: tokenization, conversion to IDs, and converting IDs back to a string. However, we've just scraped the tip of the iceberg. In the following section, we'll take our approach to its limits and take a look at how to overcome them. +Теперь вы должны понимать, какие атомарные операции может выполнять токенизатор: токенизация, преобразование в идентификаторы и преобразование идентификаторов обратно в строку. Однако мы лишь пощупали верхушку айсберга. В следующем разделе мы рассмотрим ограничения нашего подхода и посмотрим, как их преодолеть. diff --git a/chapters/ru/chapter2/5.mdx b/chapters/ru/chapter2/5.mdx index 199877efb..33e317db0 100644 --- a/chapters/ru/chapter2/5.mdx +++ b/chapters/ru/chapter2/5.mdx @@ -1,6 +1,6 @@ -# Handling multiple sequences[[handling-multiple-sequences]] +# Обработка множественных последовательностей[[handling-multiple-sequences]] {#if fw === 'pt'} @@ -28,18 +28,18 @@ {/if} -In the previous section, we explored the simplest of use cases: doing inference on a single sequence of a small length. However, some questions emerge already: +В предыдущем разделе мы рассмотрели самый простой вариант использования: проведение инференса на одной последовательности небольшой длины. Однако уже сейчас возникают некоторые вопросы: -- How do we handle multiple sequences? -- How do we handle multiple sequences *of different lengths*? -- Are vocabulary indices the only inputs that allow a model to work well? -- Is there such a thing as too long a sequence? +- Как нам работать с множественными последовательностями? +- Как нам работать с несколькими последовательностями *разной длины*? +- Являются ли индексы словаря единственными входными данными, которые позволяют модели работать хорошо? +- Существует ли такая вещь, как слишком длинная последовательность? -Let's see what kinds of problems these questions pose, and how we can solve them using the 🤗 Transformers API. +Давайте посмотрим, какие проблемы возникают в связи с этими вопросами и как их можно решить с помощью 🤗 Transformers API. -## Models expect a batch of inputs[[models-expect-a-batch-of-inputs]] +## Модели ожидают батч входов[[models-expect-a-batch-of-inputs]] -In the previous exercise you saw how sequences get translated into lists of numbers. Let's convert this list of numbers to a tensor and send it to the model: +В предыдущем упражнении вы видели, как последовательности преобразуются в списки чисел. Давайте преобразуем этот список чисел в тензор и передадим его в модель: {#if fw === 'pt'} ```py @@ -55,7 +55,7 @@ sequence = "I've been waiting for a HuggingFace course my whole life." tokens = tokenizer.tokenize(sequence) ids = tokenizer.convert_tokens_to_ids(tokens) input_ids = torch.tensor(ids) -# This line will fail. +# Эта строка завершится неудачей. model(input_ids) ``` @@ -76,7 +76,7 @@ sequence = "I've been waiting for a HuggingFace course my whole life." tokens = tokenizer.tokenize(sequence) ids = tokenizer.convert_tokens_to_ids(tokens) input_ids = tf.constant(ids) -# This line will fail. +# Эта строка завершится неудачей. model(input_ids) ``` @@ -85,9 +85,9 @@ InvalidArgumentError: Input to reshape is a tensor with 14 values, but the reque ``` {/if} -Oh no! Why did this fail? "We followed the steps from the pipeline in section 2. +О нет! Почему это не удалось? Мы следовали шагам из конвейера в разделе 2. -The problem is that we sent a single sequence to the model, whereas 🤗 Transformers models expect multiple sentences by default. Here we tried to do everything the tokenizer did behind the scenes when we applied it to a `sequence`. But if you look closely, you'll see that the tokenizer didn't just convert the list of input IDs into a tensor, it added a dimension on top of it: +Проблема в том, что мы отправили в модель одну последовательность, в то время как 🤗 модели Transformers по умолчанию ожидают несколько предложений. Здесь мы попытались сделать все то, что токенизатор делал за кулисами, когда мы применяли его к `последовательности`. Но если вы приглядитесь, то увидите, что токенизатор не просто преобразовал список входных идентификаторов в тензор, а добавил к нему еще одно измерение: {#if fw === 'pt'} ```py @@ -112,7 +112,7 @@ array([[ 101, 1045, 1005, 2310, 2042, 3403, 2005, 1037, 17662, ``` {/if} -Let's try again and add a new dimension: +Давайте попробуем еще раз и добавим новое измерение: {#if fw === 'pt'} ```py @@ -156,7 +156,7 @@ print("Logits:", output.logits) ``` {/if} -We print the input IDs as well as the resulting logits — here's the output: +Мы выводим входные идентификаторы, а также результирующие логиты - вот результат: {#if fw === 'pt'} ```python out @@ -172,25 +172,25 @@ Logits: tf.Tensor([[-2.7276208 2.8789377]], shape=(1, 2), dtype=float32) ``` {/if} -*Batching* is the act of sending multiple sentences through the model, all at once. If you only have one sentence, you can just build a batch with a single sequence: +*Батчинг* - это отправка нескольких предложений через модель одновременно. Если у вас есть только одно предложение, вы можете просто создать батч с одной последовательностью: ``` batched_ids = [ids, ids] ``` -This is a batch of two identical sequences! +Это батч из двух одинаковых последовательностей! -✏️ **Try it out!** Convert this `batched_ids` list into a tensor and pass it through your model. Check that you obtain the same logits as before (but twice)! +✏️ **Попробуйте!** Преобразуйте этот список `batched_ids` в тензор и пропустите его через вашу модель. Проверьте, что вы получаете те же логиты, что и раньше (но дважды)! -Batching allows the model to work when you feed it multiple sentences. Using multiple sequences is just as simple as building a batch with a single sequence. There's a second issue, though. When you're trying to batch together two (or more) sentences, they might be of different lengths. If you've ever worked with tensors before, you know that they need to be of rectangular shape, so you won't be able to convert the list of input IDs into a tensor directly. To work around this problem, we usually *pad* the inputs. +Батчинг позволяет модели работать, когда вы подаете ей несколько последовательностей. Использование нескольких последовательностей так же просто, как и создание батча с одной последовательностью. Однако есть и вторая проблема. Когда вы пытаетесь собрать в батч два (или более) предложения, они могут быть разной длины. Если вы когда-нибудь работали с тензорами, то знаете, что они должны иметь прямоугольную форму, поэтому вы не сможете напрямую преобразовать список входных идентификаторов в тензор. Чтобы обойти эту проблему, мы обычно прибегаем к *дополнению (pad)* входных данных. -## Padding the inputs[[padding-the-inputs]] +## Дополнение входов[[padding-the-inputs]] -The following list of lists cannot be converted to a tensor: +Следующий список списков не может быть преобразован в тензор: ```py no-format batched_ids = [ @@ -199,7 +199,7 @@ batched_ids = [ ] ``` -In order to work around this, we'll use *padding* to make our tensors have a rectangular shape. Padding makes sure all our sentences have the same length by adding a special word called the *padding token* to the sentences with fewer values. For example, if you have 10 sentences with 10 words and 1 sentence with 20 words, padding will ensure all the sentences have 20 words. In our example, the resulting tensor looks like this: +Чтобы обойти эту проблему, мы будем использовать *дополнение (padding)*, чтобы придать тензорам прямоугольную форму. Дополнение обеспечивает одинаковую длину всех предложений, добавляя специальное слово *токен дополнения* к предложениям с меньшим количеством значений. Например, если у вас есть 10 предложений с 10 словами и 1 предложение с 20 словами, то при дополнении все предложения будут состоять из 20 слов. В нашем примере результирующий тензор выглядит следующим образом: ```py no-format padding_id = 100 @@ -210,7 +210,7 @@ batched_ids = [ ] ``` -The padding token ID can be found in `tokenizer.pad_token_id`. Let's use it and send our two sentences through the model individually and batched together: +Идентификатор токена дополнения можно найти в `tokenizer.pad_token_id`. Давайте используем его и отправим наши два предложения в модель по отдельности и батчем: {#if fw === 'pt'} ```py no-format @@ -259,15 +259,15 @@ tf.Tensor( ``` {/if} -There's something wrong with the logits in our batched predictions: the second row should be the same as the logits for the second sentence, but we've got completely different values! +Что-то не так с логитами в наших батчах: во втором ряду должны быть те же логиты, что и для второго предложения, но мы получили совершенно другие значения! -This is because the key feature of Transformer models is attention layers that *contextualize* each token. These will take into account the padding tokens since they attend to all of the tokens of a sequence. To get the same result when passing individual sentences of different lengths through the model or when passing a batch with the same sentences and padding applied, we need to tell those attention layers to ignore the padding tokens. This is done by using an attention mask. +Это связано с тем, что ключевой особенностью моделей Transformer являются слои внимания (attention layers), которые *контекстуализируют* каждый токен. Они учитывают токены дополнений, так как рассматривают все токены последовательности. Чтобы получить одинаковый результат при прохождении через модель отдельных предложений разной длины или при прохождении батча с одинаковыми предложениями и дополнениями, нам нужно указать слоям внимания игнорировать дополняющие токены. Для этого используется маска внимания (attention mask). -## Attention masks[[attention-masks]] +## Маски внимания[[attention-masks]] -*Attention masks* are tensors with the exact same shape as the input IDs tensor, filled with 0s and 1s: 1s indicate the corresponding tokens should be attended to, and 0s indicate the corresponding tokens should not be attended to (i.e., they should be ignored by the attention layers of the model). +*Маски внимания (Attention masks)* - это тензоры той же формы, что и тензор входных идентификаторов, заполненные 0 и 1: 1 означает, что соответствующие токены должны "привлекать внимание", а 0 означает, что соответствующие токены не должны "привлекать внимание" (т.е. должны игнорироваться слоями внимания модели). -Let's complete the previous example with an attention mask: +Дополним предыдущий пример маской внимания: {#if fw === 'pt'} ```py no-format @@ -312,26 +312,26 @@ tf.Tensor( ``` {/if} -Now we get the same logits for the second sentence in the batch. +Теперь мы получим такие же логиты для второго предложения в батче. -Notice how the last value of the second sequence is a padding ID, which is a 0 value in the attention mask. +Обратите внимание, что последнее значение второй последовательности - это идентификатор дополнения (padding ID), который в маске внимания имеет значение 0. -✏️ **Try it out!** Apply the tokenization manually on the two sentences used in section 2 ("I've been waiting for a HuggingFace course my whole life." and "I hate this so much!"). Pass them through the model and check that you get the same logits as in section 2. Now batch them together using the padding token, then create the proper attention mask. Check that you obtain the same results when going through the model! +✏️ **Попробуйте! ** Примените токенизацию вручную к двум предложениям, использованным в разделе 2 ("I've been waiting for a HuggingFace course my whole life." и "I hate this so much!"). Пропустите их через модель и проверьте, что вы получите те же логиты, что и в разделе 2. Теперь объедините их в батч с использованием токена дополнения, а затем создайте соответствующую маску внимания. Проверьте, что при прохождении через модель вы получаете те же результаты! -## Longer sequences[[longer-sequences]] +## Более длинные последовательности[[longer-sequences]] -With Transformer models, there is a limit to the lengths of the sequences we can pass the models. Most models handle sequences of up to 512 or 1024 tokens, and will crash when asked to process longer sequences. There are two solutions to this problem: +В моделях Transformer существует ограничение на длину последовательностей, которые мы можем передавать моделям. Большинство моделей работают с последовательностями длиной до 512 или 1024 токенов и терпят крах при необходимости обработки более длинных последовательностей. Есть два решения этой проблемы: -- Use a model with a longer supported sequence length. -- Truncate your sequences. +- Использовать модель с большей поддерживаемой длиной последовательности. +- Усечение (truncate) последовательностей. -Models have different supported sequence lengths, and some specialize in handling very long sequences. [Longformer](https://huggingface.co/docs/transformers/model_doc/longformer) is one example, and another is [LED](https://huggingface.co/docs/transformers/model_doc/led). If you're working on a task that requires very long sequences, we recommend you take a look at those models. +Модели имеют разную поддерживаемую длину последовательности, а некоторые специализируются на работе с очень длинными последовательностями. Одним из примеров является [Longformer](https://huggingface.co/docs/transformers/model_doc/longformer), а другим - [LED](https://huggingface.co/docs/transformers/model_doc/led). Если вы работаете над задачей, требующей очень длинных последовательностей, мы рекомендуем вам обратить внимание на эти модели. -Otherwise, we recommend you truncate your sequences by specifying the `max_sequence_length` parameter: +В противном случае мы рекомендуем использовать усечение последовательностей, указав параметр `max_sequence_length`: ```py sequence = sequence[:max_sequence_length] diff --git a/chapters/ru/chapter2/6.mdx b/chapters/ru/chapter2/6.mdx index d26118501..6097ad0fa 100644 --- a/chapters/ru/chapter2/6.mdx +++ b/chapters/ru/chapter2/6.mdx @@ -1,6 +1,6 @@ -# Putting it all together[[putting-it-all-together]] +# Собираем все воедино[[putting-it-all-together]] {#if fw === 'pt'} @@ -22,9 +22,9 @@ {/if} -In the last few sections, we've been trying our best to do most of the work by hand. We've explored how tokenizers work and looked at tokenization, conversion to input IDs, padding, truncation, and attention masks. +В последних нескольких разделах мы старались делать большую часть работы вручную. Мы изучили, как работают токенизаторы, рассмотрели токенизацию, преобразование во входные идентификаторы, дополнении, усечении и маски внимания. -However, as we saw in section 2, the 🤗 Transformers API can handle all of this for us with a high-level function that we'll dive into here. When you call your `tokenizer` directly on the sentence, you get back inputs that are ready to pass through your model: +Однако, как мы видели в разделе 2, 🤗 Transformers API может обработать все это для нас с помощью высокоуровневой функции, которую мы рассмотрим здесь. Когда вы вызываете свой `tokenizer` непосредственно на предложении, вы получаете обратно входы, готовые к передаче в вашу модель: ```py from transformers import AutoTokenizer @@ -37,9 +37,9 @@ sequence = "I've been waiting for a HuggingFace course my whole life." model_inputs = tokenizer(sequence) ``` -Here, the `model_inputs` variable contains everything that's necessary for a model to operate well. For DistilBERT, that includes the input IDs as well as the attention mask. Other models that accept additional inputs will also have those output by the `tokenizer` object. +Здесь переменная `model_inputs` содержит все, что необходимо для нормальной работы модели. Для DistilBERT это идентификаторы входов, а также маска внимания. В других моделях, принимающих дополнительные входы, они также будут формироваться выходами объекта `tokenizer`. -As we'll see in some examples below, this method is very powerful. First, it can tokenize a single sequence: +Как мы увидим на нескольких примерах ниже, это очень мощный метод. Во-первых, он может токенизировать одну последовательность: ```py sequence = "I've been waiting for a HuggingFace course my whole life." @@ -47,7 +47,7 @@ sequence = "I've been waiting for a HuggingFace course my whole life." model_inputs = tokenizer(sequence) ``` -It also handles multiple sequences at a time, with no change in the API: +Он также обрабатывает несколько последовательностей одновременно, без каких-либо изменений в API: ```py sequences = ["I've been waiting for a HuggingFace course my whole life.", "So have I!"] @@ -55,51 +55,51 @@ sequences = ["I've been waiting for a HuggingFace course my whole life.", "So ha model_inputs = tokenizer(sequences) ``` -It can pad according to several objectives: +Он может быть дополнен исходя из нескольких целей: ```py -# Will pad the sequences up to the maximum sequence length +# Дополнение последовательностей до максимальной длины последовательности model_inputs = tokenizer(sequences, padding="longest") -# Will pad the sequences up to the model max length -# (512 for BERT or DistilBERT) +# Дополнение последовательностей до максимальной длины модели +# (512 для BERT или DistilBERT) model_inputs = tokenizer(sequences, padding="max_length") -# Will pad the sequences up to the specified max length +# Дополнение последовательностей до заданной максимальной длины model_inputs = tokenizer(sequences, padding="max_length", max_length=8) ``` -It can also truncate sequences: +Он также может выполнять усечение последовательностей: ```py sequences = ["I've been waiting for a HuggingFace course my whole life.", "So have I!"] -# Will truncate the sequences that are longer than the model max length -# (512 for BERT or DistilBERT) +# Усечение последовательностей, длина которых превышает максимальную длину модели +# (512 для BERT или DistilBERT) model_inputs = tokenizer(sequences, truncation=True) -# Will truncate the sequences that are longer than the specified max length +# Усечение последовательностей, длина которых превышает заданную максимальную длину model_inputs = tokenizer(sequences, max_length=8, truncation=True) ``` -The `tokenizer` object can handle the conversion to specific framework tensors, which can then be directly sent to the model. For example, in the following code sample we are prompting the tokenizer to return tensors from the different frameworks — `"pt"` returns PyTorch tensors, `"tf"` returns TensorFlow tensors, and `"np"` returns NumPy arrays: +Объект `tokenizer` может выполнять преобразование в тензоры конкретных фреймворков, которые затем могут быть напрямую переданы в модель. Например, в следующем примере кода мы задаем токенизатору возвращать тензоры для различных фреймворков - `"pt"` возвращает тензоры PyTorch, `"tf"` возвращает тензоры TensorFlow, а `"np"` возвращает массивы NumPy: ```py sequences = ["I've been waiting for a HuggingFace course my whole life.", "So have I!"] -# Returns PyTorch tensors +# Вернуть тензоры PyTorch model_inputs = tokenizer(sequences, padding=True, return_tensors="pt") -# Returns TensorFlow tensors +# Вернуть тензоры TensorFlow model_inputs = tokenizer(sequences, padding=True, return_tensors="tf") -# Returns NumPy arrays +# Вернуть массивы NumPy model_inputs = tokenizer(sequences, padding=True, return_tensors="np") ``` -## Special tokens[[special-tokens]] +## Специальные токены[[special-tokens]] -If we take a look at the input IDs returned by the tokenizer, we will see they are a tiny bit different from what we had earlier: +Если мы посмотрим на идентификаторы входа, возвращаемые токенизатором, то увидим, что они немного отличаются от тех, что мы получали ранее: ```py sequence = "I've been waiting for a HuggingFace course my whole life." @@ -117,7 +117,7 @@ print(ids) [1045, 1005, 2310, 2042, 3403, 2005, 1037, 17662, 12172, 2607, 2026, 2878, 2166, 1012] ``` -One token ID was added at the beginning, and one at the end. Let's decode the two sequences of IDs above to see what this is about: +Один идентификатор токена был добавлен в начале, а другой - в конце. Давайте декодируем две последовательности идентификаторов, приведенные выше, чтобы понять, в чем дело: ```py print(tokenizer.decode(model_inputs["input_ids"])) @@ -129,11 +129,11 @@ print(tokenizer.decode(ids)) "i've been waiting for a huggingface course my whole life." ``` -The tokenizer added the special word `[CLS]` at the beginning and the special word `[SEP]` at the end. This is because the model was pretrained with those, so to get the same results for inference we need to add them as well. Note that some models don't add special words, or add different ones; models may also add these special words only at the beginning, or only at the end. In any case, the tokenizer knows which ones are expected and will deal with this for you. +Токенизатор добавил специальное слово `[CLS]` в начале и специальное слово `[SEP]` в конце. Это связано с тем, что модель была предварительно обучена с ними, поэтому для получения тех же результатов при инференсе нам нужно добавить и их. Обратите внимание, что некоторые модели не добавляют специальные слова или добавляют другие слова; модели также могут добавлять эти специальные слова только в начале или только в конце. В любом случае, токенизатор знает, какие из них ожидаются, и справится с этим сам. -## Wrapping up: From tokenizer to model[[wrapping-up-from-tokenizer-to-model]] +## Подведение итогов: От токенизатора к модели[[wrapping-up-from-tokenizer-to-model]] -Now that we've seen all the individual steps the `tokenizer` object uses when applied on texts, let's see one final time how it can handle multiple sequences (padding!), very long sequences (truncation!), and multiple types of tensors with its main API: +Теперь, когда мы рассмотрели все отдельные шаги, которые использует объект `tokenizer` при работе с текстами, давайте в последний раз посмотрим, как он может работать с множественными последовательностями (дополнение!), очень длинными последовательностями (усечение!) и несколькими типами тензоров с помощью своего основного API: {#if fw === 'pt'} ```py diff --git a/chapters/ru/chapter2/7.mdx b/chapters/ru/chapter2/7.mdx index 657aa28e9..13c62e066 100644 --- a/chapters/ru/chapter2/7.mdx +++ b/chapters/ru/chapter2/7.mdx @@ -1,18 +1,18 @@ -# Basic usage completed![[basic-usage-completed]] +# Базовое использование завершено![[basic-usage-completed]] -Great job following the course up to here! To recap, in this chapter you: +Отличная работа по изучению курса до этого места! Напомним, что в этой главе вы: -- Learned the basic building blocks of a Transformer model. -- Learned what makes up a tokenization pipeline. -- Saw how to use a Transformer model in practice. -- Learned how to leverage a tokenizer to convert text to tensors that are understandable by the model. -- Set up a tokenizer and a model together to get from text to predictions. -- Learned the limitations of input IDs, and learned about attention masks. -- Played around with versatile and configurable tokenizer methods. +- Узнали об основных составляющих блоках модели Transformer. +- Узнали, из чего состоит конвейер токенизации. +- Узнали, как использовать модель Transformer на практике. +- Узнали, как использовать токенизатор для преобразования текста в тензоры, понятные модели. +- Настроили токенизатор и модель вместе, чтобы перейти от текста к прогнозам. +- Узнали об ограничениях входных идентификаторов и познакомились с масками внимания. +- Поиграли с универсальными и настраиваемыми методами токенизатора. -From now on, you should be able to freely navigate the 🤗 Transformers docs: the vocabulary will sound familiar, and you've already seen the methods that you'll use the majority of the time. +С этого момента вы должны свободно ориентироваться в документации 🤗 Transformers: лексикон будет звучать знакомо, и вы уже познакомились с методами, которые будете использовать чаще всего. diff --git a/chapters/ru/chapter2/8.mdx b/chapters/ru/chapter2/8.mdx index c41f27936..239f69868 100644 --- a/chapters/ru/chapter2/8.mdx +++ b/chapters/ru/chapter2/8.mdx @@ -2,223 +2,223 @@ -# End-of-chapter quiz[[end-of-chapter-quiz]] +# Итоговый тест по главе[[end-of-chapter-quiz]] -### 1. What is the order of the language modeling pipeline? +### 1. Каков порядок работы конвейера языкового моделирования? -### 2. How many dimensions does the tensor output by the base Transformer model have, and what are they? +### 2. Сколько измерений имеет тензор, выводимый базовой моделью Transformer, и каковы они?