“Khám phá bí quyết giải mã các mô hình ngôn ngữ lớn thế giới” – TechToday

#TechToday #NLP #MachineLearning #GreedySearch

Chiến lược giải mã trong các mô hình ngôn ngữ lớn được đề cập trên TechToday. Bài viết trình bày về các chiến lược giải mã như tìm kiếm tham lam và tìm kiếm theo chùm để tạo ra văn bản từ các mô hình như GPT-2 trong xử lý ngôn ngữ tự nhiên. Bài viết cũng giải thích về cách mô hình dự đoán mã thông báo tiếp theo dựa trên các mã thông báo trước đó và cách tính toán xác suất có điều kiện của chuỗi các mã thông báo. Tuy nhiên, việc sử dụng tìm kiếm tham lam để tạo ra văn bản có thể bỏ lỡ các chuỗi có xác suất xuất hiện tốt hơn nhưng chỉ số ưu tiên thấp hơn. Bài viết kết thúc bằng cách minh họa việc triển khai tìm kiếm tham lam bằng graphviz và networkx.

Nguồn: https://techtoday.co/decoding-strategies-in-large-language-models/

Trình mã thông báo, Mã hóa cặp byte trong trường hợp này, dịch từng mã thông báo trong văn bản đầu vào thành ID mã thông báo tương ứng. Sau đó, GPT-2 sử dụng các ID mã thông báo này làm thông tin đầu vào và cố gắng dự đoán mã thông báo có khả năng xảy ra nhất tiếp theo. Cuối cùng, mô hình tạo các bản ghi, được chuyển đổi thành xác suất bằng hàm softmax.

Ví dụ: mô hình chỉ định xác suất 17% cho mã thông báo vì “của” là mã thông báo tiếp theo sau “Tôi có một giấc mơ”. Đầu ra này về cơ bản đại diện cho một danh sách xếp hạng các mã thông báo tiềm năng tiếp theo trong chuỗi. Chính thức hơn, chúng tôi biểu thị xác suất này là P(của | Tôi có một giấc mơ) = 17%.

Các mô hình tự hồi quy như GPT dự đoán mã thông báo tiếp theo theo trình tự dựa trên các mã thông báo trước đó. Xem xét một chuỗi các mã thông báo w = (ww…, w). Xác suất chung của chuỗi này P(w) có thể được chia thành:

Đối với mỗi mã thông báo wᵢ trong trình tự, P(wᵢ | w₁, w₂, …, wᵢ₋₁) đại diện cho xác suất có điều kiện của wᵢ đưa ra tất cả các mã thông báo trước đó (w₁, w₂, …, wᵢ₋₁). GPT-2 tính toán xác suất có điều kiện này cho mỗi trong số 50.257 mã thông báo trong kho từ vựng của nó.

Điều này dẫn đến câu hỏi: làm thế nào để chúng ta sử dụng các xác suất này để tạo văn bản? Đây là lúc các chiến lược giải mã, chẳng hạn như tìm kiếm tham lam và tìm kiếm theo chùm, phát huy tác dụng.

Tìm kiếm tham lam là một phương pháp giải mã lấy mã thông báo có thể xảy ra nhất ở mỗi bước làm mã thông báo tiếp theo trong chuỗi. Nói một cách đơn giản, nó chỉ giữ lại mã thông báo có khả năng nhất ở mỗi giai đoạn, loại bỏ tất cả các tùy chọn tiềm năng khác. Sử dụng ví dụ của chúng tôi:

  • Bước 1: Đầu vào: “Tôi có một giấc mơ” → Mã thông báo rất có thể: “của”
  • Bước 2: Đầu vào: “Tôi có một giấc mơ về” → Rất có thể mã thông báo: “ là”
  • Bước 3: Đầu vào: “Tôi có ước mơ trở thành” → Mã thông báo có khả năng nhất: “ a”
  • Bước 4: Đầu vào: “Tôi có ước mơ trở thành” → Mã thông báo có khả năng nhất: “ bác sĩ”
  • Bước 5: Đầu vào: “Tôi có ước mơ làm bác sĩ” → Mã thông báo khả thi nhất: “.”

Mặc dù cách tiếp cận này nghe có vẻ trực quan, nhưng điều quan trọng cần lưu ý là tìm kiếm tham lam là thiển cận: nó chỉ xem xét mã thông báo có khả năng xảy ra nhất ở mỗi bước mà không xem xét tác động tổng thể đối với chuỗi. Thuộc tính này làm cho nó nhanh và hiệu quả vì nó không cần phải theo dõi nhiều trình tự, nhưng điều đó cũng có nghĩa là nó có thể bỏ lỡ các trình tự tốt hơn có thể đã xuất hiện với các mã thông báo tiếp theo ít có khả năng xảy ra hơn một chút.

Tiếp theo, hãy minh họa việc triển khai tìm kiếm tham lam bằng graphviz và networkx. Chúng tôi chọn ID có số điểm cao nhất, tính toán xác suất nhật ký của nó (chúng tôi lấy nhật ký để đơn giản hóa việc tính toán) và thêm nó vào cây. Chúng tôi sẽ lặp lại quá trình này cho năm mã thông báo.

import matplotlib.pyplot as plt
import networkx as nx
import numpy as np
import time

def get_log_prob(logits, token_id):
# Compute the softmax of the logits
probabilities = torch.nn.functional.softmax(logits, dim=-1)
log_probabilities = torch.log(probabilities)

# Get the log probability of the token
token_log_probability = log_probabilities(token_id).item()
return token_log_probability

def greedy_search(input_ids, node, length=5):
if length == 0:
return input_ids

outputs = model(input_ids)
predictions = outputs.logits

# Get the predicted next sub-word (here we use top-k search)
logits = predictions(0, -1, :)
token_id = torch.argmax(logits).unsqueeze(0)

# Compute the score of the predicted token
token_score = get_log_prob(logits, token_id)

# Add the predicted token to the list of input ids
new_input_ids = torch.cat((input_ids, token_id.unsqueeze(0)), dim=-1)

# Add node and edge to graph
next_token = tokenizer.decode(token_id, skip_special_tokens=True)
current_node = list(graph.successors(node))(0)
graph.nodes(current_node)('tokenscore') = np.exp(token_score) * 100
graph.nodes(current_node)('token') = next_token + f"_length"

# Recursive call
input_ids = greedy_search(new_input_ids, current_node, length-1)

return input_ids

# Parameters
length = 5
beams = 1

# Create a balanced tree with height 'length'
graph = nx.balanced_tree(1, length, create_using=nx.DiGraph())

# Add 'tokenscore', 'cumscore', and 'token' attributes to each node
for node in graph.nodes:
graph.nodes(node)('tokenscore') = 100
graph.nodes(node)('token') = text

# Start generating text
output_ids = greedy_search(input_ids, 0, length=length)
output = tokenizer.decode(output_ids.squeeze().tolist(), skip_special_tokens=True)
print(f"Generated text: output")

Generated text: I have a dream of being a doctor.

Tìm kiếm tham lam của chúng tôi tạo ra văn bản giống như văn bản từ thư viện máy biến áp: “Tôi có ước mơ trở thành bác sĩ.” Hãy hình dung cái cây mà chúng ta đã tạo ra.

import matplotlib.pyplot as plt
import networkx as nx
import matplotlib.colors as mcolors
from matplotlib.colors import LinearSegmentedColormap

def plot_graph(graph, length, beams, score):
fig, ax = plt.subplots(figsize=(3+1.2*beams**length, max(5, 2+length)), dpi=300, facecolor="white")

# Create positions for each node
pos = nx.nx_agraph.graphviz_layout(graph, prog="dot")

# Normalize the colors along the range of token scores
if score == 'token':
scores = (data('tokenscore') for _, data in graph.nodes(data=True) if data('token') is not None)
elif score == 'sequence':
scores = (data('sequencescore') for _, data in graph.nodes(data=True) if data('token') is not None)
vmin = min(scores)
vmax = max(scores)
norm = mcolors.Normalize(vmin=vmin, vmax=vmax)
cmap = LinearSegmentedColormap.from_list('rg', ("r", "y", "g"), N=256)

# Draw the nodes
nx.draw_networkx_nodes(graph, pos, node_size=2000, node_shape="o", alpha=1, linewidths=4,
node_color=scores, cmap=cmap)

# Draw the edges
nx.draw_networkx_edges(graph, pos)

# Draw the labels
if score == 'token':
labels = node: data('token').split('_')(0) + f"\ndata('tokenscore'):.2f%" for node, data in graph.nodes(data=True) if data('token') is not None
elif score == 'sequence':
labels = node: data('token').split('_')(0) + f"\ndata('sequencescore'):.2f" for node, data in graph.nodes(data=True) if data('token') is not None
nx.draw_networkx_labels(graph, pos, labels=labels, font_size=10)
plt.box(False)

# Add a colorbar
sm = plt.cm.ScalarMappable(cmap=cmap, norm=norm)
sm.set_array(())
if score == 'token':
fig.colorbar(sm, ax=ax, orientation='vertical', pad=0, label="Token probability (%)")
elif score == 'sequence':
fig.colorbar(sm, ax=ax, orientation='vertical', pad=0, label="Sequence score")
plt.show()

# Plot graph
plot_graph(graph, length, 1.5, 'token')


[ad_2]

Leave a Reply

Your email address will not be published. Required fields are marked *