<FrameworkSwitchCourse {fw} />

# Модели

{#if fw === 'pt'}

<CourseFloatingBanner chapter={2}
  classNames="absolute z-10 right-0 top-0"
  notebooks={[
    {label: "Google Colab", value: "https://colab.research.google.com/github/huggingface/notebooks/blob/master/course/ru/chapter2/section3_pt.ipynb"},
    {label: "Aws Studio", value: "https://studiolab.sagemaker.aws/import/github/huggingface/notebooks/blob/master/course/ru/chapter2/section3_pt.ipynb"},
]} />

{:else}

<CourseFloatingBanner chapter={2}
  classNames="absolute z-10 right-0 top-0"
  notebooks={[
    {label: "Google Colab", value: "https://colab.research.google.com/github/huggingface/notebooks/blob/master/course/ru/chapter2/section3_tf.ipynb"},
    {label: "Aws Studio", value: "https://studiolab.sagemaker.aws/import/github/huggingface/notebooks/blob/master/course/ru/chapter2/section3_tf.ipynb"},
]} />

{/if}

{#if fw === 'pt'}
<Youtube id="AhChOFRegn4"/>
{:else}
<Youtube id="d3JVgghSOew"/>
{/if}

{#if fw === 'pt'}
В этом разделе мы подробнее рассмотрим создание и использование модели. Мы будем использовать класс `AutoModel`, который удобен, когда вы хотите создать экземпляр любой модели из контрольной точки.

Класс `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` и все его родственники на самом деле являются простыми оболочками для большого количества моделей, доступных в библиотеке. Это умная оболочка, поскольку она может автоматически угадывать подходящую архитектуру модели для вашей контрольной точки, а затем создает экземпляр модели с этой архитектурой.

{/if}

Однако, если вы знаете тип модели, которую хотите использовать, вы можете использовать класс, который напрямую определяет ее архитектуру. Давайте посмотрим, как это работает с моделью BERT.

## Создание модели Transformer

Первое, что нам нужно будет сделать для инициализации модели 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}

Конфигурация содержит множество атрибутов, которые используются для построения модели:

```py
print(config)
```

```python out
BertConfig {
  [...]
  "hidden_size": 768,
  "intermediate_size": 3072,
  "max_position_embeddings": 512,
  "num_attention_heads": 12,
  "num_hidden_layers": 12,
  [...]
}
```

Хотя вы еще не видели, что делают все эти атрибуты, вы должны узнать некоторые из них: атрибут `hidden_size` определяет размер вектора `hidden_states`, а `num_hidden_layers` определяет количество слоев, которые имеет модель.

### Различные способы загрузки

Создание модели из конфигурации по умолчанию инициализирует ее случайными значениями:

{#if fw === 'pt'}
```py
from transformers import BertConfig, BertModel

config = BertConfig()
model = BertModel(config)

# Модель инициализируется случайным образом!
```
{:else}
```py
from transformers import BertConfig, TFBertModel

config = BertConfig()
model = TFBertModel(config)

# Модель инициализируется случайным образом!
```
{/if}

Модель можно использовать в этом состоянии, но она будет выводить тарабарщину; сначала ее нужно обучить. Мы могли бы обучить модель с нуля для решения поставленной задачи, но, как вы видели в [Главе 1](/course/chapter1), это потребовало бы много времени и большого количества данных, а также имело бы значительное воздействие на окружающую среду. Чтобы избежать ненужных и дублирующих усилий, крайне важно иметь возможность делиться и повторно использовать модели, которые уже были обучены.

Загрузить уже обученную модель Transformer очень просто — мы можем сделать это с помощью метода `from_pretrained()`:

{#if fw === 'pt'}
```py
from transformers import BertModel

model = BertModel.from_pretrained("bert-base-cased")
```

Как вы видели ранее, мы могли бы заменить `BertModel` эквивалентным классом `AutoModel`. С этого момента мы начнем делать так, поскольку таким образом создается код, не зависящий от контрольных точек; если ваш код работает для одной контрольной точки, он должен беспрепятственно работать с другой. Это применимо, даже если архитектура отличается, при условии, что контрольная точка была обучена для аналогичной задачи (например, задачи анализа тональности).

{:else}
```py
from transformers import TFBertModel

model = TFBertModel.from_pretrained("bert-base-cased")
```

Как вы видели ранее, мы могли бы заменить `TFBertModel` эквивалентным классом `TFAutoModel`. С этого момента мы начнем делать так, поскольку таким образом создается код, не зависящий от контрольных точек; если ваш код работает для одной контрольной точки, он должен беспрепятственно работать с другой. Это применимо, даже если архитектура отличается, при условии, что контрольная точка была обучена для аналогичной задачи (например, задачи анализа тональности).

{/if}

В приведенном выше примере кода мы не использовали `BertConfig`, а вместо этого загрузили предварительно обученную модель с помощью идентификатора `bert-base-cased`. Это контрольная точка модели, которую обучили сами авторы BERT; вы можете найти более подробную информацию о ней в её [карточке модели](https://huggingface.co/bert-base-cased).

Теперь эта модель инициализирована со всеми весами контрольной точки. Её можно использовать непосредственно для логического вывода на задачах, для которых она обучалась, а также её можно точно донастроить для новой задачи. Тренируясь с предварительно обученными весами, а не с нуля, мы можем быстро добиться хороших результатов.

Веса будут загружены и кэшированы (поэтому будущие вызовы метода `from_pretrained()` не будут загружать их повторно) в папку кеша, которая по умолчанию находится в *~/.cache/huggingface/transformers*. Вы можете настроить папку кэша, установив переменную среды `HF_HOME`.

Идентификатор, используемый для загрузки модели, может быть идентификатором любой модели в Model Hub, если он совместим с архитектурой BERT. Полный список доступных контрольных точек моделей BERT можно найти [здесь](https://huggingface.co/models?filter=bert).

### Способы сохранения

Сохранить модель так же просто, как и загрузить - для этого мы используем метод `save_pretrained()`, аналогичный методу `from_pretrained()`:

```py
model.save_pretrained("directory_on_my_computer")
```

Данный код сохранит два файла на вашем диске:

{#if fw === 'pt'}
```
ls directory_on_my_computer

config.json pytorch_model.bin
```
{:else}
```
ls directory_on_my_computer

config.json tf_model.h5
```
{/if}

Если вы посмотрите на файл *config.json*, вы увидите атрибуты, необходимые для построения архитектуры модели. Этот файл также содержит некоторые метаданные, например, откуда появилась контрольная точка и какую версию 🤗 Transformers вы использовали, когда в последний раз сохраняли контрольную точку.

{#if fw === 'pt'}
Файл *pytorch_model.bin* известен как *словарь состояний*; он содержит все веса вашей модели. Эти два файла идут рука об руку; конфигурация необходима, чтобы знать архитектуру вашей модели, в то время как веса модели являются параметрами вашей модели.

{:else}
Файл *tf_model.h5* известен как *словарь состояний*; он содержит все веса вашей модели. Эти два файла идут рука об руку; конфигурация необходима, чтобы знать архитектуру вашей модели, в то время как веса модели являются параметрами вашей модели.

{/if}

## Использование модели Transformer для логического вывода

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

Токенизаторы могут позаботиться о преобразовании входных данных в соответствующие тензоры фреймворка, но чтобы помочь вам понять, что происходит, мы кратко рассмотрим, что необходимо сделать, прежде чем отправлять входные данные в модель.

Допустим, у нас есть несколько последовательностей:

```py
sequences = ["Hello!", "Cool.", "Nice!"]
```

Токенизатор преобразует их в словарные индексы, которые обычно называются *входными идентификаторами*. Каждая последовательность теперь представляет собой список чисел! В результате получается:

```py no-format
encoded_sequences = [
    [101, 7592, 999, 102],
    [101, 4658, 1012, 102],
    [101, 3835, 999, 102],
]
```

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

{#if fw === 'pt'}
```py
import torch

model_inputs = torch.tensor(encoded_sequences)
```
{:else}
```py
import tensorflow as tf

model_inputs = tf.constant(encoded_sequences)
```
{/if}

### Использование тензоров в качестве входных данных для модели

Использовать тензоры с моделью чрезвычайно просто — мы просто вызываем модель с входными данными:

```py
output = model(model_inputs)
```

В то время как модель принимает множество различных аргументов, необходимы только входные идентификаторы. Позже мы объясним, для чего применяются другие аргументы и когда они требуются, но сначала нам нужно поближе познакомиться с токенизаторами, которые используются для создания входных данных, понятных модели Transformer.
