- vừa được xem lúc

Xây Dựng Mô Hình Ngôn Ngữ Lớn (Phần 5): Tiền huấn luyện với dữ liệu không gán nhãn

0 0 1

Người đăng: Le Thanh Cong

Theo Viblo Asia

File Jupyter Notebook của bài viết này có thể xem tại đây

1. Tính toán các chỉ số: cross-entropy và perplexity

Trước quá trình huấn luyện mô hình, chúng ta cần một thước đo nào đó để xác định rằng việc huấn luyện có đang làm cho mô hình tiến bộ hơn không ? Và đây là lúc cần đến hàm mất mát (loss function)

Hàm mất mát (loss function) là một khái niệm trong học máy nhằm đo lường sự khác biệt giữa dự đoán của mô hình và giá trị thực tế.

Cross entropy loss

Cross-Entropy Loss là một hàm mất mát phổ biến, được sử dụng để đo lường sự khác biệt giữa phân phối xác suất dự đoán của mô hình và phân phối thực tế (nhãn đúng).

Cross-Entropy Loss=1Ni=1Nlog(pi,true)\text{Cross-Entropy Loss} = -\frac{1}{N} \sum_{i=1}^{N} \log(p_{i,\text{true}})

  • N: Số lượng token đầu vào
  • pi,truep_{i,\text{true}} là xác suất dự đoán của mô hình cho token đúng tại vị trí i

Các bước tính toán Cross-Entropy Loss như sau:

  • Bước 1: Lấy kết quả đầu ra logits của mô hình

  • Bước 2: Chuẩn hóa softmax để thu được phân phối xác suất

  • Bước 3: Trích xuất ra giá trị xác suất của các từ kỳ vọng qua các bước

  • Bước 4: Tính logarit cho các giá trị xác suất vừa trích xuất ra

  • Bước 5: Tính trung bình cộng các kết quả ở bước trên

  • Bước 6: Đảo dấu

  • Giá trị càng gần 0, chứng tỏ mô hình dự đoán so với kết quả càng ít sai lệch

Tại sao phải đảo dấu ?

  • Trong học sâu, thay vì tối đa hóa -10.7940 để nó tiến gần đến 0, ta sẽ tối thiểu hóa 10.7940 để nó tiến gần đến 0
  • Giá trị đối của -10.794010.7940, được gọi là giá trị cross-entropy.
# ... # Ta có 2 chuỗi đầu vào
inputs = torch.tensor([[16833, 3626, 6100], # ["every effort moves", [40, 1107, 588]]) # "I really like"] # Targets là kết quả kỳ vọng mô hình sẽ dự đoán ra được qua từng bước
targets = torch.tensor([[3626, 6100, 345], # ["effort moves you", [1107, 588, 11311]]) # " really like chocolate"] def main(): GPT_CONFIG_124M = { "vocab_size": 50257, # Vocabulary size "context_length": 256, # Shortened context length (orig: 1024) "emb_dim": 768, # Embedding dimension "n_heads": 12, # Number of attention heads "n_layers": 12, # Number of layers "drop_rate": 0.1, # Dropout rate "qkv_bias": False # Query-key-value bias } torch.manual_seed(123) model = GPTModel(GPT_CONFIG_124M) model.eval(); with torch.no_grad(): logits = model(inputs) probas = torch.softmax(logits, dim=-1) text_idx = 0 # lấy 3 phần tử probas[0][0][3626], probas[0][1][6100], probas[0][2][345] target_probas_1 = probas[text_idx, [0, 1, 2], targets[text_idx]] text_idx = 1 # lấy 3 phần tử probas[1][0][1107], probas[1][1][588], (probas[1][2][11311] target_probas_2 = probas[text_idx, [0, 1, 2], targets[text_idx]] log_probas = torch.log(torch.cat((target_probas_1, target_probas_2))) avg_log_probas = torch.mean(log_probas) neg_avg_log_probas = avg_log_probas * -1 print(neg_avg_log_probas) # Kết quả: tensor(10.7940) if __name__ == "__main__": main()

Hoặc có thể dùng hàm có sẵn của Pytorch

# ... def main(): GPT_CONFIG_124M = { "vocab_size": 50257, # Vocabulary size "context_length": 256, # Shortened context length (orig: 1024) "emb_dim": 768, # Embedding dimension "n_heads": 12, # Number of attention heads "n_layers": 12, # Number of layers "drop_rate": 0.1, # Dropout rate "qkv_bias": False # Query-key-value bias } torch.manual_seed(123) model = GPTModel(GPT_CONFIG_124M) model.eval(); with torch.no_grad(): logits = model(inputs) probas = torch.softmax(logits, dim=-1) logits_flat = logits.flatten(0, 1) targets_flat = targets.flatten() loss = torch.nn.functional.cross_entropy(logits_flat, targets_flat) print(loss) 

Perplexity

Perplexity (tạm dịch là bối rối) được tính từ cross-entropy loss. Nó trả lời câu hỏi: "Mô hình bối rối như thế nào khi gặp dữ liệu mới ?". Perplexity càng thấp, mô hình càng tốt.

Lưu ý: Perplexity không phải là hàm mất mát, mà là chỉ số đánh giá độ hiệu quả của mô hình ngôn ngữ.

Perplexity=ecross entropy\text{Perplexity} =e^\text{cross entropy} với e là số Euler (~2.718).

2. Tập huấn luyện và Tập đánh giá

Một điều không thể thiếu trong quá trình huấn luyện các mô hình là chia dữ liệu thành 2 phần là Tập huấn luyện (Training datasets)Tập đánh giá (Validation datasets).

  • Tập huấn luyện chứa được sử dụng để huấn luyện mô hình. Nó sẽ học các mẫu trong tập này để điều chỉnh các tham số.
  • Tập đánh giá không được sử dụng để huấn luyện, mà chỉ dùng để đánh giá hiệu suất của mô hình. Nó giúp kiểm tra xem mô hình có đang học vẹt hay không ?
# Link file đầy đủ: https://sal.vn/HMXsKN import os
import urllib.request file_path = "the-verdict.txt"
url = "https://raw.githubusercontent.com/rasbt/LLMs-from-scratch/main/ch02/01_main-chapter-code/the-verdict.txt" if not os.path.exists(file_path): with urllib.request.urlopen(url) as response: text_data = response.read().decode('utf-8') with open(file_path, "w", encoding="utf-8") as file: file.write(text_data)
else: with open(file_path, "r", encoding="utf-8") as file: text_data = file.read()
# ... # Train/validation ratio
# Chia theo tỷ lệ 9/1
train_ratio = 0.90
split_idx = int(train_ratio * len(text_data))
train_data = text_data[:split_idx]
val_data = text_data[split_idx:] torch.manual_seed(123) train_loader = create_dataloader_v1( train_data, batch_size=2, max_length=GPT_CONFIG_124M["context_length"], stride=GPT_CONFIG_124M["context_length"], drop_last=True, shuffle=True, num_workers=0
) val_loader = create_dataloader_v1( val_data, batch_size=2, max_length=GPT_CONFIG_124M["context_length"], stride=GPT_CONFIG_124M["context_length"], drop_last=False, shuffle=False, num_workers=0
)

Training loss và Validation loss

Việc chia tập dữ liệu thành 2 phần cũng đồng thời tạo gấp đôi công sức tính hàm mất mát (loss function) trên mỗi tập 😄

# Link file đầy đủ: https://sal.vn/GJGVGi # ... def calc_loss_batch(input_batch, target_batch, model, device): input_batch, target_batch = input_batch.to(device), target_batch.to(device) logits = model(input_batch) loss = torch.nn.functional.cross_entropy(logits.flatten(0, 1), target_batch.flatten()) return loss def calc_loss_loader(data_loader, model, device, num_batches=None): total_loss = 0. if len(data_loader) == 0: return float("nan") elif num_batches is None: num_batches = len(data_loader) else: # Reduce the number of batches to match the total number of batches in the data loader # if num_batches exceeds the number of batches in the data loader num_batches = min(num_batches, len(data_loader)) for i, (input_batch, target_batch) in enumerate(data_loader): if i < num_batches: loss = calc_loss_batch(input_batch, target_batch, model, device) total_loss += loss.item() else: break return total_loss / num_batches device = torch.device("cuda" if torch.cuda.is_available() else "cpu") # Note:
# Bỏ đoạn cmt dưới nếu bạn chạy trên máy Mac chip M của Apple
# Tốc độ sẽ nhanh hơn
# Tuy nhiên, giá trị loss trả về có thể sẽ khác #if torch.cuda.is_available():
# device = torch.device("cuda")
#elif torch.backends.mps.is_available():
# device = torch.device("mps")
#else:
# device = torch.device("cpu")
#
# print(f"Using {device} device.") model.to(device) # no assignment model = model.to(device) necessary for nn.Module classes torch.manual_seed(123) # For reproducibility due to the shuffling in the data loader with torch.no_grad(): # Disable gradient tracking for efficiency because we are not training, yet train_loss = calc_loss_loader(train_loader, model, device) val_loss = calc_loss_loader(val_loader, model, device) print("Training loss:", train_loss)
print("Validation loss:", val_loss)

Với Training loss và Validation loss chúng ta có một số kịch bản sau

  1. Training loss và Validation loss đều giảm => Mô hình đang được huấn luyện hiệu quả
  2. Training loss giảm, Validation loss tăng => Mô hình chỉ đang làm tốt trên tập huấn luyện, gặp qua các dữ liệu chưa được huấn luyện thì đang bị tắc tị (Overfitting)
  3. Training loss và Validation loss đều tăng => Mô hình đang huấn luyện chưa tốt

3. Huấn luyện LLM

Quy trình

Quy trình huấn luyện mô hình sẽ có các thao tác sau:

Bước 1: Chia thành các chu kỳ huấn luyện (epoch)

Một chu kỳ là một lần duyệt qua toàn bộ tập dữ liệu huấn luyện.

Bước 2: Chia tập dữ liệu huấn luyện thành các lô (batch)

  • Dữ liệu huấn luyện được chia thành các lô thay vì huấn luyện cả tập dữ liệu một lúc.
  • Trong mỗi chu kỳ, tiến hành lặp qua các lô dữ liệu.

Ví dụ: Nếu tập huấn luyện có 10,000 mẫu và batch size là 32, thì có khoảng 313 batch.

Bước 3: Đặt lại gradient

Gradient trong hàm mất mát là một đại lượng có hướng và độ lớn, chứa thông tin về cách thay đổi trọng số để tối ưu hàm mất mát.

  • Trong PyTorch, gradient của các trọng số (weights) được tích lũy qua mỗi lần.
  • Nếu không đặt lại gradient thì sẽ xảy ra hiện tượng cộng dồn, gây sai lệch. Bước này đảm bảo mỗi lô được tính gradient một cách độc lập.

Bước 4: Tính toán giá trị hàm mất mát (loss function)

Tính hàm mất mát cho từng lô dựa trên dự đoán của mô hình và nhãn thực tế.

Bước 5: Tính gradient cho từng lô

Bước 6:Cập nhật tham số của mô hình

Cập nhật tham số mô hình dựa trên gradient tính được, sử dụng một số thuật toán SGD, ADAM ...

Bước 7: Training and validation losses (Tùy chọn)

Tính Training loss và Validation loss xem mô hình đang học như thế nào ?

Bước 8: Sinh văn bản (Tùy chọn)

Sinh ra văn bản từ mô hình để kiểm tra chất lượng đầu ra.

Minh họa với Pytorch

# FILE đầy đủ: https://sal.vn/8s0Maj  # Hàm tính Training loss và Validation loss
def evaluate_model(model, train_loader, val_loader, device, eval_iter): model.eval() with torch.no_grad(): train_loss = calc_loss_loader(train_loader, model, device, num_batches=eval_iter) val_loss = calc_loss_loader(val_loader, model, device, num_batches=eval_iter) model.train() return train_loss, val_loss # Sinh văn bản
def generate_and_print_sample(model, tokenizer, device, start_context): model.eval() # Đặt mô hình ở chế độ đánh giá (evaluation mode) context_size = model.pos_emb.weight.shape[0] encoded = text_to_token_ids(start_context, tokenizer).to(device) # Chuyển văn bản sang token id with torch.no_grad(): token_ids = generate_text_simple( model=model, idx=encoded, max_new_tokens=50, context_size=context_size ) decoded_text = token_ids_to_text(token_ids, tokenizer) # Giải mã các token id thành văn bản print(decoded_text.replace("\n", " ")) model.train() def train_model_simple(model, train_loader, val_loader, optimizer, device, num_epochs, eval_freq, eval_iter, start_context, tokenizer): train_losses, val_losses, track_tokens_seen = [], [], [] tokens_seen, global_step = 0, -1 # Vòng lặp huấn luyện for epoch in range(num_epochs): model.train() # Bật trainning mode for input_batch, target_batch in train_loader: optimizer.zero_grad() # Reset gradient về 0 loss = calc_loss_batch(input_batch, target_batch, model, device) loss.backward() # Tính gradient optimizer.step() # Cập nhật tham số của mô hình tokens_seen += input_batch.numel() global_step += 1 if global_step % eval_freq == 0: train_loss, val_loss = evaluate_model( model, train_loader, val_loader, device, eval_iter) train_losses.append(train_loss) val_losses.append(val_loss) track_tokens_seen.append(tokens_seen) print(f"Ep {epoch+1} (Step {global_step:06d}): " f"Train loss {train_loss:.3f}, Val loss {val_loss:.3f}") # In ra văn bản được tạo bởi mô hình generate_and_print_sample( model, tokenizer, device, start_context ) return train_losses, val_losses, track_tokens_seen

Kết quả huấn luyện sau 10 chu kỳ:

Ep 1 (Step 000000): Train loss 9.821, Val loss 9.931
Ep 1 (Step 000005): Train loss 8.069, Val loss 8.334
Every effort moves you,,,,,,,,,,,,,,. Ep 2 (Step 000010): Train loss 6.623, Val loss 7.049
Ep 2 (Step 000015): Train loss 6.046, Val loss 6.598
Every effort moves you, and,, and,,,,,,,,,. Ep 3 (Step 000020): Train loss 5.558, Val loss 6.503
Ep 3 (Step 000025): Train loss 5.471, Val loss 6.392
Every effort moves you, and to the to the of the to the, and I had. Gis, and I had, and, and, and, and I had, and, and, and, and, and, and, and, and, and, Ep 4 (Step 000030): Train loss 4.995, Val loss 6.275
Ep 4 (Step 000035): Train loss 4.756, Val loss 6.289
Every effort moves you, and I had been the picture. "I"I the the donkey of the donkey the donkey of the picture and I had been a"I Ep 5 (Step 000040): Train loss 4.113, Val loss 6.182
Every effort moves you know the "Oh, and he had to me--I me. "Oh, I felt--and it's the "Oh, and I had been the donkey--and it to me, and down the "Oh, Ep 6 (Step 000045): Train loss 3.721, Val loss 6.143
Ep 6 (Step 000050): Train loss 3.170, Val loss 6.147
Every effort moves you know the fact, and I felt. "I had the last word. "I didn't. "I was his pictures--I looked. "I looked. "I Ep 7 (Step 000055): Train loss 3.109, Val loss 6.186
Ep 7 (Step 000060): Train loss 2.370, Val loss 6.126
Every effort moves you know the inevitable garlanded to have to have the fact with a little: "Yes--and by me to me to have to see a smile behind his pictures--as I had been the honour of the donkey. Ep 8 (Step 000065): Train loss 1.911, Val loss 6.151
Ep 8 (Step 000070): Train loss 1.592, Val loss 6.223
Every effort moves you?" "Yes--I glanced after him, and uncertain. "Oh, he was's an awful simpleton, and Mrs. Gisburn's head to look up at the sketch of the donkey. "There were days when I Ep 9 (Step 000075): Train loss 1.239, Val loss 6.259
Ep 9 (Step 000080): Train loss 0.957, Val loss 6.270
Every effort moves you?" "Yes--quite insensible to the irony. The last word. He laughed again, and threw back the head to look up at the sketch of the donkey. "There were days when I Ep 10 (Step 000085): Train loss 0.708, Val loss 6.387
Every effort moves you?" "Yes--quite insensible to the irony. She wanted him vindicated--and by me!" He laughed again, and threw back his head to look up at the sketch of the donkey. "There were days when I

Đồ thị hóa 2 thông số Training và Validation loss

Training loss giảm dần theo thời gian chứng tỏ mô hình đang dự đoán rất tốt trên tập huấn luyện. Tuy nhiên, Validation loss giảm trong 2 chu kỳ đầu tiên và gần như đi ngang đến hết => Chứng tỏ quá trình huấn luyện đang bị quá khớp (overfit).

4. Điều chỉnh cách thức lựa chọn đầu ra

Như đã biết, từ tiếp theo sinh ra được chọn từ giá trị xác suất lớn nhất thu được khi chuẩn hóa softmax. Trong phần này chúng ta sẽ làm quen với một số cách tiếp cận khác là temperature scalingtop-k sampling.

Temperature scaling

Ý tưởng chính của phương pháp này là làm mịn, điều chỉnh lại phân phối xác suất bằng cách chia các giá trị logits cho một số T > 0 trước khi chuẩn hóa softmax.

def softmax_with_temperature(logits, temperature): scaled_logits = logits / temperature return torch.softmax(scaled_logits, dim=0)

Thông số Temperature > 1 dẫn đến xác suất được phân phối đều hơn, trong khi nếu nó nhỏ hơn 1 sẽ dẫn đến các phân phối có sự cách biệt hơn. Cùng xem đồ thị minh họa để có thể dễ hình dung hơn

Top-k sampling

Top-k Sampling là một kỹ thuật trong đó chỉ giữ lại k token có xác suất cao nhất để xử lý.

Quy trình:

    1. Chỉ giữ lại k giá trị logits lớn nhất. Các giá trị còn lại gán bằng -inf
    1. Softmax
    1. Lấy giá trị lớn nhất
top_k = 3
top_logits, top_pos = torch.topk(next_token_logits, top_k) print("Top logits:", top_logits)
print("Top positions:", top_pos) # Top logits: tensor([6.7500, 6.2800, 4.5100])
# Top positions: tensor([3, 7, 0]) # Các giá trị không thuộc k giá trị lớn nhất thì gán là -inf. Khi softmax sẽ ra xác suất = 0
new_logits = torch.where( condition=next_token_logits < top_logits[-1], input=torch.tensor(float("-inf")), other=next_token_logits
) print(new_logits)
# tensor([4.5100, -inf, -inf, 6.7500, -inf, -inf, -inf, 6.2800, -inf]) topk_probas = torch.softmax(new_logits, dim=0)
print(topk_probas)
# tensor([0.0615, 0.0000, 0.0000, 0.5775, 0.0000, 0.0000, 0.0000, 0.3610, 0.0000])

Điều chỉnh lại hàm sinh văn bản

Từ các kỹ thuật Temperature scalingTop-k sampling ở trên, chúng ta điều chỉnh lại cách thức sinh văn bản dựa trên phân phối xác suất như sau:

def generate(model, idx, max_new_tokens, context_size, temperature=0.0, top_k=None, eos_id=None): for _ in range(max_new_tokens): idx_cond = idx[:, -context_size:] with torch.no_grad(): logits = model(idx_cond) logits = logits[:, -1, :] # Áp dụng top-k sampling if top_k is not None: top_logits, _ = torch.topk(logits, top_k) min_val = top_logits[:, -1] logits = torch.where(logits < min_val, torch.tensor(float("-inf")).to(logits.device), logits) # Áp dụng temperature scaling if temperature > 0.0: logits = logits / temperature probs = torch.softmax(logits, dim=-1) # (batch_size, context_len) # Sample from the distribution idx_next = torch.multinomial(probs, num_samples=1) # (batch_size, 1) # Nếu temperture <= 0 thì lại áp dụng cách thức cũ, lấy xác suất lớn nhất else: idx_next = torch.argmax(logits, dim=-1, keepdim=True) # (batch_size, 1) if idx_next == eos_id: break idx = torch.cat((idx, idx_next), dim=1) # (batch_size, num_tokens+1) return idx

5. Tải về và sử dụng trọng số của OpenAI

Các tham số tải về và nạp vào mô hình là

  • Ma trận trọng số W của token, position embeddings
  • Các ma trận WQW_Q, WKW_K, WVW_V và hệ số tự do (bias) của cơ chế multi-head attetion
  • Ma trận W và bias của Feed Forward Network
  • Tham số của lớp chuẩn hóa LayerNorm
  • Tham số của lớp chuẩn hóa Final LayerNorm
  • Tham số của lớp Linear output
pip install tensorflow>=2.15.0 tqdm>=4.66
# ... file đầy đủ: https://sal.vn/KKG17C model_configs = { "gpt2-small (124M)": {"emb_dim": 768, "n_layers": 12, "n_heads": 12}, "gpt2-medium (355M)": {"emb_dim": 1024, "n_layers": 24, "n_heads": 16}, "gpt2-large (774M)": {"emb_dim": 1280, "n_layers": 36, "n_heads": 20}, "gpt2-xl (1558M)": {"emb_dim": 1600, "n_layers": 48, "n_heads": 25},
} model_name = "gpt2-small (124M)"
NEW_CONFIG = GPT_CONFIG_124M.copy()
NEW_CONFIG.update(model_configs[model_name])
NEW_CONFIG.update({"context_length": 1024, "qkv_bias": True}) gpt = GPTModel(NEW_CONFIG)
gpt.eval(); def assign(left, right): # right là tham số nạp vào # Kiểm tra kích thước 2 tensor if left.shape != right.shape: # Nếu không khớp, báo lỗi raise ValueError(f"Shape mismatch. Left: {left.shape}, Right: {right.shape}") # Trả về tensor right dưới dạng torch.nn.Parameter return torch.nn.Parameter(torch.tensor(right)) # Duyệt qua và gán các tham số từ GPT-2 của OpenAI vào mô hình GPT của chúng ta
def load_weights_into_gpt(gpt, params): gpt.pos_emb.weight = assign(gpt.pos_emb.weight, params['wpe']) gpt.tok_emb.weight = assign(gpt.tok_emb.weight, params['wte']) for b in range(len(params["blocks"])): q_w, k_w, v_w = np.split( (params["blocks"][b]["attn"]["c_attn"])["w"], 3, axis=-1) gpt.trf_blocks[b].att.W_query.weight = assign( gpt.trf_blocks[b].att.W_query.weight, q_w.T) gpt.trf_blocks[b].att.W_key.weight = assign( gpt.trf_blocks[b].att.W_key.weight, k_w.T) gpt.trf_blocks[b].att.W_value.weight = assign( gpt.trf_blocks[b].att.W_value.weight, v_w.T) q_b, k_b, v_b = np.split( (params["blocks"][b]["attn"]["c_attn"])["b"], 3, axis=-1) gpt.trf_blocks[b].att.W_query.bias = assign( gpt.trf_blocks[b].att.W_query.bias, q_b) gpt.trf_blocks[b].att.W_key.bias = assign( gpt.trf_blocks[b].att.W_key.bias, k_b) gpt.trf_blocks[b].att.W_value.bias = assign( gpt.trf_blocks[b].att.W_value.bias, v_b) gpt.trf_blocks[b].att.out_proj.weight = assign( gpt.trf_blocks[b].att.out_proj.weight, params["blocks"][b]["attn"]["c_proj"]["w"].T) gpt.trf_blocks[b].att.out_proj.bias = assign( gpt.trf_blocks[b].att.out_proj.bias, params["blocks"][b]["attn"]["c_proj"]["b"]) gpt.trf_blocks[b].ff.layers[0].weight = assign( gpt.trf_blocks[b].ff.layers[0].weight, params["blocks"][b]["mlp"]["c_fc"]["w"].T) gpt.trf_blocks[b].ff.layers[0].bias = assign( gpt.trf_blocks[b].ff.layers[0].bias, params["blocks"][b]["mlp"]["c_fc"]["b"]) gpt.trf_blocks[b].ff.layers[2].weight = assign( gpt.trf_blocks[b].ff.layers[2].weight, params["blocks"][b]["mlp"]["c_proj"]["w"].T) gpt.trf_blocks[b].ff.layers[2].bias = assign( gpt.trf_blocks[b].ff.layers[2].bias, params["blocks"][b]["mlp"]["c_proj"]["b"]) gpt.trf_blocks[b].norm1.scale = assign( gpt.trf_blocks[b].norm1.scale, params["blocks"][b]["ln_1"]["g"]) gpt.trf_blocks[b].norm1.shift = assign( gpt.trf_blocks[b].norm1.shift, params["blocks"][b]["ln_1"]["b"]) gpt.trf_blocks[b].norm2.scale = assign( gpt.trf_blocks[b].norm2.scale, params["blocks"][b]["ln_2"]["g"]) gpt.trf_blocks[b].norm2.shift = assign( gpt.trf_blocks[b].norm2.shift, params["blocks"][b]["ln_2"]["b"]) gpt.final_norm.scale = assign(gpt.final_norm.scale, params["g"]) gpt.final_norm.shift = assign(gpt.final_norm.shift, params["b"]) gpt.out_head.weight = assign(gpt.out_head.weight, params["wte"]) load_weights_into_gpt(gpt, params)
gpt.to(device); torch.manual_seed(123) token_ids = generate( model=gpt, idx=text_to_token_ids("Every effort moves you", tokenizer).to(device), max_new_tokens=25, context_size=NEW_CONFIG["context_length"], top_k=50, temperature=1.5
) print("Output text:\n", token_ids_to_text(token_ids, tokenizer))

Kết quả mô hình cho ra đã khá mượt mà và tự nhiên 😆

Output text: Every effort moves you as far as the hand can go until the end of your turn unless something happens This would remove you from a battle

Tài liệu tham khảo

https://github.com/rasbt/LLMs-from-scratch/tree/main/ch05

Bình luận

Bài viết tương tự

- vừa được xem lúc

Hành trình AI của một sinh viên tồi

Mình ngồi gõ những dòng này vào lúc 2h sáng (chính xác là 2h 2 phút), quả là một đêm khó ngủ. Có lẽ vì lúc chiều đã uống cốc nâu đá mà giờ mắt mình tỉnh như sáo, cũng có thể là vì những trăn trở về lý thuyết chồng chất ánh xạ mình đọc ban sáng khiến không tài nào chợp mắt được hoặc cũng có thể do mì

0 0 151

- vừa được xem lúc

[Deep Learning] Key Information Extraction from document using Graph Convolution Network - Bài toán trích rút thông tin từ hóa đơn với Graph Convolution Network

Các nội dung sẽ được đề cập trong bài blog lần này. . Tổng quan về GNN, GCN. Bài toán Key Information Extraction, trích rút thông tin trong văn bản từ ảnh.

0 0 228

- vừa được xem lúc

Tìm hiểu về YOLO trong bài toán real-time object detection

1.Yolo là gì. . Họ các mô hình RCNN ( Region-Based Convolutional Neural Networks) để giải quyết các bài toán về định vị và nhận diện vật thể.

0 0 291

- vừa được xem lúc

Encoding categorical features in Machine learning

Khi tiếp cận với một bài toán machine learning, khả năng cao là chúng ta sẽ phải đối mặt với dữ liệu dạng phân loại (categorical data). Khác với các dữ liệu dạng số, máy tính sẽ không thể hiểu và làm việc trực tiếp với categorical variable.

0 0 261

- vừa được xem lúc

TF Lite with Android Mobile

Như các bạn đã biết việc đưa ứng dụng đến với người sử dụng thực tế là một thành công lớn trong Machine Learning.Việc làm AI nó không chỉ dừng lại ở mức nghiên cứu, tìm ra giải pháp, chứng minh một giải pháp mới,... mà quan trọng là đưa được những nghiên cứu đó vào ứng dụng thực tế, được sử dụng để

0 0 75

- vừa được xem lúc

Xây dựng hệ thống Real-time Multi-person Tracking với YOLOv3 và DeepSORT

Trong bài này chúng ta sẽ xây dựng một hệ thống sử dụng YOLOv3 kết hợp với DeepSORT để tracking được các đối tượng trên camera, YOLO là một thuật toán deep learning ra đời vào tháng 5 năm 2016 và nó nhanh chóng trở nên phổ biến vì nó quá nhanh so với thuật toán deep learning trước đó, sử dụng YOLO t

0 0 319