在23年年末,花了两周时间,练了一下《GPT图解》这本书的代码,作一个记录。
《GPT图解:大模型是怎样构建的》
image.png
一 N-Gram模型
代码
# 构建一个玩具语料库数据集
corpus = [
"我喜欢吃苹果",
"我喜欢吃香蕉",
"她喜欢吃葡萄",
"他不喜欢吃香蕉",
"他喜欢吃苹果",
"她喜欢吃草莓"
]
# 定义一个分词函数,将文本转换为单个字符的列表
def tokenize(text):
return [char for char in text] # 将文本拆分为字符列表
# 定义计算N-Gram词频的函数
from collections import defaultdict, Counter
def count_ngram(corpus, n):
# 创新一个字典, 存储N-Gram计数
ngram_count = defaultdict(Counter)
# 遍历语料库中的每个文本
for text in corpus:
# 对文本进行分词
tokens = tokenize(text)
# print("tokens: ", tokens)
# 遍历分词结果,生成N-Gram
for i in range(len(tokens) - n + 1):
# 创建一个N-Gram元组
ngram = tuple(tokens[i:i+n])
# print("ngram: ", ngram)
# 获取N-Gram的前缀
prefix = ngram[:-1]
# 获取N-Gram的目标单字
token = ngram[-1]
# 更新N-Gram计数
ngram_count[prefix][token] += 1
return ngram_count
# 计算2_gram词频
n_gram_counts = count_ngram(corpus, 2)
# print("n_gram_counts", n_gram_counts)
# 打印2_gram词频
print("n_gram:")
for prefix, counts in n_gram_counts.items():
print("{}: {}".format("".join(prefix),dict(counts)))
pass
# 定义计算N-Gram出现概率的函数
def ngram_probabilies(ngram_counts):
# 创建一个字典,存储N-Gram出现的概念
ngram_probs = defaultdict(Counter)
# 遍历N-Gram前缀
for prefix, tokens_count in ngram_counts.items():
# 计算当前前缀的N-Gram计算
total_count = sum(tokens_count.values())
# 遍历每个前缀的N-Gram
for token, count in tokens_count.items():
# 计算每个N-Gram出现的概率
ngram_probs[prefix][token] = count / total_count
return ngram_probs
# 计算BiGram出现的概率
n_gram_probs = ngram_probabilies(n_gram_counts)
# 打印BiGram概率
print("\nn_gram出现的概率")
for prefix, probs in n_gram_probs.items():
print("{}: {}".format("".join(prefix), dict(probs)))
# 定义生成下一个词的函数
def generate_next_token(prefix, ngram_probe):
# 如果前缀不在N-Gram中,返回none
if not prefix in ngram_probe:
return None
# 获取当前前缀的下一个词的概率
next_token_probs =ngram_probe[prefix]
# 选择概率最大的词作为下一个词
next_token = max(next_token_probs, key=next_token_probs.get)
return next_token
# 定义生成连续文本的函数
def generate_text(prefix, ngram_probe, n, length=6):
# 将前缀转换为字符列表
tokens = list(prefix)
# 根据指定长度生成文本
for _ in range(length - len(prefix)):
# 获取当前前缀的下一个词
next_token = generate_next_token(tuple(tokens[-(n-1):]), ngram_probe)
if not next_token:
break
tokens.append(next_token)
return "".join(tokens)
# 输入一个前缀,生成文本
generated_text = generate_text("我", n_gram_probs, 2)
print("\n生成的文本:", generated_text)
网友评论