Концепции ИИ на Python

Attention и self-attention на Python

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

Суть простыми словами

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

Вычислите scaled dot-product attention вручную с запросами, ключами и значениями, а затем добавьте causal mask, как в GPT.

Главные идеи

  • Веса attention получаются из softmax, поэтому каждая строка в сумме даёт 1.
  • Деление на √d не даёт оценкам становиться слишком большими для длинных векторов.
  • Causal mask не позволяет токену смотреть на будущие токены во время генерации.
  • Multi-head attention выполняет несколько attention параллельно, а позиционное кодирование добавляет порядок слов.

Когда это использовать?

  • Понять, что происходит внутри нейронных сетей и библиотек ИИ.
  • Разобраться в идее до того, как реализовать её в соответствующих задачах.
  • Подготовиться к курсам по машинному обучению, собеседованиям и проектам.

Посмотрите в действии

Щёлкните по строке тепловой карты, чтобы увидеть, куда смотрит этот токен. Включите causal mask, чтобы скрыть будущие токены, и меняйте резкость, чтобы сфокусировать attention.

Пример кода

Запустить код →
main.py
import math

def softmax(row):
    exps = [math.exp(v - max(row)) for v in row]
    return [e / sum(exps) for e in exps]

# Three tokens, each with a query, key and value vector of size 2.
Q = [[1, 0], [0, 1], [1, 1]]
K = [[1, 0], [0, 1], [1, 1]]
V = [[10, 0], [0, 10], [5, 5]]
d = len(K[0])

def attention(causal=False):
    out = []
    for i, q in enumerate(Q):
        # Score: how well this query matches every key, scaled by sqrt(d).
        scores = [sum(a * b for a, b in zip(q, k)) / math.sqrt(d) for k in K]
        if causal:  # a token may only look at itself and earlier tokens
            scores = [s if j <= i else -1e9 for j, s in enumerate(scores)]
        weights = softmax(scores)
        out.append([round(sum(w * v[c] for w, v in zip(weights, V)), 2) for c in range(2)])
    return out

print("attention:", attention())
print("causal attention:", attention(causal=True))

Ожидаемый результат

attention: [[6.02, 3.98], [3.98, 6.02], [5.0, 5.0]]
causal attention: [[10.0, 0.0], [3.3, 6.7], [5.0, 5.0]]

Как это работает

Для каждого запроса оценки - это его скалярные произведения со всеми ключами, делённые на √d. Softmax превращает оценки в веса, а выход - это взвешенное среднее значений. С causal mask первый токен видит только себя, поэтому его выход в точности равен его собственному значению [10, 0].

Измените значения и запустите программу в онлайн-компиляторе Python CodeUtility без локальной установки Python.

Практические задания

Изменяйте входные данные и проверяйте граничные случаи перед работой с большими наборами.

  1. Измените входные данные или веса и предскажите результат до запуска.
  2. Выводите промежуточные значения, чтобы проследить каждый шаг вычислений.
  3. Решите задачи по ссылкам ниже, чтобы самостоятельно реализовать идею.
Запустить в Python IDE →

Попрактикуйтесь на задаче

Примените материал этого урока к реальной задаче. Каждая задача запускается в браузере, с мгновенными тестами и разбором от ИИ.

Все задачи