Гузариш ба мундариҷа
Мавзӯи 5 аз 6

Тавлиди матн

Чаро тавлид лозим аст?

Гурӯҳбандӣ аз маҷмӯъ як тамғаро интихоб мекунад, вале модели забонӣ идомаи матн месозад: пешниҳоди муҳаррир, сиёҳнависи нома ё ҷавоби ёвар. Амали асосӣ арзёбии token-и навбатӣ бо назардошти матни мавҷуда аст.

Ин тавлиди авторегрессионӣ мебошад: token-и интихобшуда ба вуруд илова шуда, ба қадамҳои баъдӣ таъсир мекунад. Модел ҷавоби ояндаро пешакӣ намегирад. Як интихоби аввал метавонад идомаро ҷиддӣ дигар кунад.

Блокҳоро бо тартиб иҷро кунед. Дар поён меъмории ҳақиқии GPT-2 бо конфигуратсияи хурд ва вазнҳои сифрӣ аст. Он забон намедонад: ҳамаи token-ҳо баробаранд. Ин намуна бе боргирии GPT-2 натиҷаҳои такроршаванда медиҳад.

1. Баҳои token-и навбатӣ

AutoModelForCausalLM идомаро пешгӯӣ мекунад. logits се меҳвар дорад: баста, мавқеъҳои вуруд ва луғат. Мавқеи охирини [0, -1] баҳои token-и давомдиҳандаи тамоми вуруди ҷориро медиҳад.

import torch
from transformers import GPT2Config, GPT2LMHeadModel

config = GPT2Config(vocab_size=5, n_positions=16, n_embd=8, n_layer=1, n_head=2, bos_token_id=1, eos_token_id=4, pad_token_id=0)
model = GPT2LMHeadModel(config).eval()
with torch.no_grad():
    for parameter in model.parameters():
        parameter.zero_()
ids = torch.tensor([[1, 2]])
mask = torch.ones_like(ids)
with torch.no_grad():
    outputs = model(input_ids=ids, attention_mask=mask)
print(list(outputs.logits.shape))
print(outputs.logits[0, -1].tolist())

Натиҷа:

[1, 2, 5]
[0.0, 0.0, 0.0, 0.0, 0.0]

Як вуруд аз ду token ва панҷ номзади навбатӣ дорем. Баҳои сифрӣ интихоби token-ро манъ намекунад: softmax эҳтимолиятҳои баробар медиҳад. attention_mask ошкоро дода шудааст, зеро рақами 0 ҳамчун padding низ истифода мешавад.

2. generate ва ҳадди token-ҳои нав

Интихоби greedy баҳои калонтаринро мегирад. Ҳангоми баробарӣ дар намуна рақами аввал, яъне 0 интихоб мешавад. generate давраро иҷро мекунад ва max_new_tokens танҳо қисми иловашударо маҳдуд мекунад. Натиҷаи пурраи модели causal дархости аслиро низ дорад.

out = model.generate(input_ids=ids, attention_mask=mask, max_new_tokens=3, do_sample=False)
print(out.tolist())
print(out[:, ids.shape[1]:].tolist())

Натиҷа:

[[1, 2, 0, 0, 0]]
[[0, 0, 0]]

Ду token-и аслӣ дар оғоз монд ва се token-и нав пайдо шуд. Буриш аз рӯйи дарозии вуруд идомаро ҷудо мекунад. Дар лоиҳаи воқеӣ AutoTokenizer ва AutoModelForCausalLM-и мувофиқро бо from_pretrained гирифта, натиҷаро бо tokenizer-и худ decode кунед.

3. Temperature ва интихоби тасодуфӣ

Sampling token-ро мувофиқи тақсимот тасодуфӣ интихоб мекунад. temperature тезии онро идора мекунад: адади мусбати аз 1 камтар афзалияти пешсафро қавӣ ва аз 1 калонтар фарқҳоро ҳамвор мекунад. Temperature дониш намеафзояд ва далелҳои нодурустро ислоҳ намекунад.

logits = torch.tensor([1.0, 0.0])
for t in (0.25, 2.0):
    print(t, [round(p, 3) for p in torch.softmax(logits / t, dim=-1).tolist()])

Натиҷа:

0.25 [0.982, 0.018]
2.0 [0.622, 0.378]

Бо 0.25 token-и аввал қариб тамоми эҳтимолиятро мегирад, бо 2.0 номзадҳо наздиктаранд. Дар generate интихоби тасодуфиро do_sample=True фаъол мекунад: temperature дар ҳолати greedy sampling-ро фаъол намекунад. Temperature-и сифрӣ барои тақсим нодуруст аст.

4. Маҳдуд кардани номзадҳо бо top-k

Top-k sampling-ро байни k token-и беҳтарин иҷозат медиҳад. Дигарон бояд эҳтимолияти сифрӣ гиранд. -inf қулай аст: экспонентаи он сифр аст. Рақами ду номзади беҳтарин ва тақсимоти пешакӣ додашударо мебинем:

logits = torch.tensor([0.0, 2.0, 1.0])
print(logits.topk(2).indices.tolist())
print([round(p, 3) for p in torch.softmax(torch.tensor([float('-inf'), 2.0, 1.0]), dim=-1).tolist()])

Натиҷа:

[1, 2]
[0.0, 0.731, 0.269]

Рақами 0 хориҷ шуд ва эҳтимолиятҳои боқимонда як мешаванд. Logit-и одии сифрӣ чунин манъ намекунад. Top-p ба ҷойи он token-ҳои эҳтимолиро то массаи умумии муайян ҷамъ мекунад; шумораи номзадҳо метавонад тағйир ёбад.

5. Анҷоми ҷавоб

EOS рақами махсуси анҷоми пайдарпайӣ аст. Ҳадди token-ҳои нав ҳадди болоӣ аст, на дарозии ваъдашуда. EOS-ро 0 таъин мекунем: намуна онро дар қадами аввал интихоб мекунад.

out = model.generate(input_ids=ids, attention_mask=mask, max_new_tokens=3, do_sample=False, eos_token_id=0)
print(out.tolist())
print(out.shape[1] - ids.shape[1])

Натиҷа:

[[1, 2, 0]]
1

EOS ба пайдарпайии натиҷавӣ дохил мешавад. decode(..., skip_special_tokens=True) онро одатан ҳангоми нишон додан пинҳон мекунад. Дар масъалаҳои мавзӯъ мавҷудияти EOS байни рақамҳои натиҷа санҷида мешавад.

Дар дохил чӣ мегузарад?

Модел дархостро коркард мекунад, token-и навбатӣ интихоб ва шартҳои қатъ санҷида мешаванд. Пас аз илова модел бо контексти нав идома медиҳад. generate одатан ҳисобҳои пешинаи attention-ро дар cache нигоҳ медорад, то ҳама чизро аз нав ҳисоб накунад. Мисли идомаи ҷумла, калимаи нав интихобҳоро танг мекунад, аммо интихоби беҳтарини наздик беҳтарин матни пурраро кафолат намедиҳад.

Хатоҳои маъмул

  • outputs.logits[0, 0] мавқеи аввалро идома медиҳад. Барои тамоми вуруд мавқеи охирин лозим аст.
  • max_length=20 дарозии умумиро бо дархост маҳдуд мекунад. Барои қисми нав max_new_tokens=20 гиред.
  • temperature=0 ҳангоми тақсим тақсимоти нодуруст медиҳад. Барои greedy do_sample=False истифода кунед.
  • do_sample=False, temperature=2 интихоби тасодуфиро фаъол намекунад. Барои sampling do_sample=True гузоред.
  • decode(out[0]) дар модели causal дархостро ҳам нишон медиҳад. Барои танҳо ҷавоб аввал рақамҳои навро ҷудо кунед.

Ёдномаи кӯтоҳ

Параметр Вазифа
logits[0, -1] баҳои идома
do_sample=False интихоби greedy
do_sample=True интихоб аз рӯйи эҳтимолият
temperature тезии тақсимот
top_k шумораи номзадҳо
max_new_tokens, eos_token_id ҳадд ва анҷом

Тафсилот: ҳуҷҷатҳои generate.