文章

AI大模型基础知识

AI大模型基础知识

AI大模型基础知识

本文档介绍大语言模型(LLM)的基础知识,包括命名规则、技术指标和使用细节。


目录


1. 模型命名规则

1.1 完整命名结构

大模型通常遵循以下命名规范:

1
模型系列-版本号-规模-训练类型-量化方法-精度-其他特性

1.2 命名示例解析

示例1:Qwen2.5-1.5B-Instruct

1
2
3
Qwen2.5 - 1.5B - Instruct
  ↓       ↓       ↓
模型系列  规模   训练类型
部分含义说明
Qwen2.5模型系列和版本通义千问第2.5代
1.5B参数量15亿(Billion)参数
Instruct训练类型经过指令微调

示例2:Qwen2.5-7B-Instruct-GPTQ-Int4

1
2
3
Qwen2.5 - 7B - Instruct - GPTQ - Int4
  ↓       ↓      ↓        ↓      ↓
 系列    规模  指令微调  量化方法 量化精度

1.3 常见后缀含义

训练类型后缀

后缀含义特点适用场景
-Base基础预训练模型只完成预训练,擅长续写需要进一步微调
-Instruct指令微调模型能理解和执行指令对话、问答、任务执行
-Chat对话优化模型专门优化对话能力聊天机器人
-Code代码专用模型针对代码生成优化编程助手
-Math数学专用模型针对数学问题优化数学解题
-VL视觉语言模型支持图像理解多模态应用

量化方法后缀

后缀含义显存占用质量损失
-GPTQGPTQ量化算法减少75%很小
-AWQAWQ量化算法减少75%极小
-GGUF / -GGMLllama.cpp格式减少50-75%可调
-Int44位整数量化最小较小
-Int88位整数量化减少50%极小

Base vs Instruct 对比

1
2
3
4
5
6
7
# Base模型(续写模式)
输入"今天天气真好"
输出",阳光明媚,微风拂面,正是出游的好时节..."  # 自动续写

# Instruct模型(指令模式)
输入"今天天气真好"
输出"是的!您想聊聊天气,还是有什么计划吗?"  # 理解为对话

1.4 多后缀组合规则

当模型使用多种技术时,后缀会组合在一起:

排列顺序

1
模型系列 → 版本号 → 规模 → 训练类型 → 量化方法 → 量化精度

实际示例

完整模型名各部分含义
Qwen2.5-7B系列-规模(基础版)
Qwen2.5-7B-Instruct+ 指令微调
Qwen2.5-7B-Instruct-GPTQ+ GPTQ量化
Qwen2.5-7B-Instruct-GPTQ-Int4+ 4位精度
CodeLlama-13B-Instruct-AWQ代码+指令+AWQ量化
Llama-2-7B-Chat-GGUF-Q4_K_M对话+GGUF格式+4位混合量化

1.5 参数规模对照表

规模标识参数量显存需求(FP16)显存需求(Int4)适用设备
0.5B5亿~1-2 GB~0.5 GB手机、边缘设备
1.5B15亿~3-4 GB~1 GB入门级GPU
3B30亿~6-8 GB~2 GB消费级GPU
7B70亿~14-16 GB~4-5 GBRTX 3090/4090
13B130亿~26-32 GB~8-10 GB专业GPU
30B300亿~60 GB~15 GBA100等
70B700亿~140 GB~35 GB多卡并行

2. 模型主要技术指标

2.1 核心指标概览

指标类别关键指标重要性
规模指标参数量、模型大小⭐⭐⭐⭐⭐
长度指标上下文长度、输入输出限制⭐⭐⭐⭐⭐
性能指标推理速度、吞吐量⭐⭐⭐⭐
质量指标基准测试得分、困惑度⭐⭐⭐⭐
资源指标显存占用、计算需求⭐⭐⭐⭐⭐

2.2 上下文长度(Context Length)⭐

这是最重要的指标之一!

定义

1
2
上下文长度 = 系统提示词 + 历史对话 + 当前输入 + 模型输出
           └────────── 所有这些加起来不能超过限制 ──────────┘

主流模型对比

模型上下文长度约等于字数(中文)说明
GPT-3.54K tokens~3千字早期版本
GPT-3.5-16K16K tokens~1.2万字扩展版
GPT-48K tokens~6千字标准版
GPT-4-32K32K tokens~2.4万字长文本版
GPT-4-Turbo128K tokens~9.6万字超长版
Claude 2100K tokens~7.5万字长文本专家
Claude 3200K tokens~15万字极长文本
Qwen2.532K - 128K2.4万 - 9.6万字取决于版本
Llama 24K tokens~3千字标准版
Llama 38K tokens~6千字标准版
Llama 3.1128K tokens~9.6万字长文本版

Token与字符换算

1
2
3
4
5
6
7
8
9
中文:1个汉字 ≈ 1.3-1.5 tokens
      1000 tokens ≈ 650-750个汉字

英文:1个单词 ≈ 1-2 tokens
      1000 tokens ≈ 750个单词

示例:
"我爱编程" → 约5-6 tokens
"I love programming" → 约4-5 tokens

2.3 输入输出Token限制

限制类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
┌─────────────────────────────────────────┐
│ 最大上下文长度 (Max Context Length)      │
│ 例如:32,768 tokens (32K)               │
├─────────────────────────────────────────┤
│                                          │
│  ┌────────────────────────────────┐    │
│  │ 输入部分 (Input Tokens)        │    │
│  │ - 系统提示词                   │    │
│  │ - 历史对话                     │    │
│  │ - 当前用户输入                 │    │
│  │ 无明确限制,但占用上下文空间   │    │
│  └────────────────────────────────┘    │
│              +                           │
│  ┌────────────────────────────────┐    │
│  │ 输出部分 (Output Tokens)       │    │
│  │ max_new_tokens = 2048-4096     │    │
│  │ ⭐ 通常有单独的限制             │    │
│  └────────────────────────────────┘    │
│                                          │
│  = 总和不能超过上下文长度                │
└─────────────────────────────────────────┘

典型配置示例

1
2
3
4
5
6
7
8
最大上下文 = 32,768 tokens (32K)

分配示例
├─ 系统提示词     200 tokens
├─ 历史对话     5,000 tokens
├─ 当前用户输入  2,000 tokens
├─ 可用于输出  24,568 tokens
└─ 实际输出限制 2,048 tokens (max_new_tokens设置)

2.4 性能指标

推理速度(Tokens per Second)

速度体验效果应用场景
10-20 t/s缓慢打字大模型/弱GPU
30-50 t/s流畅打字标准配置 ⭐
50-100 t/s快速生成高性能GPU
100+ t/s几乎瞬间小模型/专用硬件

其他性能指标

  • 首Token延迟(TTFT):从提交到开始输出的时间
    • 良好:< 1秒
    • 可接受:1-3秒
    • 较慢:> 3秒
  • 吞吐量(Throughput):每秒处理的请求数
    • 重要性:影响服务器负载能力

2.5 质量指标

困惑度(Perplexity, PPL)

1
2
3
4
5
6
困惑度越低 = 模型预测越准确

典型值:
- 优秀:PPL < 10
- 良好:PPL 10-20
- 一般:PPL 20-50

基准测试

测试名称评估内容满分
MMLU多任务语言理解(学术能力)100%
C-Eval中文综合能力100%
HumanEval代码生成能力100%
GSM8K数学推理能力100%
BBH复杂推理能力100%
TruthfulQA真实性和准确性100%

2.6 资源消耗

显存占用计算

1
2
3
4
5
6
7
8
9
10
11
12
13
14
基础公式(FP16精度):
显存需求(GB) ≈ 参数量(B) × 2

示例:
- 1.5B模型:1.5 × 2 = 3 GB
- 7B模型:  7 × 2 = 14 GB
- 14B模型: 14 × 2 = 28 GB

量化后(Int4):
显存需求(GB) ≈ 参数量(B) × 0.5

示例:
- 7B-Int4:  7 × 0.5 = 3.5 GB
- 14B-Int4: 14 × 0.5 = 7 GB

实际显存占用(包含推理开销)

模型规模FP16Int8Int4推荐显卡
1.5B4 GB2 GB1 GBGTX 1660以上
3B8 GB4 GB2 GBRTX 3060
7B16 GB8 GB5 GBRTX 3090/4070Ti
13B32 GB16 GB10 GBRTX 4090/A5000
30B60 GB30 GB18 GBA100 40GB×2
70B140 GB70 GB40 GBA100 80GB×2

3. 模型使用细节

3.1 模型的”记忆”机制

核心原理

❌ 模型本身没有对话缓存能力!

模型是无状态的,每次生成都是”失忆”的。

✅ 通过每次传入完整历史来”伪装”记忆

工作流程

1
2
3
4
5
6
7
8
9
10
# 每次对话都构建完整历史(代码片段)
conversation = [
    {'role': 'system', 'content': enhanced_system_message},
]
# ⭐ 添加所有历史对话
for query_h, response_h in history:
    conversation.append({'role': 'user', 'content': query_h})
    conversation.append({'role': 'assistant', 'content': response_h})
# 添加当前问题
conversation.append({'role': 'user', 'content': query})

多轮对话示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 第一轮对话
输入[系统提示] + [用户"你好"]
输出"你好!有什么可以帮你的?"  # 生成了15个tokens

# 第二轮对话(重新输入所有历史)
输入[系统提示] 
     + [用户"你好"] 
     + [助手"你好!有什么可以帮你的?"]   上一轮的完整内容
     + [用户"我叫小明"]                     新输入
输出"很高兴认识你,小明!"  # 只返回新生成的20个tokens

# 第三轮对话(再次重新输入所有历史)
输入[系统提示]
     + [用户"你好"]
     + [助手"你好!有什么可以帮你的?"]
     + [用户"我叫小明"]
     + [助手"很高兴认识你,小明!"]
     + [用户"我叫什么名字?"]              新输入
输出"你叫小明。"  # 能回答是因为历史中包含这个信息

Token消耗增长

1
2
3
4
5
6
第1轮:100 tokens (输入) + 15 tokens (输出) = 115 tokens
第2轮:100 + 15 + 50 (输入) + 20 tokens (输出) = 185 tokens
第3轮:100 + 15 + 50 + 20 + 30 (输入) + 10 (输出) = 225 tokens
第10轮:可能达到数千tokens

⚠️ 随着对话进行,token消耗会持续增长!

3.2 新旧内容识别机制

方法1:skip_prompt=True(推荐)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# TextIteratorStreamer 自动跳过输入部分
streamer = TextIteratorStreamer(
    tokenizer=tokenizer, 
    skip_prompt=True,      # ⭐ 自动识别并跳过input_ids部分
    timeout=60.0,
    skip_special_tokens=True
)

# 使用流式输出器
generation_kwargs = dict(
    input_ids=inputs["input_ids"],
    max_new_tokens=max_new_tokens,
    streamer=streamer,
    ...
)

# 只返回新生成的token
for new_text in streamer:
    yield new_text  # 逐字输出(打字机效果)

方法2:手动切片

1
2
3
4
5
6
7
8
9
# 如果不使用streamer
output = model.generate(input_ids=input_ids, max_new_tokens=2048)

# output包含:input_ids + 新生成的tokens
input_length = input_ids.shape[1]      # 输入长度:例如1300
new_tokens = output[:, input_length:]  # 切片取新部分

# 解码新部分
new_text = tokenizer.decode(new_tokens[0])

自回归生成过程

1
2
3
4
5
6
7
8
9
10
11
12
13
# 模型内部生成机制(简化版)
input_tokens = [1, 2, 3, ..., 1300]  # 输入的1300个token

# 逐个生成新token
步骤1: input=[1,2,...,1300]           预测并生成 token_1301
步骤2: input=[1,2,...,1300,1301]      预测并生成 token_1302
步骤3: input=[1,2,...,1301,1302]      预测并生成 token_1303
步骤4: input=[1,2,...,1302,1303]      预测并生成 token_1304
...
步骤2048: 停止达到max_new_tokens限制

# streamer只返回新生成的部分:
[1301, 1302, 1303, ..., 3348]

3.3 流式输出机制详解

什么是流式输出?

流式输出(Streaming Output)是指在模型生成过程中,实时逐个返回生成的token,而不是等待全部生成完毕后一次性返回。

1
2
3
4
5
6
7
8
9
10
# 项目中使用的流式输出实现
streamer = TextIteratorStreamer(tokenizer=tokenizer, skip_prompt=True)

# 在单独的线程中运行模型生成
thread = Thread(target=model.generate, kwargs=generation_kwargs)
thread.start()

# 实时逐个返回生成的token
for new_text in streamer:
    yield new_text  # 打字机效果

对比:流式 vs 非流式

1
2
3
4
5
6
7
8
# 非流式输出(批量返回)
output = model.generate(input_ids, max_new_tokens=2048)
result = tokenizer.decode(output)
return result  # 一次性返回完整结果,用户需等待10秒

# 流式输出(逐步返回)
for token in streamer:
    yield token  # 每生成一个就返回一个,0.5秒就有反馈

流式输出的优点 ✅

1. 用户体验极佳 ⭐⭐⭐⭐⭐

打字机效果,即时反馈

1
2
3
4
5
6
非流式输出:
用户等待 ────── 5秒 ────── [完整文本突然出现]

流式输出:
用户等待 0.3秒 → "我" "是" "一" "个" "AI" "助" "手" ...
                └─ 立即看到反馈,焦虑感降低

心理学优势:

  • 用户知道系统在工作,不会觉得卡死
  • 可以边生成边阅读,节省总体时间
  • 类似ChatGPT的体验,符合用户期望
2. 感知延迟显著降低 ⭐⭐⭐⭐⭐
指标非流式流式改善
首次反馈10秒0.5秒20倍
用户焦虑显著改善
可读体验突兀自然更好
1
2
3
4
5
# 非流式:首Token延迟 + 全部生成时间
总等待时间 = 0.5 + 10 = 10.5  用户需要等10.5

# 流式:只需要首Token延迟
首次反馈 = 0.5  用户0.5秒就看到输出开始
3. 支持提前终止 ⭐⭐⭐⭐
1
2
3
4
# 用户可以随时停止生成
for token in streamer:
    if user_clicked_stop:
        break  # 立即停止,节省计算资源和时间

实际场景:

1
2
3
4
5
6
7
生成中:"今天我们来聊聊量子物理,首先从薛定谔的猫说起..."
用户想法:"这不是我要的内容!"
用户操作:点击停止按钮 ✅ 立即停止,重新提问

如果是非流式:
❌ 必须等10秒生成完毕才能看到内容
❌ 浪费了10秒和大量计算资源
4. 内存效率更高 ⭐⭐⭐
1
2
3
4
5
6
7
# 流式输出:处理一个token就释放
for token in streamer:
    yield token  # 内存中只保存当前token

# 非流式输出:保存完整结果
full_output = generate_all_tokens()  # 2048个tokens
# 内存中保存完整的2048个tokens,然后一次性返回
5. 适合长文本生成 ⭐⭐⭐⭐⭐
1
2
3
4
5
6
7
8
9
生成5000字文章:

非流式:等待30秒 → [文章出现]
       ↓
    用户体验:这是不是死机了?😰

流式:0.5秒开始 → "AI..." → "是..." → "人工智能..."
     ↓
   用户体验:正在生成,可以边看边读 😊
6. 网络传输优化
1
2
3
4
5
6
7
# 流式传输可以边生成边发送
Token 1-10:   生成 0.3  立即发送  用户看到
Token 11-20:  生成 0.3  立即发送  用户看到
...

# 非流式需要等全部生成完
Token 1-2048: 生成 10  一次性发送  用户才看到

流式输出的缺点 ❌

1. 实现复杂度高 ⭐⭐⭐⭐

需要多线程/异步处理

1
2
3
4
5
6
7
8
9
10
11
12
# 流式实现(复杂)
# 需要单独的线程来运行模型
thread = Thread(target=model.generate, kwargs=generation_kwargs)
thread.start()

# 主线程从streamer中读取结果
for new_text in streamer:
    yield new_text

# 非流式实现(简单)
output = model.generate(**kwargs)
return tokenizer.decode(output)  # 一行搞定 ✅

潜在问题:

  • 线程同步问题
  • 异常处理复杂
  • 资源清理困难
2. 难以进行整体后处理 ⭐⭐⭐⭐⭐
1
2
3
4
5
6
7
8
9
# 非流式:可以对完整文本进行处理
full_text = generate()
formatted_text = format_markdown(full_text)  # 格式化
cleaned_text = remove_errors(formatted_text)  # 清理
return cleaned_text  # ✅ 返回处理后的完美结果

# 流式:每个token立即返回,无法整体处理
for token in streamer:
    yield token  # ❌ 已经发出去了,无法修改

实际问题示例:

1
2
3
4
5
6
7
8
9
10
11
场景1:Markdown格式化
生成:"### 标题\n\n**加粗"  # 加粗标签不完整
返回:用户已经看到了           # ❌ 无法修正

场景2:敏感词过滤
生成:"这个方法很傻X"
返回:已经输出 "很傻"          # ❌ "X" 还没生成,无法提前过滤

场景3:代码块识别
生成:"```python\nprint("
返回:已经输出,无法确定是否是完整代码块
3. 错误处理非常困难 ⭐⭐⭐⭐
1
2
3
4
5
6
7
8
9
# 流式输出中途出错
输出"今天天气很好,我们来聊聊"
[突然报错CUDA out of memory]
结果用户看到半截内容体验不佳 

# 非流式出错
[生成过程出错]
返回"抱歉,生成失败,请重试"
结果用户收到清晰的错误提示 

回滚困难:

1
2
3
已输出:200个token
第201个token生成失败
问题:无法撤回前面200个token ❌
4. 无法提前知道内容长度 ⭐⭐⭐
1
2
3
4
5
6
7
8
9
10
// 前端问题
// 非流式:可以预留空间
<div style="height: 500px">  // 知道内容高度
  {full_content}
</div>

// 流式:高度不断变化
<div style="height: auto">   // 页面不断跳动
  {streaming_content}        // 用户体验可能不佳
</div>
5. 网络连接要求高 ⭐⭐⭐
1
2
3
4
5
6
7
# 流式需要保持长连接
连接时间30生成期间持续占用
网络要求稳定不能断开

# 非流式只需短连接
连接时间0.1传输结果
网络要求可以重试

问题场景:

1
2
3
用户网络不稳定:
流式:断开 → 内容丢失 → 需要重新生成 ❌
非流式:断开 → 重传结果 → 快速恢复 ✅
6. 难以缓存 ⭐⭐⭐
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 非流式:可以轻松缓存
cache_key = hash(user_input)
if cache_key in cache:
    return cache[cache_key]  # 立即返回 ✅
else:
    result = generate()
    cache[cache_key] = result  # 缓存完整结果
    return result

# 流式:缓存复杂
# 需要缓存token序列,且难以判断何时完成 ❌
for token in streamer:
    cache.append(token)  # 边生成边缓存?
    yield token
7. 并发处理复杂 ⭐⭐⭐
1
2
3
4
5
6
7
8
9
10
11
# 非流式:简单的请求队列
queue = [request1, request2, request3]
for req in queue:
    result = process(req)
    send(result)

# 流式:每个用户需要独立的streamer和线程
thread1 = Thread(streamer1)  # 用户1
thread2 = Thread(streamer2)  # 用户2
thread3 = Thread(streamer3)  # 用户3
# 资源消耗更大 ❌

完整对比表

维度流式输出非流式输出推荐
用户体验⭐⭐⭐⭐⭐ 极佳⭐⭐ 较差流式
感知延迟⭐⭐⭐⭐⭐ 很低⭐⭐ 很高流式
实现难度⭐⭐ 复杂⭐⭐⭐⭐⭐ 简单非流式
错误处理⭐⭐ 困难⭐⭐⭐⭐⭐ 简单非流式
后处理能力⭐ 几乎不可能⭐⭐⭐⭐⭐ 灵活非流式
内存效率⭐⭐⭐⭐ 高⭐⭐⭐ 一般流式
缓存能力⭐⭐ 困难⭐⭐⭐⭐⭐ 简单非流式
长文本生成⭐⭐⭐⭐⭐ 优秀⭐⭐ 较差流式
网络要求⭐⭐⭐ 较高⭐⭐⭐⭐ 低非流式
可中断性⭐⭐⭐⭐⭐ 可以⭐ 不可以流式

使用场景建议

适合使用流式输出:

1
2
3
4
5
6
✅ 对话式应用(聊天机器人)
✅ 长文本生成(文章、故事)
✅ 实时性要求高的应用
✅ 用户需要即时反馈
✅ 内容较长(>100 tokens)
✅ 交互式应用(可以随时打断)

适合使用非流式输出:

1
2
3
4
5
6
✅ API接口(需要整体返回)
✅ 批处理任务
✅ 需要后处理的内容(格式化、审核)
✅ 需要缓存的场景
✅ 短文本生成(<50 tokens)
✅ 需要稳定网络传输

混合方案:

1
2
3
4
5
6
7
8
# 根据内容长度自动选择
if max_new_tokens < 100:
    # 短文本:非流式
    return generate_complete()
else:
    # 长文本:流式
    for token in stream_generate():
        yield token

流式输出优化技巧

优化1:批量返回token
1
2
3
4
5
6
7
8
9
# 减少传输次数,提高效率
batch = []
for token in streamer:
    batch.append(token)
    if len(batch) >= 5:  # 每5个token一起返回
        yield ''.join(batch)
        batch = []
if batch:  # 返回剩余的
    yield ''.join(batch)
优化2:添加心跳机制
1
2
3
4
5
# 保持长连接稳定
for i, token in enumerate(streamer):
    yield token
    if i % 50 == 0:
        send_heartbeat()  # 每50个token发送心跳
优化3:错误恢复
1
2
3
4
5
6
7
8
9
# 优雅地处理异常
try:
    for token in streamer:
        yield token
except TimeoutError:
    yield "\n\n[生成超时,请重试]"
except Exception as e:
    yield f"\n\n[生成中断: {str(e)}]"
    logger.error(f"Stream error: {e}")
优化4:前端配合
1
2
3
4
5
6
7
8
9
10
11
// 自动滚动到底部
onTokenReceived = (token) => {
    appendText(token);
    scrollToBottom();  // 跟随最新内容
}

// 显示生成状态
<div>
    {streamingText}
    {isGenerating && <Spinner />}  // 显示正在生成
</div>

项目实现分析

本项目使用的流式实现(第665-689行):

1
2
3
4
5
6
7
8
9
10
11
12
streamer = TextIteratorStreamer(
    tokenizer=tokenizer, 
    skip_prompt=True,           # ✅ 自动跳过输入
    timeout=60.0,               # ✅ 设置超时
    skip_special_tokens=True    # ✅ 跳过特殊token
)

thread = Thread(target=model.generate, kwargs=generation_kwargs)
thread.start()  # ✅ 独立线程运行

for new_text in streamer:
    yield new_text  # ✅ 逐个返回

优点:

  • ✅ 用户体验好(打字机效果)
  • ✅ 适合对话场景
  • ✅ 支持长文本生成
  • ✅ 使用官方TextIteratorStreamer,稳定可靠

进一步改进建议:

1
2
3
4
5
6
7
8
9
10
11
# 添加更完善的异常处理
try:
    for new_text in streamer:
        if new_text:  # 过滤空字符串
            yield new_text
except TimeoutError:
    yield "\n[生成超时]"
except Exception as e:
    yield f"\n[错误: {str(e)}]"
finally:
    thread.join(timeout=5)  # 确保线程结束

总结

流式输出的核心价值:用户体验

  • 在对话应用中几乎是必需的 ⭐
  • 给用户”活着”的感觉
  • 符合现代AI助手的交互模式(ChatGPT、Claude等)

代价:实现和维护的复杂度

  • 需要处理并发、异常、网络等问题
  • 难以进行整体内容处理
  • 错误恢复较困难

本项目选择流式输出是正确的! 因为这是一个对话应用,用户体验是第一位的。打字机效果大大降低了用户的等待焦虑,提供了流畅的交互体验。


3.4 完整数据流示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
┌──────────────────────────────────────────────────────┐
│ 用户界面操作                                          │
├──────────────────────────────────────────────────────┤
│ 1. 拖动滑块: max_new_tokens = 3000                   │
│ 2. 输入: "帮我写一篇关于AI的文章"                    │
│ 3. 点击发送                                           │
└──────────────────────────────────────────────────────┘
                        ↓
┌──────────────────────────────────────────────────────┐
│ 后端处理流程                                          │
├──────────────────────────────────────────────────────┤
│                                                       │
│ 步骤1: 构建完整对话历史                              │
│ ┌─────────────────────────────────┐                │
│ │ conversation = [                 │                │
│ │   system: "你是AI助手...",       │                │
│ │   user: "你好",                  │                │
│ │   assistant: "你好!",           │                │
│ │   user: "帮我写一篇关于AI的文章" │  ← 新输入      │
│ │ ]                                │                │
│ └─────────────────────────────────┘                │
│                                                       │
│ 步骤2: Tokenize                                      │
│ ┌─────────────────────────────────┐                │
│ │ text → tokens                    │                │
│ │ input_ids = [1,2,3,...,1500]    │                │
│ │ (总共1500个token)                │                │
│ └─────────────────────────────────┘                │
│                                                       │
│ 步骤3: 模型生成                                      │
│ ┌─────────────────────────────────┐                │
│ │ model.generate(                  │                │
│ │   input_ids=[1,...,1500],       │                │
│ │   max_new_tokens=3000           │                │
│ │ )                                │                │
│ │                                  │                │
│ │ 自回归生成3000个新token:         │                │
│ │ [1501,1502,1503,...,4500]       │                │
│ └─────────────────────────────────┘                │
│                                                       │
│ 步骤4: 流式输出(skip_prompt=True)                 │
│ ┌─────────────────────────────────┐                │
│ │ streamer只返回:                  │                │
│ │ [1501,1502,...,4500]            │                │
│ │ (跳过了input_ids部分)            │                │
│ └─────────────────────────────────┘                │
│                                                       │
│ 步骤5: 解码为文本                                    │
│ ┌─────────────────────────────────┐                │
│ │ "AI是人工智能的缩写..."          │                │
│ │ (约2200个中文字)                 │                │
│ └─────────────────────────────────┘                │
│                                                       │
└──────────────────────────────────────────────────────┘
                        ↓
┌──────────────────────────────────────────────────────┐
│ 前端显示                                              │
├──────────────────────────────────────────────────────┤
│ 打字机效果逐字显示:                                  │
│ "AI是人工智能的缩写,代表着..."                      │
└──────────────────────────────────────────────────────┘

附录:快速参考表

Token限制对照表

模型上下文默认输出最大输出适用场景
GPT-3.54K2K4K短对话
GPT-48K-128K2K-4K8K全场景
Claude 3200K4K4K长文档分析
Qwen2.532K-128K2K8K中文对话
Llama 38K2K4K开源部署

显存需求速查表

模型FP16Int8Int4推荐显卡
1.5B4GB2GB1GBGTX 1660+
7B16GB8GB5GBRTX 3090
13B32GB16GB10GBRTX 4090

参数调优速查表

参数范围默认值效果
temperature0.1-2.00.7越低越确定,越高越创意
top_p0.1-1.00.9核采样阈值
top_k1-10050候选词数量
repetition_penalty1.0-2.01.1避免重复
max_new_tokens50-81922048输出长度

总结

关键要点

  1. 模型命名:遵循”系列-规模-训练类型-量化方法”的规则
  2. Instruct模型:对话应用必选,能理解和执行指令
  3. 上下文长度:决定能记住多少对话历史
  4. 流式输出:提供打字机效果,大幅提升用户体验
本文由作者按照 CC BY 4.0 进行授权