大模型的预训练
预训练值得特别关注有2个原因:
1. 前期预训练的成本高(GPT-4预训练成本超1亿美元)但效果好;后期的模型微调则投入产出比低;
2. 预训练依赖大规模数据,企业长期积累的优质数据是核心竞争力(数据质量与大模型生成效果呈正相关)
数据集和训练数据
Transformer算法
►Transformer 是什么? 变形金刚?
►大语言模型是基于概率的模型,它基于训练数据中的统计信息,预测下一个词;
►由于基于概率去决策,即使是相同问题,每次回答都稍微不同
Transformer架构工作流程:
►组成
Transformer 由 Encoder 和 Decoder 两个部分组成
►步骤
►►第一步:输入各维度向量,相加得到向量矩阵X(全局上下文理解)
获取输入句子的每一个单词的表示向量 X,X由单词的 Embedding(Embedding就是从原始数据提取出来的Feature) 和单词位置的 Embedding 相加得到向量矩阵X。
►►第二步:输入向量矩阵X,Encoder输出编码信息矩阵 C
►►第三步:输入编码信息矩阵 C,Decoder 输出预测性结果
编码信息矩阵 C 输入Decoder,根据当前解码过的单词 1~ i 解码下一个单词 i+1,最终得到预测性结果
token计算
影响大模型 token 生成速率的采样概率参数有 max_token、top_k/top_p、temperature
"大模型通过Token处理文本时,中文的Token-字符映射呈现阶梯式特征:
最大上下文长度
上下文是指大模型处理任务的时候,能够考虑的信息范围。
max_token指的是模型一次性能够接收的最大字符数或 token 数(如果输入的文本超过了这个限制,超出部分将被截断或者忽略,这就会导致上下文信息的丢失)。
Token概率采样策略
Token统计器
在线统计:OpenAI Tokens 在线计算工具 - AIGC2D.com
离线统计:
from typing import List, Dict
import tiktoken
from aihub_service.model.request.ai_base_request import Message
class TokenTracker:
"""支持上下文Token统计的增强版"""
def __init__(self, model_name:str=""):
self.model_name = model_name
self._init_encoder()
def _init_encoder(self):
"""初始化编码器"""
try:
self.encoding = tiktoken.encoding_for_model(self.model_name)
self.is_openai = True
except KeyError:
self.encoding = tiktoken.get_encoding("cl100k_base")
self.is_openai = False # 非OpenAI模型可能使用不同规则
def _openai_message_tokens(self, message: Message) -> int:
"""计算单条消息的Token(含OpenAI特殊格式)"""
# 官方计算规则:https://platform.openai.com/docs/guides/text-generation/managing-tokens
tokens_per_message = 4 # 每条消息的基础开销
tokens = tokens_per_message
tokens += len(self.encoding.encode(message.content))
if message.role:
tokens += len(self.encoding.encode(message.role)) + 1
return tokens
def count_context_tokens(self, context: List[Message]) -> int:
"""统计上下文Token总数"""
if self.is_openai:
# OpenAI聊天模型特殊计算规则
tokens_per_reply = 3 # 每次回复的固定开销
total = sum([self._openai_message_tokens(msg) for msg in context])
total += tokens_per_reply
return total
else:
# 通用模型直接拼接文本计算
full_text = "\n".join([msg.content for msg in context])
return len(self.encoding.encode(full_text))
def predict_output_tokens(self, output_text: str) -> int:
"""预测输出Token数"""
return len(self.encoding.encode(output_text))
def track_full_token_usage(
self,
input_text: str,
output_text: str,
context: List[Message] = None
) -> Dict:
"""完整使用统计(输入+输出+上下文)"""
context = context or []
# 统计各部分
context_tokens = self.count_context_tokens(context)
input_tokens = len(self.encoding.encode(input_text))
output_tokens = self.predict_output_tokens(output_text)
# 总消耗 = 上下文 + 本次输入 + 输出
total_tokens = context_tokens + input_tokens + output_tokens
return {
"input_tokens": input_tokens + context_tokens,
"output_tokens": output_tokens,
"total_tokens": total_tokens,
}
词嵌入、注意力机制、相似性比较