NLP基础
·
自然语言处理(NLP)基础
一、NLP概览
二、文本表示
2.1 为什么需要文本表示?
核心问题:计算机只能处理数字,如何把文字变成数字?
2.2 文本表示演进
2.3 One-Hot编码
理解:每个词用一个独热向量表示,只有一个位置是1。
词表: ["我", "爱", "AI", "学习"]
"我" → [1, 0, 0, 0]
"爱" → [0, 1, 0, 0]
"AI" → [0, 0, 1, 0]
"学习" → [0, 0, 0, 1]
问题:
- 维度等于词表大小(可能几十万)
- 无法表达语义相似性("猫"和"狗"距离一样远)
2.4 词向量(Word Embedding)
理解:把每个词映射到一个低维稠密向量,语义相近的词距离更近。
经典方法:
| 方法 | 原理 | 特点 |
|---|---|---|
| Word2Vec | 预测上下文词 | 高效,但无上下文 |
| GloVe | 全局词共现矩阵 | 统计信息 |
| FastText | 字符级n-gram | 处理未登录词 |
2.5 上下文相关Embedding
理解:同一个词在不同语境下有不同的向量表示。
实现方式:BERT等模型根据上下文动态生成Embedding。
三、核心NLP任务
3.1 文本分类
理解:给定文本,预测其类别。
应用场景:
- 情感分析(评论、舆情)
- 意图识别(智能客服)
- 内容审核(违规检测)
3.2 命名实体识别(NER)
理解:从文本中识别出特定类型的实体。
3.3 机器翻译
理解:将文本从一种语言翻译成另一种语言。
3.4 文本生成
理解:根据输入生成连贯的文本。
生成方式:自回归生成,一个词一个词地预测。
四、NLP技术发展历程
4.1 RNN时代
4.2 Transformer革命
核心创新:用注意力机制替代循环结构。
| 特性 | RNN | Transformer |
|---|---|---|
| 计算方式 | 串行 | 并行 |
| 长距离依赖 | 困难 | 直接连接 |
| 训练效率 | 较慢 | 快 |
| 可扩展性 | 有限 | 可扩展到千亿参数 |
五、大语言模型(LLM)
5.1 LLM的基本原理
5.2 GPT系列演进
5.3 涌现能力
理解:当模型规模超过某个阈值后,突然出现的新能力。
六、提示工程(Prompt Engineering)
6.1 什么是提示工程?
理解:通过设计输入提示词来引导模型生成期望的输出。
6.2 提示工程技巧
| 技巧 | 说明 | 示例 |
|---|---|---|
| 明确角色 | 指定模型扮演的角色 | “你是一个资深工程师…” |
| 提供示例 | 给出输入输出样例 | “示例:输入A→输出B” |
| 分步引导 | 拆解复杂任务 | “第一步…第二步…” |
| 约束输出 | 限定输出格式 | “用JSON格式返回” |
| 思维链 | 引导推理过程 | “让我们一步步思考” |
6.3 提示模板示例
你是一个{{角色}},擅长{{技能}}。
任务:{{具体任务}}
要求:
- {{要求1}}
- {{要求2}}
输出格式:{{格式说明}}
示例:
输入:{{示例输入}}
输出:{{示例输出}}
七、NLP应用架构
7.1 典型应用架构
7.2 RAG架构
RAG(检索增强生成):先检索相关信息,再让模型基于检索结果生成回答。
后端类比:
RAG ≈ 带缓存的API调用
1. 用户请求 → 检查缓存(向量检索)
2. 缓存命中 → 直接使用缓存数据
3. 缓存未命中 → 查询数据库(LLM生成)
4. 合并结果 → 返回给用户
八、常见NLP任务实现
8.1 任务与模型选择
| 任务 | 推荐模型 | 说明 |
|---|---|---|
| 文本分类 | BERT/RoBERTa | 理解能力强 |
| 命名实体识别 | BERT+CRF | 序列标注 |
| 文本生成 | GPT系列 | 自回归生成 |
| 问答系统 | RAG+LLM | 检索增强 |
| 文本嵌入 | Sentence-BERT | 语义相似度 |
| 机器翻译 | mT5/NLLB | 多语言支持 |
8.2 开发工具推荐
| 工具 | 用途 | 特点 |
|---|---|---|
| Hugging Face Transformers | 模型调用 | 丰富的预训练模型 |
| LangChain | LLM应用开发 | 链式调用、工具集成 |
| LlamaIndex | RAG开发 | 知识库构建 |
| OpenAI API | 商业应用 | 简单易用 |
九、后端工程师实践建议
9.1 NLP服务设计考量
9.2 常见坑与解决方案
| 问题 | 解决方案 |
|---|---|
| 幻觉(胡说八道) | 提供上下文、要求引用来源 |
| 输出不稳定 | 降低temperature、提供示例 |
| 上下文太长 | 使用RAG、分段处理 |
| 响应慢 | 流式输出、异步处理 |
| 成本高 | 缓存、使用更小模型 |
十、NLP代码实战
10.1 文本向量化示例
使用Transformers获取词向量
💻 对应脚本:
3.1.text_embedding_bert.py
"""
BERT文本向量化示例
=================
使用Transformers获取中文文本的词向量和句子向量
依赖安装: pip install transformers torch
运行: python text_embedding_bert.py
"""
from transformers import AutoTokenizer, AutoModel
import torch
def main():
# 1. 加载预训练模型(使用中文BERT)
model_name = 'bert-base-chinese'
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModel.from_pretrained(model_name)
# 2. 文本预处理
text = "人工智能正在改变世界"
inputs = tokenizer(text, return_tensors='pt', padding=True, truncation=True)
print(f"分词结果: {tokenizer.tokenize(text)}")
print(f"Token IDs: {inputs['input_ids']}")
# 3. 获取词向量
with torch.no_grad():
outputs = model(**inputs)
# last_hidden_state: 每个token的向量表示 (batch_size, seq_len, hidden_size)
embeddings = outputs.last_hidden_state
print(f"向量形状: {embeddings.shape}") # (1, 序列长度, 768)
# 4. 获取句子向量(使用[CLS]token或平均池化)
cls_embedding = embeddings[:, 0, :] # [CLS] token的向量
mean_embedding = embeddings.mean(dim=1) # 平均池化
print(f"[CLS]向量形状: {cls_embedding.shape}") # (1, 768)
print(f"平均池化向量形状: {mean_embedding.shape}")
# 5. 计算句子相似度
def get_sentence_embedding(text):
inputs = tokenizer(text, return_tensors='pt', padding=True, truncation=True)
with torch.no_grad():
outputs = model(**inputs)
return outputs.last_hidden_state.mean(dim=1).squeeze()
def cosine_similarity(vec1, vec2):
return torch.nn.functional.cosine_similarity(
vec1.unsqueeze(0), vec2.unsqueeze(0)
).item()
sentences = [
"我喜欢吃苹果",
"苹果很好吃",
"今天天气不错",
]
embeddings_list = [get_sentence_embedding(s) for s in sentences]
print("\n=== 句子相似度 ===")
print(f"'{sentences[0]}' vs '{sentences[1]}': "
f"{cosine_similarity(embeddings_list[0], embeddings_list[1]):.4f}")
print(f"'{sentences[0]}' vs '{sentences[2]}': "
f"{cosine_similarity(embeddings_list[0], embeddings_list[2]):.4f}")
if __name__ == "__main__":
main()
输出示例:
分词结果: ['人', '工', '智', '能', '正', '在', '改', '变', '世', '界']
Token IDs: tensor([[ 101, 782, 1057, 3168, 5686, 3731, 1762, 2841, 1290, 102]])
向量形状: torch.Size([1, 12, 768])
[CLS]向量形状: torch.Size([1, 768])
平均池化向量形状: torch.Size([1, 768])
=== 句子相似度 ===
'我喜欢吃苹果' vs '苹果很好吃': 0.8923
'我喜欢吃苹果' vs '今天天气不错': 0.5421
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)