2025-07-28 09:54:49
飞桨 (PaddlePaddle)是百度自研的深度学习平台,集深度学习核心训练和推理框架、基础模型库、端到端开发套件和丰富的工具组件于一体,对标国外的 Pytorch 和 Tensorflow。
由于飞桨各个模块组件更偏底层,为了方便AI学习者和开发者在线使用、训练、部署各种模型,基于飞桨平台百度又推出了AI Studio(https://aistudio.baidu.com/index)。AI Studio 是一个集教学资源、算力、开发工具和社区生态于一体的在线 AI 模型开发平台,对标国外的 HuggingFace,其实国内也有类似的社区平台modelscope(https://www.modelscope.cn/home)。顺带一提,百度还有一个历史悠久的千帆平台,也可以满足大模型在线训练和使用。
进到 AI Studio 首页之后,最重要的是要点击右上角的小电脑图标,它显示了你拥有的算力信息,选择预训练模型时,也要注意算力和 Paddle 版本的对应关系,比如选用Tesla V100显卡,算力只有 7.0,支持不了最新版 Paddle 的一些底层函数,建议选择 A/H100以上的显卡。
ERNIE支持 alpaca 和 erniekit 两种数据集格式。alpaca 格式是 HuggingFace 社区流行的一种对话式监督数据格式,采用JSON行格式,强调instruction(指令)+ input + output。ERNIEKit 格式是百度 PaddlePaddle 社区用于训练 ERNIE 模型的格式,更注重内部结构化字段。
本次微调我们使用erniekit格式,源数据来自百度2025LIC 赛事的示例数据(https://aistudio.baidu.com/datasetdetail/345031),经过清洗之后,格式如下图所示。
数据准备好之后,我们就可以开始下一步微调(finetune)大模型了,我们这次选用的预训练模型是文心大模型 4.5 开源系列中最小的大模型ERNIE-4.5-0.3B,总大小 700M 左右。
首先,安装适配 CUDA 12.6 的 PaddlePaddle GPU 版本(3.1.0),并使用中国镜像源以加速下载。如果你还不确定你电脑的 CUDA 版本,可以使用nvidia-smi
查看。
!python -m pip install paddlepaddle-gpu==3.1.0 -i https://www.paddlepaddle.org.cn/packages/stable/cu126/
# 检验是否安装成功
!python -c "import paddle;paddle.utils.run_check()"
ERNIE是百度在 PaddlePaddle 上开发的一个中文为主的预训练语言模型,文心一言后面的大模型就是ERNIE。
!git clone https://github.com/PaddlePaddle/ERNIE.git
%cd ERNIE-develop
!python -m pip install -r requirements/gpu/requirements.txt
!python -m pip install -e .
FastDeploy是百度开发的一个模型部署工具,可以快速启动一个带有大模型后端的Web 服务。
!python -m pip install fastdeploy-gpu -i https://www.paddlepaddle.org.cn/packages/stable/fastdeploy-gpu-80_90/ --extra-index-url https://mirrors.tuna.tsinghua.edu.cn/pypi/web/simple
接着需要下载 ERNIE-4.5-0.3B 模型。这里需要额外安装 aistudio-sdk
Python 包,这个下载服务并未集成在 ERNIE 的安装包中,这一点确实有些令人费解。
!pip install --upgrade aistudio-sdk
# 使用aistudio cli下载模型(推荐)
!aistudio download --model PaddlePaddle/ERNIE-4.5-0.3B-Paddle --local_dir baidu/ERNIE-4.5-0.3B-Paddle
修改配置文件,使用官方的模版就行,改一下参数train_dataset_path
和eval_dataset_path
,其他保持不变。
### data
train_dataset_type: "erniekit"
eval_dataset_type: "erniekit"
train_dataset_path: "./examples/data/finetune_train_dataset.jsonl"
train_dataset_prob: "1.0"
eval_dataset_path: "./examples/data/finetune_eval_dataset.jsonl"
eval_dataset_prob: "1.0"
max_seq_len: 8192
num_samples_each_epoch: 6000000
### model
model_name_or_path: baidu/ERNIE-4.5-0.3B-Paddle
fine_tuning: LoRA
fuse_rope: True
use_sparse_head_and_loss_fn: True
### finetuning
# base
stage: SFT
seed: 23
do_train: True
do_eval: True
distributed_dataloader: False
dataloader_num_workers: 1
batch_size: 1
num_train_epochs: 1
max_steps: 100
max_evaluate_steps: 10000
eval_steps: 10000
evaluation_strategy: steps
save_steps: 10000000
save_total_limit: 5
save_strategy: steps
logging_steps: 1
release_grads: True
gradient_accumulation_steps: 8
logging_dir: ./vdl_log
output_dir: ./output
disable_tqdm: True
# train
warmup_steps: 20
learning_rate: 1.0e-5
lr_scheduler_type: cosine
min_lr: 1.0e-6
layerwise_lr_decay_bound: 1.0
# optimizer
weight_decay: 0.1
adam_epsilon: 1.0e-8
adam_beta1: 0.9
adam_beta2: 0.95
offload_optim: True
# performance
tensor_parallel_degree: 1
pipeline_parallel_degree: 1
sharding_parallel_degree: 1
sharding: stage1
sequence_parallel: True
pipeline_parallel_config: enable_delay_scale_loss enable_release_grads disable_partial_send_recv
recompute: False
recompute_use_reentrant: True
compute_type: bf16
fp16_opt_level: O2
disable_ckpt_quant: True
amp_master_grad: True
amp_custom_white_list:
- lookup_table
- lookup_table_v2
- flash_attn
- matmul
- matmul_v2
- fused_gemm_epilogue
amp_custom_black_list:
- reduce_sum
- softmax_with_cross_entropy
- c_softmax_with_cross_entropy
- elementwise_div
- sin
- cos
unified_checkpoint: True
unified_checkpoint_config: async_save
微调的方法有很多,这里我们使用 LoRA(低秩适配),主要因为这次训练使用的训练集比较少。
实际结果跑下来,一共 2629条训练数据,花了大概 3 分钟就训练完了
!erniekit train examples/configs/ERNIE-4.5-0.3B/sft/run_sft_lora_8k.yaml
!erniekit export examples/configs/ERNIE-4.5-0.3B/run_export.yaml lora=True
模型微调并导出后,即可进行部署。
!erniekit server examples/configs/ERNIE-4.5-0.3B/run_chat.yaml
!erniekit chat examples/configs/ERNIE-4.5-0.3B/run_chat.yaml
微调前,模型在回答医疗相关问题时显得有些冗长。经过训练后,面对同样的问题,模型的回答风格变得更加简洁干脆。当然,也有一些问题的回答仍有待提升。
在 AI Studio 平台进行开发时,建议选择在线 VS Code 开发模式。如果使用在线 Notebook,可能会频繁遇到文件找不到等服务不稳定的情况。
尽管平台提供了在线学习资源,但许多教程内容过于简化,甚至有些项目不兼容 macOS 系统(例如 PP - ASR),部分视频资源的音量也忽大忽小,整体使用体验不尽如人意。
不过,抛开这些产品体验,具体函数的执行效果上,还是不错的。百度似乎仍在坚持 “技术狂奔,产品拉胯” 的发展路径。
2025-06-19 10:12:10
2021 年 OpenAI 在推出 1750 亿参数的 GPT-3 模型的时候,也推出了 120 亿参数的 DALL·E模型和几亿参数的 CLIP 模型,这两个模型都是多模态模型(不仅可以处理文本还可以处理图片)。
然而,这两者的类型和应用场景有所不同。DALL·E模型是生成式模型,它学习数据的分布并能生成新的数据样本,与 GPT 系列异曲同工。而 CLIP 模型则属于判别式模型,它旨在学习数据之间的区分边界,主要用于分类和判断,但不能生成新样本。具体来说,DALL·E模型的核心功能是根据文本生成图像,常见于封面设计等场景;CLIP 模型则主要用于计算文本与图像的相似度,广泛应用于图像搜索和文案推荐。
CLIP 是一种多模态模型,它通过对比学习来对齐文本和图像,也就是把文本和图像映射到同一个空间中,比如提到“狗”这个文本的时候,通过 embedding 对应高维空间的一个点,而提到一个包含有狗的图像的时候,通过 embedding 也会对应同一个空间的点,CLIP 的目标是让这两个对应的点尽可能接近。
CLIP 模型由图像编码器(通常是 ViT 或 ResNet)和文本编码器(Transformer)组成,在训练这个模型的时候,图像编码器负责把一张图片映射到空间中的某一点,文本编码器负责把一段文字映射到空间中的某一点。每次训练拿出 n 张图片和对应的文字,n 张图片丢给图像编码器产出 In,n 段文字丢给文本编码器产出 Tn,我们定义损失函数为对应的(In,Tn)要越像越好,也就是内积相乘越大越好,对应的就是图中蓝色部分。而其余部分则希望它们的相似度尽可能低,通过内积值越接近 0 来表示(图中灰色部分)。
在使用 CLIP 模型的时候,我们给出几段文字和一张图片,CLIP 模型会计算图像嵌入与每一段文本嵌入在共享空间中的相似度(内积值),并输出与图像最接近的文本(即内积值最大的文本)。
同理,我们也可以给出多张图片和一段文字描述,从而得到与该文字描述最接近的图片。例如,知名的图片网站 Unsplash 就是利用 CLIP 模型实现了其全站图片检索功能。
CLIP 模型以其快速的计算速度和对不同类型图片内容出色的泛化识别能力而著称。然而,它的主要缺点在于对图像中细节的识别能力相对较弱。例如,在以下以图搜图的场景中,将一张正在缫丝的图片传递给不同模型时,CLIP 模型可能仅能捕捉到这是一种 “手工艺活动”,而无法识别出具体的精细缫丝过程,这与一些更专业的模型DINO-v2 和 BLIP2有所不同。
我们将选择一个本地图片文件夹,遍历目录下所有图片并通过 CLIP 建立 Embedding。然后,通过一段文本或一张图片进行检索查询,找出最相似的前 5 张图片。
from sentence_transformers import SentenceTransformer
import random
import glob,os
from PIL import Image
import matplotlib.pyplot as plt
#图片目录
image_folder = 'xxx/xx'
# 使用CLIP模型构建特征
def generate_clip_embeddings(images_path, model):
image_paths = glob.glob(os.path.join(images_path, '**/*.jpg'), recursive=True)
embeddings = []
for img_path in image_paths:
image = Image.open(img_path)
embedding = model.encode(image)
embeddings.append(embedding)
return embeddings, image_paths
model = SentenceTransformer('clip-ViT-B-32')
embeddings, image_paths = generate_clip_embeddings(image_folder, model)
import faiss
import numpy as np
# FAISS 构建索引
features = np.array(embeddings).astype(np.float32)
faiss.normalize_L2(features)
vector_dim = features.shape[1]
index = faiss.IndexFlatIP(vector_dim)
index.add(features)
# 图片查询:选一张图(或上传图)再计算 embedding 作为查询向量
# query_image = Image.open('xxxx/feiji.jpeg')
# query_vector = model.encode(query_image)
# query_vector = np.array(query_vector).reshape(1, -1).astype(np.float32)
# faiss.normalize_L2(query_vector)
# 文本查询
query_text = "一辆自行车"
query_vector = model.encode(query_text) # 使用同一个模型对文本编码
query_vector = np.array(query_vector).reshape(1, -1).astype(np.float32)
faiss.normalize_L2(query_vector)
# 搜索最相似的图片
top_k = 5
distances, ann = index.search(query_vector, k=top_k)
# 显示搜索结果
for i, idx in enumerate(ann[0]):
print(f"Top {i+1} match: {image_paths[idx]} (Score: {distances[0][i]:.4f})")
2025-06-13 09:57:45
近两年当人们谈起 LLM 的时候,似乎已经和 AI 画上了等号,但是 LLM 其实只是 AI 领域的一个重要组成部分。
自然语言处理(NLP)是人工智能领域一个重要分支,它主要研究内容和方向有:分词(Tokenization)、文本分类(Text Classification)、情感分析(Sentiment Analysis)、实体命名(Named Entity Recognition)、文本摘要(Topic Modeling)。上面所有这些研究方向底层的技术基础都是从 RNN 神经网络发展而来,在此基础上又产生了基于encoder-decoder 结构的Seq2seq 模型。
然而,RNN 在处理长文本时存在固有的缺陷:它会逐步计算每个词元(token)之间的依赖关系,这不仅会导致长文本信息丢失或遗忘,而且每一步计算都必须顺序进行,无法实现并行运算。
2017 年 Google 发布了 Transformer 架构,Transformer 是一种基于自注意力机制的神经网络架构,它的目标是处理序列资料,特别擅长处理长距离的元素依赖相关性,而且可以并行运算。Transformer 由两部分组成:编码器(encoder)和解码器(decoder),其结构无疑借鉴了 Seq2seq 模型,并成功克服了 RNN 的内在缺点。 以 Transformer 架构为基础,各家公司开始开发自家的模型。2018年当时最火的还是Google 的 BERT模型,BERT模型其实是一个理解式的模型,而 OpenAI 的 GPT是一个生成式的模型,使用的是 decode-only 的结构。其他的语言模型大多数采用的是编码器加解码器这种方式,编码器负责理解,解码器负责输出。 2022 年OpenAI 推出的 GPT3模型,其中的参数量达到了千亿级别,而且实际的测试效果碾压当时市面上的所有模型,真正实现了“大力出奇迹”,大语言模型(LLM) 的时代来临了。 随后,Meta 推出了 LLaMA 系列,Google 发布了 Gemini 系列,国内的深度求索推出了 DeepSeek 系列,阿里巴巴也推出了 Qwen 系列。一时间,各类大型语言模型百花齐放,共同推动着 AI 领域的飞速发展。
在 LLM 的基础上,许多产品得以封装并广泛应用。其中,ChatGPT 是最广为人知的产品之一,国内也有豆包、通义千问、文心一言等同类产品。除了通过产品界面直接使用 LLM,我们还可以通过代码的方式灵活调用 LLM。
以下是使用 GPT-3.5-turbo 模型和 DeepSeek-R1 模型的代码示例:
from langchain_openai import ChatOpenAI
from langchain_core.messages import SystemMessage, HumanMessage
llm = ChatOpenAI(
api_key=env_settings.OPENAI_API_KEY,
model_name="gpt-3.5-turbo",
base_url='https://burn.hair/v1'
)
ai_message = llm.invoke([
SystemMessage(content="please speak in chinese"),
HumanMessage(content="hello"),
])
print(ai_message.content)
#输出:你好!有什么可以帮助你的吗?
from langchain_core.messages import SystemMessage, HumanMessage
from langchain_deepseek import ChatDeepSeek
llm = ChatDeepSeek(
api_key=env_settings.DS_API_KEY,
model="deepseek-ai/DeepSeek-R1",
temperature=0,
max_tokens=None,
timeout=None,
max_retries=2,
api_base='https://api.siliconflow.cn'
)
ai_message = llm.invoke([
SystemMessage(content="please speak in chinese"),
HumanMessage(content="hello"),
])
print(ai_message.content)
# 你好!😊 有什么可以帮您的吗?