一、大模型(LLM)定义与演化
- 语言模型核心目标:预测词序列中下一个词或缺失词的概率,对人类语言内在规律建模。
- 四代语言模型演化:
- 统计语言模型(SLM):基于马尔可夫假设的n-gram模型。
- 神经语言模型(NLM):神经网络(如RNN)+分布式词向量(Word Embedding)。代表:word2vec。
- 预训练语言模型(PLM):海量无标注数据预训练(biLSTM或Transformer)+下游任务微调。代表:ELMo、BERT、GPT-1/2。
- 大语言模型(LLM):遵循“扩展法则”(Scaling Law),增大参数/数据提升性能,并出现“涌现能力”(Emergent Abilities)。代表:GPT-3、ChatGPT、Claude、Llama。
二、大模型构建三阶段
- 预训练(Pretraining)
- 目的:用海量文本数据为模型参数找到优质起点。
- 当前主流路线:Transformer Decoder-only + 自回归下一个词预测(GPT系列主导)。
- 数据要求:数T级tokens(Llama-1/2/3分别为1T、2T、15T),需高质量、多样性、清洗有害内容。
- 算力需求:极高(如Llama-1 65B在2048块A100训练近3周)。
- 关键:数据配比、学习率调度、训练监控经验。
- 有监督微调(SFT / Instruction Tuning)
- 目的:激活预训练模型的任务解决能力,让模型学会遵循指令、问答形式输出。
- 数据量:几十万~百万条(高质量数千~数万条也可)。
- 作用:催化剂式激活潜在能力,非传授新知识。
- 效果:显著提升指令遵循能力,支持零样本下游任务。
- 基于人类反馈的强化学习对齐(RLHF)
- 目的:使模型输出更符合人类价值观、偏好。
- 核心:训练奖励模型(Reward Model)用人类偏好排序数据评估输出质量 → 用PPO等强化学习优化。
- 简化替代:DPO(Direct Preference Optimization),无需强化学习采样,复杂度接近SFT,超参更易调。
- 示例流程(Llama-2-Chat):预训练 → SFT → 多次RLHF(拒绝采样 + PPO),并迭代更新人类偏好数据。
三、开源 vs 闭源大模型
- 共同需求:海量数据 + 强大算力,只有少数机构能独立承担。
- 开源阵营(促进学术交流、创新民主化):Meta AI、浪潮信息等。开放代码、权重、数据集。
- 闭源阵营(商业竞争力):OpenAI、百度等。通过API提供服务,保护核心技术。
四、浪潮“源”大模型开源体系(截至2025年12月资料)
- 源1.0(2021.9)
- 2457亿参数,5T数据,76层Decoder,超越GPT-3规模,中文能力突出。
- 开放:API、高质量中文数据集、代码。
- 源2.0(2023.11)
- 10T数据,三规模(1026亿、518亿、21亿)。
- 创新:局部注意力过滤增强(LFA),精度提升3.53%。
- 全面开源:全系列参数+代码。
- 源2.0-M32(2024.5)
- MoE结构,400亿总参数、37亿激活参数,2000B Tokens训练,32专家。
- 结构:LFA + Attention Router。
- 性能:对标Llama3-70B,推理算力降至1/19。
五、大模型时代开发范式(挖掘模型能力)
- Prompt工程(有手就行)
- 直接精心设计Prompt调用模型。
- 关键技术:
- In-Context Learning(ICL):提示中加入任务说明+示例,零样本归纳。
- Chain-of-Thought(CoT):加入推理链,提升复杂问题处理。
- Embedding + 检索(外接大脑)
- 解决:知识局限(无实时/私有知识)、数据安全、幻觉问题。
- 方法:私有知识 → Embedding → 存向量数据库 → 检索后作为上下文输入LLM。
- 参数高效微调(PEFT / Lightweight Fine-tuning)
- 解决:特定任务能力弱、学习新能力。
- 全量微调算力代价高 → PEFT只训极少参数,效果接近全量。
六、大模型应用开发必知必会
- 整体架构:客户端(用户交互) + 服务端(模型推理)。
- 客户端主流框架:
- Gradio:
- 组件分类:输入输出组件、布局组件(Row/Column/Blocks推荐)、控制组件。
- 适合丰富交互界面。
- Streamlit:
- 无输入输出区分,直接独立组件(文本、数据、图表、输入、多媒体、Chat、布局容器等)。
- 支持多页面、缓存、数据库连接、自定义组件等。
- Gradio:
- 服务端两种方式:
- 调用API(OpenAI、讯飞星火等)
- 优点:便捷、无硬件维护、稳定、易扩展。
- 缺点:网络延迟、隐私风险、费用不确定、依赖服务商。
- 本地部署(下载权重 + 推理框架)
- 优点:数据安全、低延迟、成本固定、可深度定制。
- 缺点:高硬件投入、运维复杂、技术门槛高。
- 调用API(OpenAI、讯飞星火等)
选择依据:数据敏感性、预算、延迟要求、并发规模等。
核心结论:大模型能力源于规模化预训练,实际应用需通过SFT/RLHF对齐、Prompt/ICL/CoT、检索增强、PEFT等方式进一步挖掘与适配。开源与闭源并行推动行业发展,实际开发中灵活选择API或本地部署。
七、案例:智能编程助手
本项目基于源2B大模型的编程能力来解决用户的问题。
核心代码
注:下面代码为修改后可运行的代码(参考群友代码修改),与原代码不同。
# 导入所需的库
from transformers import AutoTokenizer, AutoModelForCausalLM
import torch
import streamlit as st
# 创建一个标题和一个副标题
st.title("💬 Yuan2.0 智能编程助手")
# 源大模型下载
from modelscope import snapshot_download
model_dir = snapshot_download('IEITYuan/Yuan2-2B-Mars-hf', cache_dir='./')
# model_dir = snapshot_download('IEITYuan/Yuan2-2B-July-hf', cache_dir='./')
# 定义模型路径
path = './IEITYuan/Yuan2-2B-Mars-hf'
# path = './IEITYuan/Yuan2-2B-July-hf'
# 定义模型数据类型
torch_dtype = torch.bfloat16 # A10
# torch_dtype = torch.float16 # P100
# 定义一个函数,用于获取模型和tokenizer
@st.cache_resource
def get_model():
print("Creat tokenizer...")
tokenizer = AutoTokenizer.from_pretrained(path,
add_eos_token=False,
add_bos_token=False,
eos_token='<eod>',
trust_remote_code=True)
# 添加特殊token
tokenizer.add_tokens(['<sep>', '<pad>', '<mask>', '<predict>', '<FIM_SUFFIX>', '<FIM_PREFIX>', '<FIM_MIDDLE>','<commit_before>','<commit_msg>','<commit_after>','<jupyter_start>','<jupyter_text>','<jupyter_code>','<jupyter_output>','<empty_output>'], special_tokens=True)
# 设置pad_token
if tokenizer.pad_token is None:
tokenizer.pad_token = tokenizer.eos_token
tokenizer.pad_token_id = tokenizer.eos_token_id
print("Creat model...")
model = AutoModelForCausalLM.from_pretrained(path,
dtype=torch_dtype,
trust_remote_code=True,
device_map="auto"
)
if model.config.pad_token_id is None:
model.config.pad_token_id = model.config.eos_token_id
print("Done.")
return tokenizer, model
# 加载model和tokenizer
tokenizer, model = get_model()
# 初次运行时,session_state中没有"messages",需要创建一个空列表
if "messages" not in st.session_state:
st.session_state["messages"] = []
# 每次对话时,都需要遍历session_state中的所有消息,并显示在聊天界面上
for msg in st.session_state.messages:
st.chat_message(msg["role"]).write(msg["content"])
# 如果用户在聊天输入框中输入了内容,则执行以下操作
if prompt := st.chat_input():
# 将用户的输入添加到session_state中的messages列表中
st.session_state.messages.append({"role": "user", "content": prompt})
# 在聊天界面上显示用户的输入
st.chat_message("user").write(prompt)
# 构建对话历史
history = "<n>".join(msg["content"] for msg in st.session_state.messages) + "<sep>"
print(f"Prompt: {history}") # 调试用
# Tokenize输入
inputs = tokenizer(history, return_tensors="pt")
input_ids = inputs["input_ids"]
# 创建attention_mask
attention_mask = torch.ones_like(input_ids)
# 将数据移动到模型所在的设备
device = model.device
input_ids = input_ids.to(device)
attention_mask = attention_mask.to(device)
try:
# 生成回复 - 使用修复后的参数
with torch.no_grad():
outputs = model.generate(
input_ids=input_ids,
attention_mask=attention_mask,
do_sample=False,
max_length=1024,
pad_token_id=tokenizer.pad_token_id,
eos_token_id=tokenizer.eos_token_id,
use_cache=False, # 关键修复:禁用KV缓存
repetition_penalty=1.1,
num_beams=1,
temperature=None, # 设置为None避免警告
top_p=None, # 设置为None避免警告
)
# 解码输出
output = tokenizer.decode(outputs[0], skip_special_tokens=False)
print(f"Raw output: {output}") # 调试用
# 提取生成的回复部分
if "<sep>" in output:
# 找到最后一个<sep>之后的内容
parts = output.split("<sep>")
response = parts[-1].replace("<eod>", "").strip()
else:
# 如果没有<sep>,使用整个输出
response = output.replace("<eod>", "").strip()
# 清理回复,移除可能重复的提示部分
if history in response:
response = response.replace(history, "").strip()
except Exception as e:
st.error(f"生成时出现错误: {e}")
# 尝试更简化的生成方式
try:
with torch.no_grad():
outputs = model.generate(
input_ids=input_ids,
do_sample=False,
max_length=1024,
pad_token_id=tokenizer.pad_token_id,
eos_token_id=tokenizer.eos_token_id,
use_cache=False
)
output = tokenizer.decode(outputs[0])
response = output.split("<sep>")[-1].replace("<eod>", '').strip()
except Exception as e2:
st.error(f"简化生成方式也失败: {e2}")
response = "抱歉,模型生成时出现错误。请尝试重新输入或检查模型配置。"
# 将模型的输出添加到session_state中的messages列表中
st.session_state.messages.append({"role": "assistant", "content": response})
# 在聊天界面上显示模型的输出
st.chat_message("assistant").write(response)
运行效果


994

被折叠的 条评论
为什么被折叠?



