【大模型应用-知识整理】240922内容分享

【大模型应用】240922内容分享

[TOC]

一、如何从零构建一个大模型

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
# 内容来源:橙篇


一、确定目标和需求
首先,需要明确大模型的构建目标和应用场景。这包括确定模型将用于哪些任务(如自然语言处理、图像识别、语音识别等),以及期望的性能指标和输出形式。
例子:假设我们的目标是构建一个用于自然语言处理(NLP)的大模型,用于回答用户的问题和生成文本。

二、收集数据
大模型的训练需要大量的数据作为支撑。这些数据应该涵盖各种主题、语境、语法结构和风格,以确保模型的泛化能力。
例子:对于NLP大模型,我们需要收集各种来源的文本数据,如新闻报道、学术论文、社交媒体内容、书籍等。这些数据应该被清洗、去噪并转换成适合模型训练的格式。

三、数据预处理
在将数据输入模型之前,需要进行一系列预处理操作,如分词、去停用词、词嵌入等。这些操作有助于将原始文本转换为模型可以理解和处理的形式。
例子:对于NLP大模型,我们可以使用分词工具将文本切分成词语或子词单元,并去除停用词以减少噪声。同时,可以使用词嵌入技术将词语转换为高维向量,以便模型捕捉词语之间的语义关系。

四、选择模型架构
根据任务需求和可用资源选择合适的模型架构。常见的模型架构包括循环神经网络(RNN)、长短期记忆网络(LSTM)、Transformer等。
例子:对于NLP大模型,我们可以选择基于Transformer的架构,如GPT(Generative Pre-trained Transformer)系列模型。这些模型在自然语言生成和理解方面表现出色,并且具有强大的泛化能力。

五、配置训练环境
准备训练所需的硬件和软件环境,包括高性能计算资源(如GPU集群)、深度学习框架(如TensorFlow、PyTorch)和必要的库(如NumPy、Pandas等)。
例子:为了训练一个大型的NLP模型,我们需要一个具有多个GPU的服务器集群,并安装PyTorch或TensorFlow等深度学习框架。同时,我们还需要安装各种必要的库和工具,以便进行数据处理和模型训练。

六、训练模型
使用预处理后的数据和选定的模型架构进行模型训练。训练过程可能涉及多个阶段,包括预训练和微调。
例子:对于NLP大模型,我们可以首先使用大规模的无标签文本数据进行预训练,以学习通用的语言表示。然后,使用有标签的数据对模型进行微调,以适应特定的任务需求。训练过程中需要监控模型的性能指标,并调整超参数以优化模型性能。

七、评估和调优
使用验证集或测试集评估模型的性能,并根据评估结果进行模型调优。调优可能涉及调整模型架构、超参数或训练策略等。
例子:在NLP大模型的评估阶段,我们可以使用标准的测试集来评估模型的性能,如准确率、召回率、F1分数等。根据评估结果,我们可以对模型进行微调以改善性能。这可能包括调整模型的层数、注意力机制的设置或学习率等超参数。

八、部署和应用
将训练好的模型部署到实际应用中,并监控其性能以确保稳定运行。同时,根据用户反馈和实际需求进行模型更新和迭代。
例子:对于NLP大模型的应用,我们可以将其部署到问答系统、文本生成系统或对话系统中。在实际应用中,我们需要监控模型的响应速度和准确性,并根据用户反馈进行必要的更新和优化。

总结
从零构建一个大模型是一个复杂而系统的过程,涉及多个阶段和多个方面的知识和技能。
通过明确目标和需求、收集数据、数据预处理、选择模型架构、配置训练环境、训练模型、评估和调优以及部署和应用等步骤,我们可以逐步构建出具有强大性能和应用价值的大模型。在实际操作中,需要根据具体情况灵活调整和优化各个步骤中的策略和参数。

二、数据预操作处理详析

1. 分词(Tokenization)

1
2
3
分词是将文本拆分成独立的单词、短语、符号或其他有意义的最小单位
对于英文等使用空格分隔的语言,分词相对简单,只需按空格切分即可
但对于中文等不使用空格分词的语言,分词难度较大,需要使用分词工具如 Jieba 来完成。

示例:

  • 原始文本(中文):大唐不夜城是西安市的一处著名景点。
  • 分词结果:['大唐不夜城', '是', '西安市', '的', '一处', '著名', '景点', '。']
  • 原始文本(英文):Natural language processing is a fascinating field.
  • 分词结果:['Natural', 'language', 'processing', 'is', 'a', 'fascinating', 'field', '.']

2. 去停用词(Stop Words Removal)

1
2
停用词是指那些在特定语言中使用频率很高但对文本含义贡献较少的词语,如中文的“的”、“是”、“在”或英文的“the”、“is”、“in”等。
去除这些词语有助于减少文本噪音,提高模型的性能。

示例:

  • 分词结果(中文):['大唐不夜城', '是', '西安市', '的', '一处', '著名', '景点', '。']
  • 去停用词结果:['大唐不夜城', '西安市', '著名', '景点']
  • 分词结果(英文):['Natural', 'language', 'processing', 'is', 'a', 'fascinating', 'field', '.']
  • 去停用词结果:['Natural', 'language', 'processing', 'fascinating', 'field']

3. 词嵌入(Word Embedding)

1
2
词嵌入是将单词转换为具有固定维度的稠密向量,以便模型能够理解和处理。词嵌入方法包括 Word2Vec、GloVe、BERT 等。
每个单词被表示为一个实数向量,向量之间的距离可以反映单词的语义相似性。

示例:

  • 假设分词结果为:['大唐不夜城', '西安市', '著名', '景点']

  • 词嵌入结果(每个词映射为一个维度为 3 的向量):

    1
    2
    3
    4
    arduino复制代码'大唐不夜城' -> [0.23, 0.45, -0.12]
    '西安市' -> [0.67, 0.98, -0.34]
    '著名' -> [0.11, -0.09, 0.56]
    '景点' -> [0.37, 0.12, 0.42]

4. 词形还原(Lemmatization)与词干提取(Stemming)

1
2
3
4
词形还原是将单词还原为其基本形式(如动词的原形),
而词干提取则是将单词截断为词干。
词形还原能保留更多的词汇信息,
而词干提取可能会截断得过于简单,但处理速度较快。

示例:

  • 原始文本(英文):running, ran, runs
  • 词形还原结果:run
  • 词干提取结果:run

三、模型架构详析

1. 循环神经网络(RNN, Recurrent Neural Network)

1
2
3
4
5
RNN 是一种用于处理序列数据的神经网络,能够有效地捕捉序列中的上下文关系。
它的特点是具有“记忆”功能,能够将前一时刻的输出和当前输入结合起来影响当前的输出。
RNN 的核心特性是能够通过隐藏状态(hidden state)来捕捉序列中的时间依赖性。
RNN 会在序列的每一个时间步(time step)上使用相同的网络参数,并通过隐藏状态将前一时间步的信息传递给下一时间步。
RNN 适合处理时间序列、文本等依赖于上下文顺序的数据。
工作流程
  • 输入层:输入序列的每个元素逐个输入网络。
  • 隐藏层:每个时间步的隐藏状态是由当前输入和前一时间步的隐藏状态共同决定的。
  • 输出层:最终的隐藏状态或所有时间步的隐藏状态可以用于预测输出。
优缺点
  • 优点:适合处理时间序列数据(如天气预测、股票预测)和自然语言数据(如文本生成、语音识别)。
  • 缺点:在长序列中,容易出现梯度消失或梯度爆炸问题,难以捕捉长时间依赖关系。
举例
  • 应用于文本生成任务,如给定一段文本前面的若干个单词,预测下一个单词。

2. 长短期记忆网络(LSTM)

1
2
LSTM 是 RNN 的一种变体,用于解决 RNN 的梯度消失问题。
LSTM 引入了三个门(input gate、forget gate、output gate)和一个细胞状态(cell state),通过门控机制来控制信息的流动,从而可以更好地捕捉长时间依赖。
工作流程
  • 输入门(Input Gate):决定当前输入信息的重要性。
  • 遗忘门(Forget Gate):决定细胞状态中哪些信息需要被遗忘。
  • 输出门(Output Gate):决定哪些信息会被输出作为隐藏状态。
优缺点
  • 优点:能够捕捉长时间的依赖关系,适合长序列的处理,如机器翻译、问答系统、语音生成。
  • 缺点:相比 RNN 更加复杂,训练时间较长,计算开销较大。
举例

应用于机器翻译任务,例如给定英文句子“Hello world”,预测对应的中文句子“你好,世界”。

3. Transformer

1
2
3
Transformer 是一种基于自注意力(Self-Attention)机制的序列到序列模型架构。
与 RNN 和 LSTM 不同,Transformer 不依赖于序列的顺序处理数据,而是通过自注意力机制能够同时关注序列中的所有位置。
它由编码器(Encoder)和解码器(Decoder)组成。
工作流程
  • 自注意力机制(Self-Attention):每个位置的表示向量与其他位置的表示向量进行交互,捕捉全局信息。
  • 多头注意力(Multi-Head Attention):使用多个注意力机制头来捕捉不同的语义信息。
  • 位置编码(Position Encoding):加入位置信息来保持序列的顺序性。
优缺点
  • 优点:并行计算效率高,适合处理长序列,效果优于 RNN 和 LSTM,适用于各种自然语言处理任务,如机器翻译、文本摘要、情感分析等。
  • 缺点:模型参数多,计算资源需求较大。
举例

应用于机器翻译任务,如“Hello world”到“你好,世界”的翻译。Transformer 在这类任务中往往比 LSTM 表现更好。

4. 如何选择模型架构

  • 如果任务涉及较短的序列数据,且对资源要求较低,可以选择 RNN。

  • 如果任务要求捕捉长时间的依赖关系,如长文本或长时间序列数据,且资源充足,LSTM 是更好的选择。

  • 如果任务对精度要求高且计算资源丰富,尤其是处理长序列数据或复杂自然语言任务(如机器翻译、大规模文本生成等),Transformer 是首选。

四、模型训练环境详析

1. 高性能计算资源(如 GPU 集群)

1.1 GPU(图形处理单元)
1
2
GPU 是专为并行计算设计的硬件,最初用于图像处理,但现在广泛应用于深度学习和科学计算。
与 CPU 相比,GPU 可以更高效地处理大规模矩阵运算,非常适合训练神经网络。
优势
  • 并行计算能力强:能够同时处理大量计算任务,非常适合训练需要大量矩阵运算的深度学习模型。
  • 高效的浮点运算能力:在神经网络训练中,涉及大量的浮点数计算,GPU 的多核架构可以快速完成这些任务。
例子
  • NVIDIA 的 Tesla、A100、V100 系列是专为深度学习设计的高性能 GPU。
1.2 GPU 集群
1
2
GPU 集群是由多个 GPU 设备组成的计算集群,用于处理超大规模的深度学习任务。
集群中的 GPU 可以并行协作,加快训练速度,特别适合大规模模型或大数据集的训练任务。
优势
  • 扩展性好:多个 GPU 可以协同工作,提升训练速度。
  • 大模型训练:对于一些需要大量计算资源的大模型(如 GPT-3),只有通过 GPU 集群才能在合理的时间内完成训练。
例子
  • 亚马逊 AWS 的 EC2 P3 实例、谷歌的 TPU Pods 以及 NVIDIA 的 DGX 系列都提供了 GPU 集群服务。

2. 深度学习框架

2.1 TensorFlow
1
2
TensorFlow 是 Google 开发的一个开源深度学习框架。
它支持多平台、多设备的高效计算,并且拥有强大的生态系统和丰富的工具集。
特点
  • 灵活性高:支持静态图(静态计算图)和动态图(Eager Execution)模式,可以根据需求选择不同的计算方式。
  • 生态系统完善:拥有 TensorBoard(可视化工具)、TensorFlow Serving(部署)等丰富的工具。
例子

用于各种计算机视觉任务(如图像分类、目标检测)、自然语言处理任务(如文本生成、情感分析)等。

2.2 PyTorch
1
PyTorch 是由 Facebook 开发的深度学习框架,以动态计算图和灵活性著称,近年来在学术界和工业界都非常流行。
特点
  • 动态图机制:计算图可以在运行时动态构建,便于调试和实验,特别适合研究人员和快速原型开发。
  • 直观性强:代码风格接近 Python,便于理解和使用。
例子

用于自然语言处理(如 BERT、GPT 系列模型)、计算机视觉(如 ResNet、YOLO)等任务。

3. 必要的Python库

3.1 NumPy
1
NumPy 是 Python 中的基础科学计算库,提供了高效的多维数组(ndarray)操作和各种数学函数。
特点
  • 多维数组支持:高效的多维数组(ndarray)操作。
  • 丰富的数学函数:支持矩阵运算、线性代数、统计学函数等。
例子

在深度学习中用于数据预处理,如归一化、矩阵运算等。

3.2 Pandas
1
Pandas 是一个强大的数据分析和数据处理库,提供了便捷的数据结构(如 DataFrame)和数据操作工具。
特点
  • 数据处理便捷:支持数据清洗、转换、聚合等操作。
  • 与其他库兼容性好:可以与 NumPy、Matplotlib 等库很好地结合使用。
例子

用于数据分析和特征工程,如从 CSV 文件中读取数据、数据清洗、缺失值处理等。

4. 实际训练大模型的基本流程

  1. 选择硬件资源:根据模型的大小和数据集的规模,选择合适的硬件资源,如单个 GPU、多个 GPU 或 GPU 集群。

    自分の感受:在本地电脑使用云服务器(3090Ti)部署的大模型可以跑,但是跑的速度比较慢

    类似ChatGPT和kimi这种可以迅速做出反应的模型,应该就是在GPU集群上面跑的:)

  2. 配置软件环境:安装所需的深度学习框架(如 TensorFlow、PyTorch)和辅助库(NumPy、Pandas 等)。

  3. 数据预处理:使用 Pandas、NumPy 等库对数据进行预处理,包括数据清洗、归一化、数据增强等操作。

  4. 构建模型:使用深度学习框架构建神经网络模型,包括定义模型结构、损失函数和优化器。

  5. 训练模型:将预处理后的数据输入模型,进行训练过程,包括前向传播、计算损失、反向传播、更新权重等步骤。

  6. 评估模型:在测试集上评估模型的性能,如准确率、损失值等。

  7. 部署模型:将训练好的模型部署到生产环境中,供用户使用。

五、模型训练详析

以下内容结合现在的任务情况:已经以xlsx的形式收集了数据,怎么放到云服务器部署的大模型中

1. 数据预处理

1
将原始数据处理为模型能够理解的格式
  1. 读取xlsx文件
1
2
3
4
# 使用 pandas 库读取 Excel 文件,将数据转为 DataFrame 格式

import pandas as pd
data = pd.read_excel('your_file.xlsx')
  1. 数据清洗
1
2
3
4
5
# 移除无效数据、重复数据,填充缺失值
# 去除 HTML 标签、特殊符号等噪声数据

data = data.dropna() # 删除缺失值
data = data.drop_duplicates() # 删除重复值
  1. 数据格式转换
1
2
3
4
5
# 将数据转为文本格式,并根据任务需求组织为问答对、上下文-问题对等

# 假设你的数据包含 "问题" 和 "回答" 两列
questions = data['问题'].tolist()
answers = data['回答'].tolist()
  1. 文本分词和标注(可选)
1
2
3
4
5
# 对文本数据进行分词处理,或者进行其他特定的标注,如 NER(命名实体识别)
# 可以使用 jieba 等分词工具

import jieba
data['分词文本'] = data['原始文本'].apply(lambda x: ' '.join(jieba.cut(x)))

2. 预训练(Pre-training)

1
预训练是指在大规模无标签数据上训练语言模型,让模型学习通用的语言表示
1. 使用现有的预训练模型
  • Langchain Chatchat框架中可能已经包含了预训练的模型,比如 GPT 系列模型
  • 可以直接加载这些模型进行微调
2. 自行预训练(不推荐初学者)
  • 如果有大规模无标签数据(如维基百科、开源书籍等),可以在这些数据上从头开始训练模型。但这需要非常高的计算资源

3. 微调(Fine-tuning)

1
微调是将预训练的语言模型应用到特定任务上的过程
  1. 数据准备
1
2
3
4
# 将预处理好的问答对(或其他形式的数据)分为训练集和验证集

from sklearn.model_selection import train_test_split
train_data, val_data = train_test_split(data, test_size=0.2)
  1. 定义训练脚本
1
2
3
4
5
6
7
8
9
10
11
12
13
# 使用 Langchain 或 Hugging Face 的 transformers 库定义模型和训练参数

from transformers import GPT2LMHeadModel, GPT2Tokenizer, Trainer, TrainingArguments

model_name = "gpt2"
tokenizer = GPT2Tokenizer.from_pretrained(model_name)
model = GPT2LMHeadModel.from_pretrained(model_name)

def tokenize_function(examples):
return tokenizer(examples["text"], padding="max_length", truncation=True)

# 假设 data 是一个有 “text” 列的 DataFrame
tokenized_data = data.map(tokenize_function, batched=True)
  1. 训练模型
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 设置训练参数并启动训练。可以使用 GPU 集群加速训练

training_args = TrainingArguments(
output_dir="./results",
evaluation_strategy="epoch",
learning_rate=2e-5,
per_device_train_batch_size=4,
per_device_eval_batch_size=4,
num_train_epochs=3,
weight_decay=0.01,
)

trainer = Trainer(
model=model,
args=training_args,
train_dataset=train_data,
eval_dataset=val_data,
)

trainer.train()
  1. 保存模型
1
2
3
4
# 将微调后的模型保存,以便后续使用

model.save_pretrained("fine_tuned_model")
tokenizer.save_pretrained("fine_tuned_model")

4. 模型评估

1
在验证集上评估模型性能,如困惑度(Perplexity),并根据结果调整超参数(如学习率、批大小等),以优化模型性能
评估指标
  • 困惑度(Perplexity):评估生成模型对数据的拟合程度。
  • 准确率(Accuracy)、F1 值(F1-score):评估分类模型的表现。
模型调优
  • 通过观察损失值的变化、验证集上的性能指标,调整模型的超参数或数据预处理策略。

5. 实际应用建议

1
2
你可以将大唐不夜城的问答数据集用于微调一个 GPT 模型,使得模型能够回答关于该旅游景点的具体问题。
在 Langchain Chatchat 的框架中,可以使用微调后的模型作为回答模块,通过 API 与前端交互,实现智能问答功能。

六、问答对生成建议

来自ChatGPT,但是具体实现还要进行调整

1. 数据理解与提取

1
先对已有数据进行理解和提取,以确定内容的类别和结构,然后根据大类和小类生成问题
1.1 数据理解
  • 大类:可能是“历史背景”、“文化意义”、“地理位置”、“著名景点”等。

  • 小类:可能是某个景点的具体描述、某个事件的历史背景等。

1.2 数据提取
1
2
3
4
5
6
7
8
9
10
# 使用 pandas 库读取 xlsx 文件,将数据整理为适合处理的格式

import pandas as pd

# 读取Excel文件
data = pd.read_excel('datang_baike.xlsx')

# 假设大类为'Category',小类为'Subcategory',内容为'Content'
categories = data['Category'].unique()
subcategories = data['Subcategory'].unique()

2. 生成问答对

1
根据每个小类生成问答对
2.1 基本问答对生成
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 对每一个小类,根据内容生成标准问题和答案。
# 生成问题:可以从小类的名称或内容中提取,比如“小雁塔的历史背景是什么?”
# 生成答案:从小类的内容字段中提取答案。


# 生成问答对
qa_pairs = []

for idx, row in data.iterrows():
question = f"{row['Subcategory']}是什么?"
answer = row['Content']
qa_pairs.append({"question": question, "answer": answer})

# 将问答对保存为DataFrame
qa_df = pd.DataFrame(qa_pairs)
2.2 使用模板生成多种问题
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import random

# 定义一些常见的提问模板
templates = [
"{subcategory}的详细信息是什么?",
"你能告诉我一些关于{subcategory}的事情吗?",
"介绍一下{subcategory}。",
"{subcategory}有什么特别的?"
]

# 生成多个相似问题
expanded_qa_pairs = []

for idx, row in data.iterrows():
for template in templates:
question = template.format(subcategory=row['Subcategory'])
answer = row['Content']
expanded_qa_pairs.append({"question": question, "answer": answer})

# 保存到DataFrame
expanded_qa_df = pd.DataFrame(expanded_qa_pairs)

3. 相似问题生成

3.1 基于规则的同义句生成
  • 将问题中某些词替换为同义词,或使用不同的提问方式。
  • 例如:“大唐不夜城在哪里?” -> “请问大唐不夜城位于什么地方?”
3.2 使用自然语言处理工具
  • 使用 NLP 工具(如 nltkspaCy 等)或深度学习模型(如 transformers 中的 paraphrase 模型)生成多种相似问题
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from transformers import pipeline

# 使用Hugging Face的paraphrase模型
paraphrase_model = pipeline("paraphrase-multilingual-mpnet-base-v2")

# 生成相似问题
def generate_similar_questions(question):
similar_questions = paraphrase_model(question)
return [item['generated_text'] for item in similar_questions]

# 示例:生成问题的多种形式
question = "大唐不夜城有什么景点?"
similar_questions = generate_similar_questions(question)

print(similar_questions)

4. 存储入数据库

1
2
将生成的问答对和相似问题存储到数据库中,
可以选择 MySQL、SQLite 或 MongoDB 等数据库系统
4.1 关系型数据库(如MySQL)
1. 表结构设计
  • questions 表:存储原始问题及其类别、小类等信息

  • similar_questions 表:存储相似问题及其对应的原始问题 ID

2. 插入数据
  • 使用 pandasto_sql 方法将 DataFrame 直接插入到数据库中
1
2
3
4
5
6
7
8
import pymysql
from sqlalchemy import create_engine

# 建立数据库连接
engine = create_engine('mysql+pymysql://username:password@localhost/dbname')

# 将问答对和相似问题插入数据库
expanded_qa_df.to_sql('questions', con=engine, if_exists='replace', index=False)
4.2 文档型数据库(如MongoDB)
  1. 文档结构设计
  • question_document:包含原始问题、相似问题列表、答案等信息
  1. 插入数据
  • 使用 pymongo库将数据插入到 MongoDB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from pymongo import MongoClient

# 建立MongoDB连接
client = MongoClient("mongodb://localhost:27017/")
db = client['datang_db']
collection = db['questions']

# 插入问答对
for idx, row in expanded_qa_df.iterrows():
document = {
"question": row['question'],
"answer": row['answer'],
"similar_questions": generate_similar_questions(row['question'])
}

collection.insert_one(document)

5. 总结

1
2
3
4
数据预处理:使用 pandas 对 Excel 文件中的内容进行整理
问答对生成:根据小类内容生成标准问答对,使用模板生成多种形式的问题
相似问题生成:使用 NLP 工具生成问题的多种相似形式
存储到数据库:根据应用场景选择适合的数据库,将问答对和相似问题存储

七、数据库的选择(MySQL / MongoDB)

1. MySQL

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
- 优点
- 结构化数据:适合有【明确表结构和关系】的场景,如用户信息、交易记录等
- 事务支持:支持【事务操作】,适用于需要数据一致性的场景
- 复杂查询:支持复杂的 SQL 查询、JOIN 操作,适合【数据间关系复杂】的情况
- 数据完整性:通过外键约束、数据类型限制等机制保障【数据一致性和完整性】

- 缺点
- 【扩展性有限】:水平扩展(sharding)较为复杂
- 【灵活性不如】文档型数据库:对于不规则数据或数据结构经常变动的情况不太适合

- 适用场景
- 数据表结构清晰,字段和表之间关系明确
- 需要复杂的查询操作,比如 JOIN、聚合等
- 需要保证数据的一致性和完整性
- 数据不经常发生结构上的变化

2. MongoDB

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
- 优点
- 【灵活性强】:不需要预定义表结构,数据字段可以动态增加和改变,适合结构不固定的数据
- 水平扩展性好:天然支持分片(sharding),适合【大规模数据的存储和管理】
- 文档模型:使用 JSON/BSON 格式存储,查询和更新数据更灵活,尤其【适合嵌套结构的存储和查询】
- 适合大数据量:可以轻松【处理海量数据和高并发读写请求】

- 缺点
- 复杂查询支持不如关系型数据库:不支持传统 SQL 的 JOIN 操作,复杂查询需要设计合理的数据模型
- 缺乏事务性(较新版本已经支持多文档事务):对于强一致性要求较高的场景不太适合
- 数据冗余问题:数据的去规范化设计(如嵌套文档)可能导致数据冗余

- 适用场景
- 【数据结构不固定】,字段和层次变化多,比如用户行为数据、日志数据、内容管理系统等
- 【高并发读写操作】,如实时数据、在线应用的后台
- 【数据规模大】,且需要横向扩展
- 不需要复杂的跨表查询,或者可以通过嵌套文档结构代替关联关系

3. 针对项目需求的推荐

来自:ChatGPT

项目特点
1
2
3
4
5
6
7
8
旅游信息数据:
大唐不夜城的旅游信息数据,可能包括景点介绍、历史背景、文化故事等,内容较为多样化,数据结构可能不完全统一
问答对生成:
你希望生成多种形式的问答对和相似问题,这意味着数据的生成和变动比较频繁
查询需求:
前端可能需要根据不同关键词、类别、景点名称进行查询,且需要支持一定的灵活查询
扩展性:
后期可能会增加更多景点或景区的数据,需要数据库有一定的扩展能力
推荐
1
2
3
4
5
综合考虑你的需求,我会推荐使用 MongoDB,理由如下:

灵活的数据结构:景点描述、历史背景等数据字段可能变化较大,MongoDB 能够更好地适应这种不固定的结构
适合大数据量存储:如果你打算未来增加更多的旅游数据,MongoDB 的水平扩展能力会更好
文档模型易于查询:每个景点的信息可以存储为一个完整的文档,不同字段如“景点名称”、“历史背景”、“问答对”等都可以在一个文档中管理,查询时更加直观和方便

提问:是不是要换成MongoDB更好?

八、评估和调优详析

1. 评估模型性能

1.1 数据集划分
  • 训练集:用于训练模型的数据
  • 验证集:用于在训练过程中监控模型性能,帮助选择最佳模型
  • 测试集:独立的数据集,用于最终评估模型的性能
1
2
3
4
5
6
7
8
9
10
# 从现有的问答对数据集中随机划分出 70% 用于训练,20% 用于验证,10% 用于测试

from sklearn.model_selection import train_test_split

# 读取已生成的问答对数据
data = pd.read_excel('datang_baike_qa_pairs.xlsx')

# 划分训练集、验证集、测试集
train_data, temp_data = train_test_split(data, test_size=0.3, random_state=42)
val_data, test_data = train_test_split(temp_data, test_size=0.33, random_state=42) # 20%验证集, 10%测试集
1.2 评估指标

对于问答对生成和问答系统,常用的评估指标包括:

  • 准确率(Accuracy):回答正确的比例。

    • 适用于分类任务。
  • 召回率(Recall):模型能找到所有正确答案的比例。

    • 适用于存在较多负样本的场景。
  • 精确率(Precision):模型预测正确答案的比例。

    • 适用于需要关注结果精确性的场景。
  • F1分数:精确率和召回率的调和平均值.

    • 适用于需要平衡两者的场景。
  • BLEU分数:评估生成文本的质量.

    • 衡量生成的问题是否与目标问题语义接近。
  • 示例:假设你有一个生成问答对的模型,使用 F1 分数来评估模型生成的问答是否与目标问答相匹配。

1
2
3
4
5
6
7
8
9
from sklearn.metrics import f1_score

# 假设模型预测的答案和实际答案如下
y_true = ["大唐不夜城是一个历史文化主题公园", "位于西安"]
y_pred = ["大唐不夜城是一个历史文化公园", "在西安"]

# 计算F1分数
f1 = f1_score(y_true, y_pred, average='micro')
print(f"F1 Score: {f1}")

2. 模型调优

  • 根据评估结果,对模型进行调优,包括但不限于模型架构、超参数和训练策略等
2.1 模型架构调优

使用的是 LangChain Chatchat 大模型框架,可能需要关注以下几个方面:

  • 层数和单元数:适当增加或减少模型的层数和单元数,以找到最佳的模型容量。

  • 注意力机制:调整注意力头数、多头注意力机制等,以提升模型对问答对关系的捕捉能力。

  • 示例:假设你在使用一个基础的 BERT 模型进行问答对生成,你可以通过增加模型的层数、增加注意力头数来尝试提升性能。

1
2
3
4
5
6
7
8
9
10
from transformers import BertConfig, BertModel

# 使用自定义的BERT配置
config = BertConfig(
hidden_size=768, # 增加模型的隐藏层大小
num_attention_heads=12, # 增加注意力头数
num_hidden_layers=12 # 增加模型层数
)

model = BertModel(config)
2.2 超参数调优

超参数调优是提升模型性能的关键步骤,可以使用以下几种方法:

  • 学习率(Learning Rate):调整学习率,过大或过小都会影响模型的收敛效果
  • 批次大小(Batch Size):较大的批次大小可能提升训练效率,但可能导致模型欠拟合
  • 训练轮次(Epochs):增加或减少训练轮次,避免过拟合或欠拟合

示例:可以使用 GridSearchCVRandomSearchCV 来自动化地搜索超参数组合

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
from sklearn.model_selection import GridSearchCV
from keras.models import Sequential
from keras.layers import Dense


# 定义模型架构
def build_model(optimizer='adam', init='glorot_uniform'):
model = Sequential()
model.add(Dense(12, input_dim=8, kernel_initializer=init, activation='relu'))
model.add(Dense(8, kernel_initializer=init, activation='relu'))
model.add(Dense(1, kernel_initializer=init, activation='sigmoid'))
model.compile(loss='binary_crossentropy', optimizer=optimizer, metrics=['accuracy'])
return model


# 定义超参数组合
param_grid = {
'batch_size': [10, 20, 40],
'epochs': [10, 50, 100],
'optimizer': ['SGD', 'Adam'],
'init': ['glorot_uniform', 'normal']
}


# 实例化GridSearchCV
model = KerasClassifier(build_fn=build_model, verbose=0)
grid = GridSearchCV(estimator=model, param_grid=param_grid, n_jobs=-1, cv=3)
grid_result = grid.fit(X, y)


# 输出最佳结果
print(f"Best: {grid_result.best_score_} using {grid_result.best_params_}")
2.3 训练策略调整

在训练过程中,你可以调整一些策略来提高模型性能:

  • 学习率调整策略:使用学习率调度器(如 ReduceLROnPlateau)动态调整学习率
  • 正则化方法:使用 Dropout 或权重衰减来防止过拟合
  • 数据增强:通过数据增强技术(如同义词替换)增加数据多样性,提高模型鲁棒性

示例:在 PyTorch 中使用学习率调度器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import torch
from torch.optim import Adam
from torch.optim.lr_scheduler import ReduceLROnPlateau

# 定义优化器
optimizer = Adam(model.parameters(), lr=0.001)

# 定义学习率调度器
scheduler = ReduceLROnPlateau(optimizer, 'min', patience=3, factor=0.1)

# 在训练循环中使用调度器
for epoch in range(epochs):
train_loss = train_epoch(model, train_loader, optimizer)
val_loss = validate_epoch(model, val_loader)

# 更新学习率
scheduler.step(val_loss)

3. 示例:结合项目进行调优

评估模型性能
  • 使用生成的问答对和相似问题对模型进行评估,计算精确率、召回率和 F1 分数
  • 对于相似问题的生成,使用 BLEU 分数衡量模型生成问题的语义相似度
调优策略
  • 模型架构调整:根据评估结果,增加或减少模型的层数,并尝试不同的预训练模型(如 RoBERTa、GPT 等)
  • 超参数调优:调整学习率、批次大小、训练轮次,尝试不同的优化器(如 AdamW、SGD 等)
  • 训练策略调整:使用动态学习率调度、添加 Dropout 层防止过拟合、增加训练数据的多样性
实际应用
  • 如果模型在某些类型的问题上表现不佳,可以针对这些类型的数据进行数据增强或微调
  • 如果生成的相似问题质量不高,可以尝试不同的生成模型或增强生成策略(如使用预训练的 T5 模型)

4. 总结

1
2
3
4
5
6
模型评估:
根据任务需求选择适合的评估指标,如 F1 分数、BLEU 分数等
模型调优:
通过调整模型架构、超参数和训练策略,提高模型性能
示例应用:
结合你的项目实际需求,针对性地进行调优策略调整

九、将微调后的模型作为回答模块并通过API与前端交互

1
2
3
4
5
6
7
8
9
10
11
12
13
在 Langchain Chatchat 框架中,将微调后的模型作为回答模块并通过 API 与前端交互,实现智能问答功能,主要涉及以下几个步骤:

微调模型:
使用大唐不夜城的问答数据对基础语言模型进行微调

集成微调模型:
将微调后的模型集成到Langchain Chatchat框架中,作为回答模块

构建 API 接口:
使用 Flask、FastAPI 或 Django 等框架搭建 RESTful API 服务,使前端能够通过 HTTP 请求与后端模型交互

前后端交互:
前端通过发送用户问题到 API 接口,后端调用微调模型生成回答并返回前端

1. 微调模型

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
# 假设你已经使用大唐不夜城的数据对预训练模型(如 BERT、GPT)进行了微调,并保存了微调后的模型

from transformers import Trainer, TrainingArguments, AutoModelForQuestionAnswering

# 加载预训练模型和数据集
model_name = "bert-base-uncased"
model = AutoModelForQuestionAnswering.from_pretrained(model_name)
# 假设微调的数据已经准备好
train_dataset = ...

# 设置训练参数
training_args = TrainingArguments(
output_dir='./results',
num_train_epochs=3,
per_device_train_batch_size=16,
per_device_eval_batch_size=16,
warmup_steps=500,
weight_decay=0.01,
logging_dir='./logs',
logging_steps=10,
)

# 创建 Trainer 对象
trainer = Trainer(
model=model,
args=training_args,
train_dataset=train_dataset,
eval_dataset=val_dataset
)

# 开始微调
trainer.train()
# 保存微调后的模型
model.save_pretrained("./fine_tuned_model")

2. 集成微调模型到Langchain Chatchat

1. 将微调模型加载到 Langchain Chatchat
1
2
3
4
5
6
7
8
# 在 Langchain Chatchat 的回答模块中加载微调后的模型

from transformers import AutoTokenizer, AutoModelForQuestionAnswering

# 加载微调后的模型
model_path = "./fine_tuned_model"
tokenizer = AutoTokenizer.from_pretrained(model_path)
model = AutoModelForQuestionAnswering.from_pretrained(model_path)
2. 定义回答模块
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 在 Chatchat 中定义一个回答模块,该模块将接收用户问题,并调用微调模型生成答案

class QAAnsweringModule:
def __init__(self, model, tokenizer):
self.model = model
self.tokenizer = tokenizer

def get_answer(self, question, context):
inputs = self.tokenizer(question, context, return_tensors="pt")
outputs = self.model(**inputs)
# 提取答案逻辑
answer_start = torch.argmax(outputs.start_logits) # 答案开始位置
answer_end = torch.argmax(outputs.end_logits) # 答案结束位置
answer = self.tokenizer.decode(inputs.input_ids[0][answer_start:answer_end+1])
return answer
3. 创建回答模块实例
1
qa_module = QAAnsweringModule(model, tokenizer)

3. 构建API接口

1
使用 Flask 或 FastAPI 框架创建 RESTful API 接口,将 Langchain Chatchat 集成到 API 中
1. 使用 FastAPI 创建接口
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
from fastapi import FastAPI, Request
from pydantic import BaseModel

app = FastAPI()

# 定义请求数据模型
class QuestionRequest(BaseModel):
question: str
context: str # 用于提供上下文,如关于大唐不夜城的详细描述

# 定义 API 路由,接收前端请求并返回答案
@app.post("/qa")
async def get_answer(request: QuestionRequest):
question = request.question
context = request.context
answer = qa_module.get_answer(question, context)
return {"answer": answer}
2. 启动 FastAPI 服务器
1
uvicorn app:app --host 0.0.0.0 --port 8000

4. 前后端交互

1. 前端发送请求
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 前端通过 HTTP 请求向 FastAPI 发送用户问题和上下文,并接收返回的答案

async function askQuestion(question, context) {
const response = await fetch("http://localhost:8000/qa", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({ question: question, context: context })
});
const data = await response.json();
return data.answer;
}

// 使用示例
const question = "大唐不夜城的开放时间是什么时候?";
const context = "大唐不夜城位于西安市,是一个以唐代文化为主题的文化旅游区...";
askQuestion(question, context).then(answer => console.log("答案: ", answer));
2. 后端处理请求
1
2
3
4
5
6
7
8
9
# FastAPI 接收到请求后,调用 Langchain Chatchat 的回答模块生成答案并返回给前端 

@app.post("/qa")
async def get_answer(request: QuestionRequest):
question = request.question
context = request.context
# 调用微调后的模型获取答案
answer = qa_module.get_answer(question, context)
return {"answer": answer}
3. 前端展示结果
  • 前端将返回的答案显示在用户界面上,用户可以看到由微调模型生成的智能回答

5. 结合项目示例

1
2
3
4
5
6
7
8
9
10
11
12
13
假设你已经有大唐不夜城的问答对数据,将以下步骤应用到你的项目中:

- 微调模型:用大唐不夜城的数据集(xlsx 文件)微调 BERT 或 GPT 模型

- 模型集成:将微调后的模型加载到 Langchain Chatchat 框架中,创建一个自定义的回答模块

- 构建 API 接口:使用 FastAPI 构建 RESTful API 接口,将问答模块暴露为 Web 服务

- 前端交互:
- 用户在前端输入问题,如“大唐不夜城的门票价格是多少?”
- 前端将用户问题通过 API 请求发送到后端
- 后端微调模型处理问题,返回答案给前端
- 前端将答案展示给用户

十、全程开发流程规划(来自:ChatGPT)

1
基于你的实际项目情况,我们可以详细规划大模型应用的全程开发流程。以下是结合 Django + Vue + ElementUI + MySQL(或 MongoDB)的开发流程,以及如何集成微调后的 Langchain Chatchat 模型,并实现前后端交互
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
1. 项目环境配置
1.1 硬件环境
GPU 服务器:确保 AutoDL 云服务器配置了必要的 GPU 资源,并已安装 Langchain Chatchat 社区镜像
操作系统:建议使用 Ubuntu 18.04 或更高版本

1.2 软件环境
后端:
Python 3.8+:用于 Django 开发
Django 3.x/4.x:用于后端 API 开发
FastAPI(可选):可以单独用于模型微服务接口开发
Langchain Chatchat:集成微调后的大模型
MySQL/MongoDB:选择合适的数据库存储问答数据
SQLAlchemy(如果使用 MySQL):ORM 框架
PyMongo(如果使用 MongoDB):数据库操作工具
前端:
Vue 2.x/3.x:前端框架
ElementUI:Vue 的 UI 组件库,用于构建界面
axios:前端 HTTP 库,用于与后端 API 交互

1.3 环境配置
- 安装依赖:安装 Python、Django、FastAPI、数据库驱动(如 pymysql、pymongo)
- 设置虚拟环境:
python3 -m venv venv
source venv/bin/activate
pip install django fastapi sqlalchemy pymysql pymongo
- Django 项目创建:
django-admin startproject my_project
cd my_project
django-admin startapp api
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
2. 数据预处理与模型微调
2.1 数据预处理
- 读取 xlsx 数据:提取大唐不夜城的问答对数据
- 数据清洗:去除空值、重复值等
- 格式转换:将数据转换为模型训练所需的格式,如 JSON、CSV 等

import pandas as pd

# 读取xlsx文件
df = pd.read_excel('data/datang_questions.xlsx')

# 数据清洗
df = df.dropna() # 去除空值

# 将数据转换为列表格式
qa_pairs = df[['问题', '答案']].to_dict(orient='records')

# 保存为JSON
import json
with open('data/qa_pairs.json', 'w') as f:
json.dump(qa_pairs, f)


2.2 模型微调
- 选择模型:基于任务需求,选择 BERT、GPT 等模型
- 数据集划分:将数据分为训练集、验证集和测试集
- 训练与微调:
- 加载预训练模型和分词器
- 训练时选择合适的超参数(如学习率、batch size)


from transformers import Trainer, TrainingArguments, AutoModelForQuestionAnswering

# 加载预训练模型和数据集
model_name = "bert-base-chinese"
model = AutoModelForQuestionAnswering.from_pretrained(model_name)
tokenizer = ...

# 设置训练参数
training_args = TrainingArguments(
output_dir='./results',
num_train_epochs=3,
per_device_train_batch_size=16,
logging_dir='./logs',
)

# 创建 Trainer 对象
trainer = Trainer(
model=model,
args=training_args,
train_dataset=train_dataset,
eval_dataset=val_dataset
)

# 开始训练
trainer.train()
model.save_pretrained("./fine_tuned_model")
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
3. 模型集成与 API 接口开发
3.1 Django 后端
创建 API 应用:
- 在 Django 项目中创建 api 应用,用于管理所有 API 接口
- 配置 urls.py 路由
定义模型接口:
- 使用 Django REST framework 创建模型 API 接口
- 或使用FastAPI独立创建模型微服务,并通过 Django 请求调用


# 在 Django 中使用 FastAPI
from fastapi import FastAPI
from .models import QAAnsweringModule # 微调后的模型集成

app = FastAPI()

# 创建问答模块实例
qa_module = QAAnsweringModule(model, tokenizer)

# 定义 API 路由
@app.post("/api/qa/")
async def get_answer(request: QuestionRequest):
question = request.question
context = request.context
answer = qa_module.get_answer(question, context)
return {"answer": answer}

数据库操作:
- 如果使用 MySQL,定义 Django 模型并使用 ORM 操作数据库
- 如果使用 MongoDB,配置 PyMongo 连接,操作数据库
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
    3.2 前端交互
创建 Vue 项目:
- 使用 Vue CLI 创建前端项目
- 安装 ElementUI 组件库
设计前端页面:
- 使用 ElementUI 设计用户输入和答案显示界面
- 使用 axios 向 Django 后端发送请求

import axios from 'axios';

// 问答请求函数
async function askQuestion(question, context) {
const response = await axios.post("http://localhost:8000/api/qa/", {
question: question,
context: context
});
return response.data.answer;
}
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
	前端页面逻辑:
- 用户输入问题后,调用 askQuestion(),将结果显示在页面上

<template>
<div>
<el-input v-model="question" placeholder="请输入您的问题"></el-input>
<el-button @click="submitQuestion">提交</el-button>
<p>答案:{{ answer }}</p>
</div>
</template>

<script>
export default {
data() {
return {
question: '',
answer: ''
};
},
methods: {
async submitQuestion() {
this.answer = await askQuestion(this.question, "大唐不夜城相关背景信息");
}
}
};
</script>
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
4. 部署与测试
后端部署:
使用 Gunicorn 和 Nginx 部署 Django 应用
如果使用 FastAPI 微服务,使用 Uvicorn 部署

前端部署:
构建 Vue 项目,生成静态文件,放置到 Django static 文件夹中

测试与调优:
测试前后端接口连通性,确保 API 能正确响应
根据用户反馈或测试结果,调整模型和前后端逻辑

5. 数据库选择与优化
MySQL:适合结构化数据的存储,支持复杂查询和事务操作
MongoDB:适合非结构化或半结构化数据,数据模式灵活
选择建议:
如果问答数据结构稳定,关系明确,使用 MySQL
如果需要存储灵活的文档格式,使用 MongoDB

6. 总结
结合你的项目需求,以下是一个完整的开发流程:
- 配置环境,预处理数据并微调模型【当前还在这个流程】
- 在 Django 中集成微调模型,构建 API 接口
- 使用 Vue + ElementUI 开发前端页面,并实现与后端 API 的交互
- 部署项目,并不断调优,最终实现智能问答系统
  • Copyrights © 2024-2025 brocademaple
  • 访问人数: | 浏览次数:

      请我喝杯咖啡吧~

      支付宝
      微信