大语言模型(LLM)的主要任务是:给定输入文本,它应该能够正确预测下一个单词。例如,给定句子 “llm is used to generate text”,LLM 的输入和输出如下:
llm -> is
llm is -> used
llm is used -> generate
llm is used generate -> text
可以看出,这类似于使用滑动窗口将输入文本包含其中,期望的输出是窗口右边界之外的下一个单词。需要注意的是,在此之前,我们需要对文本进行分词(tokenize),也就是说,LLM 将接收到一个数字数组,并尝试预测下一个数字。
让我们通过代码实现滑动窗口策略。在上一节中,我们通过给定的 URL 下载了训练文本,结果是一个网页的 HTML 代码。我们需要跳过返回文本的很大一部分,直到找到我们需要用作训练文本的主要内容。如下图所示,我们需要跳过开头的一部分文本,才能到达主要内容:
然后使用以下代码,我们从选定文本中提取内容,并将其转换为 tokens:
import tiktoken
tokenizer = tiktoken.get_encoding('gpt2')
with open("fire-tongue.txt", "r", encoding="utf-8") as f:
raw_text = f.read()
pos = raw_text.index("His investigation of the case of the man")
training_text = raw_text[pos:]
encoded_text = tokenizer.encode(training_text)
print(len(encoded_text))
运行以上代码后,输出为 14429,表示原始文本被分词为 14429 个 token。
我们将窗口长度固定为 4,并生成输入文本和期望输出(即下一个单词)如下:
window_size = 4
# 窗口大小决定了有多少个 token 作为输入
x = encoded_text[:window_size]
# 右移一位以获得预测单词
y = encoded_text[1 : window_size+1]
print(f"x: {
x}")
print(f"y: {
y}")
for i in range(1, window_size + 1):
input = encoded_text[:i]
expect = encoded_text[i]
print(input, "----->", expect)
for i in range(1, window_size + 1):
input = encoded_text[:i]
expect = encoded_text[i]
print(tokenizer.decode(input), "----->" ,tokenizer.decode([expect]))
运行以上代码,我们得到以下输出:
x: [6653, 3645, 286