背景

2025年08月31日,参加了个AI深度学习workshop,记录和复盘一下整个workshop例子。

环境准备

  • 显卡:L20

    因为手上有算力资源,本次记录就不使用AutoDL租借算力,本次使用L20,顺便完善一下yolo11环境,方便以后训练复用,同时也顺便测一下与4090的算力情况。

  • 训练环境:yolo11环境搭建
  • 视觉模块:reCamera 摄像头 $49.90刀
    • 缺点:我觉得像素还是上不了生产,还不如一个高清摄像头。
    • 优点:小,不仅仅一个摄像头,相当于一个边缘设备,可以独立部署上去。整合了工作流,可以快速部署监测模型。

实践

数据集准备

首先到 roboflow 找一份数据集,这次复盘记录我选一个螺丝数据集吧,毕竟这个reCamera的外观有一点工业风,就拿工业场景来做比较合适。

数据训练

前面准备了yolo11环境搭建,我们开始在这个yolo11环境开始训练。

模型量化与格式转换

  • 工具安装

    我们使用docker

    1
    2
    3
    4
    5
    # 拉取镜像并启动容器
    docker pull sophgo/tpuc_dev:v3.1
    docker run --privileged --name reCamera_dev -v $PWD:/workspace -it sophgo/tpuc_dev:v3.1
    #容器内安装工具包 tpu_mlir
    pip install tpu_mlir[all]==1.7 -i https://mirrors.aliyun.com/pypi/simple

    上面方法慢的话:

    1
    2
    3
    4
    5
    wget https://sophon-assets.sophon.cn/sophon-prod-s3/drive/25/04/15/16/tpuc_dev_v3.4.tar.gz
    docker load -i tpuc_dev_v3.4.tar.gz
    docker run --privileged --name reCamera_dev -v $PWD:/workspace -it sophgo/tpuc_dev:v3.4
    #容器内安装工具包 tpu_mlir
    pip install tpu_mlir[all]==1.7 -i https://mirrors.aliyun.com/pypi/simple
  • 格式转换

    之所以要进行格式转换,因为不同的部署平台的架构不一样,支持的的格式不一

    • reCamera 基于RISC-V架构
      • ONNX→MLIR转换→cvimodel量化

部署与测试

  • 使用reCamera测试
  • 在本地电脑部署测试
  • 在手机端部署测试

场景思考

  • 深度学习在供应链中的应用

相关链接

ReCamera AI模型转换与量化全流程指南

基础搭建

  • 创建虚拟环境

    1
    conda create -n yolo11 python=3.11 -y 
  • 安装ultralytics

    我们使用源代码进行安装

    1
    2
    3
    git clone https://github.com/ultralytics/ultralytics.git
    cd ultralytics
    pip install -e .

    这段命令会安装你下载的ultralytics,安装完成后pip list你就会发现包会有一个路径,就表示安装成功了。

    1
    ultralytics              8.3.193     /home/ultralytics

  • 安装pytorch

  • 验证,推理

目标

探索使用MCP与商品结合的场景,让大模型能回答和理解用户的产品需求并获得需要的产品信息。

  • 用户问答搜索产品场景
    • 根据关键字搜索产品详情。
    • 最热门商品
  • 用户问答根据用户个性化推荐场景
    • 根据用户ID推荐商品。

注意数据为mock,根据需要对接数据库或者其他数据来源即可。

实践

编写MCP服务程序

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
# 引入 fastmcp 包
from fastmcp import FastMCP
# 创建一个mcp服务
mcp = FastMCP("ProductServer")

# 定义工具,也就是实际执行的内容,类似于 RestAPI 中的 POST,mcp主要的能力都在这里体现。

# 定义根据关键字keyword搜索产品详情的工具函数
@mcp.tool()
def search_produc_by_keyword(keyword):
"""search product by keyword"""
# mock data
return {"product_name":"小米SU7 Ultra", "price": 529999, "category": "Car"}

# 定义获取热门商品的工具函数
@mcp.tool()
def get_popular_products():
"""List of popular products"""
# mock data
hot_products = ('[{"product_name":"iPhone 14 Pro Max", "price": 5999, "category": "Electronics"},'
'{"product_name":"小米SU7 Ultra", "price": 529999, "category": "Car"},'
'{"product_name":"红米K80", "price": 2399, "category": "Electronics"}]')

return hot_products


# 定义为指定用户获取推荐商品的工具函数
@mcp.tool()
def get_recommended_products(user_id):
"""Products recommended for users"""
# mock data
recommended_products = '{"product_name":"小米SU7 Ultra", "price": 529999, "category": "Car"}'
return recommended_products


if __name__ == "__main__":
mcp.run(transport='stdio')

运行mcp,验证一下是否能正常运行,确认能正常后,我们在Cherry Studio中配置一下mcp

1
fastmcp run main.py

在Cherry Studio中配置MCP

  • 在命令中填写 uv
  • 填写参数

    注意 /{PATH}/fastmcp/为这个mcp的项目路径

    1
    2
    3
    4
    --directory
    /{PATH}/fastmcp/
    run
    main.py
    其实组合起来就是 uv --directory /{PATH}/fastmcp/ run main.py,即跑起来文件项目
    JrtIR3

配置好后,我们可以看到工具中已经 包含了

  • search_produc_by_keyword 根据关键字搜索产品
  • get_popular_products 获取热门商品
  • get_recommended_products 获取推荐商品
    RIkSsQ

通过问答调用产品mcp

我们会发现在如下的问答过程,会根据问题,自动调用mcp服务获得需要的产品信息。

  • “我想了解一下当下的热门产品,帮我获取一下热门产品信息。”
    m7bpbS
  • “我想查询一下关键字:小米SU7 Ultra,了解一下它的价格。”
    4emS9b
  • “请为用户ID为1的用户,推荐商品。”
    jG3pwW

未来验证

模块化产品订单mcp 服务,即可接入大模型,进行问答调用。

相关

结合FastMCP创建自己的MCP服务,实现哔哩视频查询
基于FastMCP 2.0的MCP Server快速搭建指南

背景

  • 行业:生物试剂
  • 手上有自产试剂的所有说明书,大概300多份
  • 不限于说明书的资料

目标

希望微调出一个名字为 dayou 的自产生物试剂行业垂直大语言模型。首要目标是能解答说明书内的相关内容,继而继续增加数据集,完善该 dayou 自训练大模型,或者分领域分别训练 dayou-saledyou-manualdyou-tech大模型。

本次可行性验证,我们从说明书选取如下2个试剂产品

  • IMDM培养基 (6016311 IMDM培养基说明书(中文)–C2–A4.docx)
  • TransFx转染用无血清培养基 (6066411 TransFx转染用无血清培养基说明书–C0.docx)

通过AI对2个产品的docx文件进行制作QA的数据集。

实践

  • 微调模型选择:Qwen2.5-7B-Instruct
  • 微调框架选择:LLaMA-Factory
  • GPU显卡选择: RTX 4090
  • 数据集制作:easy-dataset

算力准备及训练环境准备

本次实验使用AutoDL AI算力云 租借算力,采用GPU卡进行训练,使用Ubuntu 24.04LTS版本
IX3I8x

AutoDL的系统盘和数据盘可以通过source ~/.bashrc 查看

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$ source ~/.bashrc
+-----------------------------------------------AutoDL-----------------------------------------------------+
目录说明:
╔═════════════════╦════════╦════╦══════════════════════════════════════════════════════════════╗
║目录 ║名称 ║速度 ║说明 ║
╠═════════════════╬════════╬════╬══════════════════════════════════════════════════════════════╣
║/ ║系 统 盘 ║一般║实例关机数据不会丢失,可存放代码等。会随保存镜像一起保存。 ║
║/root/autodl-tmp ║数 据 盘 ║ 快 ║实例关机数据不会丢失,可存放读写IO要求高的数据。但不会随保存镜像一起保存 ║
╚═════════════════╩════════╩════╩═══════════════════════════════════════════════════════════════╝
CPU :16 核心
内存:120 GB
GPU :NVIDIA GeForce RTX 4090, 1
存储:
系 统 盘/ :29% 8.6G/30G
数 据 盘/root/autodl-tmp:1% 72M/50G

LLaMA-Factory搭建

1
2
3
4
5
6
7
8
9
10
11
12
13
## 克隆项目
git clone https://github.com/hiyouga/LLaMA-Factory.git
cd LLaMA-Factory
## 创建环境
conda create -n llamafactory python=3.10
## 激活环境
conda activate llamafactory
## 安装依赖
pip install -e ".[torch,metrics]" --no-build-isolation -i https://mirrors.aliyun.com/pypi/simple
## 执行webui
llamafactory-cli webui
## 后台运行
nohup llamafactory-cli webui > webui.log 2>&1 &
  • 下载模型
    a0F1dg
    界面中选择Qwen2.5-7B-Instruct,并加载模型,会自动下载到默认路径: /root/.cache/modelscope/hub/models/Qwen,我们自己手动下载并指定路径。
    1
    2
    3
    4
    5
    6
    7
    8
    pip install modelscope
    modelscope download --model Qwen/Qwen2.5-7B-Instruct --local_dir /root/autodl-tmp/LLaMA-Factory/models/Qwen/Qwen2.5-7B-Instruct
    modelscope download --model Qwen/Qwen2.5-1.5B-Instruct --local_dir /root/autodl-tmp/LLaMA-Factory/models/Qwen/Qwen2.5-1.5B-Instruct

    apt install git-lfs
    git lfs install
    git clone https://www.modelscope.cn/Qwen/Qwen2.5-7B-Instruct.git /root/autodl-tmp/LLaMA-Factory/models/Qwen
    git clone https://www.modelscope.cn/Qwen/wen2.5-1.5B-Instruct.git /root/autodl-tmp/LLaMA-Factory/models/Qwen

数据集准备

我们使用easy-dataset来简化我们的数据集制作流程,通过大模型自动生成QA数据集。

  • 初始化数据库文件。
    1
    2
    3
    4
    git clone https://github.com/ConardLi/easy-dataset.git
    cd easy-dataset
    npm install
    npm run db:push
  • 部署
    docker-compose.yml
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    services:
    easy-dataset:
    image: ghcr.io/conardli/easy-dataset
    container_name: easy-dataset
    ports:
    - '1717:1717'
    volumes:
    - ./local-db:/app/local-db
    - ./prisma:/app/prisma # 如果需要挂载请先手动初始化数据库文件
    restart: unless-stopped
    1
    docker-compose up -d
    就此我们部署好我们的数据集制作工具。
    wBoKqJ

我们来制作2个产品的数据集

  • IMDM培养基
    hvvrd7
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    [
    {
    "instruction": "IMDM与RPMI-1640培养基在酚红含量上有何差异",
    "input": "",
    "output": "IMDM培养基含有酚红,其含量为15 mg/L。而RPMI-1640培养基的酚红含量在文档中未提及,表明该产品标签中未列出酚红作为成分。因此,IMDM与RPMI-1640培养基在酚红含量上的主要差异在于IMDM明确包含酚红,而RPMI-1640未标明含有该成分。",
    "system": "你是一个由“达科为”公司自产的生物试剂产品,品牌名为:“达优”,产品名称是:“IMDM培养基”,有一个规格,货号为:“6016311”"
    },
    {
    "instruction": "IMDM培养基是否含有抗生素?",
    "input": "",
    "output": "IMDM培养基不含抗生素。该培养基是一种改进型的DMEM培养基,特别设计用于红细胞和巨噬细胞前体、T淋巴细胞、B淋巴细胞、骨髓造血细胞和淋巴瘤细胞的培养。在产品参数中明确指出,该培养基不含抗生素成分,需额外添加胎牛血清等培养添加物以满足细胞生长的需求。",
    "system": "你是一个由“达科为”公司自产的生物试剂产品,品牌名为:“达优”,产品名称是:“IMDM培养基”,有一个规格,货号为:“6016311”"
    },
    ...一下省略,共41个问题
    ]
  • TransFx转染用无血清培养基
    cAEnPF
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    [
    {
    "instruction": "分析无血清培养基中不含酚红、HEPES和胰岛素成分对减少转染试剂用量和避免血清干扰的实证数据支持。",
    "input": "",
    "output": "无血清培养基中不含酚红、HEPES和胰岛素的设计可有效减少转染试剂用量并提升转染效率。酚红作为pH指示剂,可能干扰细胞代谢及外源物质摄取;HEPES缓冲系统在某些情况下会与转染试剂发生非特异性结合,降低其活性。胰岛素则可能影响细胞膜通透性,干扰阳离子脂质体或聚合物介导的核酸传递。实验证明,在不含这些成分的TransFx培养基中,转染试剂(如TransIT-X2)与核酸复合物更稳定,细胞摄取效率提高,从而减少试剂用量并避免血清成分的干扰,最终实现更高效的基因转染。",
    "system": "你是一个由“达科为”公司自产的生物试剂产品,品牌名为:“达优”,产品名称是:“TransFx转染用无血清培养基”,有一个规格,货号为:“6066411”"
    },
    {
    "instruction": "比较不同储存条件(如温度2℃~8℃和避光)对TransFx培养基稳定性和转染效果的影响机制。",
    "input": "",
    "output": "TransFx转染用无血清培养基的稳定性与活性受储存条件影响显著。其推荐储存温度为2℃~8℃,该温度范围可维持培养基中植物源重组生长因子(如IGF-1和EGF)、氨基酸(如L-谷氨酰胺)及微量元素的化学稳定性,防止降解或失活。高温可能加速成分氧化或降解,影响其支持转染的能力。同时,避光保存可防止光敏感成分(如酚红替代物及某些维生素或辅因子)发生光化学反应,从而维持培养基的pH稳定性和生物活性。若未避光或温度波动较大,可能降低转染效率,影响核酸-转染试剂复合物的形成与细胞摄取能力,最终削弱基因表达效果。因此,遵循推荐储存条件对于维持TransFx培养基功能至关重要。",
    "system": "你是一个由“达科为”公司自产的生物试剂产品,品牌名为:“达优”,产品名称是:“TransFx转染用无血清培养基”,有一个规格,货号为:“6066411”"
    },
    ...一下省略,共43个问题
    ]

训练

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
llamafactory-cli train \
--stage sft \
--do_train True \
--model_name_or_path /root/autodl-tmp/LLaMA-Factory/models/Qwen/Qwen2.5-3B-Instruct \
--preprocessing_num_workers 16 \
--finetuning_type lora \
--template qwen \
--flash_attn auto \
--dataset_dir data/dayou/ \
--dataset identity,[Easy Dataset] [oLYDc6WUW-2H] ShareGPT,[Easy Dataset] [ag7XS4Wdb3LM] ShareGPT \
--cutoff_len 1024 \
--learning_rate 0.0001 \
--num_train_epochs 20.0 \
--max_samples 100000 \
--per_device_train_batch_size 2 \
--gradient_accumulation_steps 16 \
--lr_scheduler_type cosine \
--max_grad_norm 1.0 \
--logging_steps 5 \
--save_steps 50 \
--warmup_steps 4 \
--packing False \
--enable_thinking True \
--report_to none \
--output_dir saves/Qwen2.5-3B-Instruct/lora/dayou_v6 \
--bf16 True \
--plot_loss True \
--trust_remote_code True \
--ddp_timeout 180000000 \
--include_num_input_tokens_seen True \
--optim adamw_torch \
--adapter_name_or_path saves/Qwen2.5-3B-Instruct/lora/dayou_v6 \
--lora_rank 16 \
--lora_alpha 32 \
--lora_dropout 0 \
--lora_target all

可行性总结与分析

硬件环境

首先按照 nvidia驱动安装 装下驱动

1
2
3
4
nvidia-smi

pip install nvitop
nvitop

TnPQDZ

环境准备

  • 安装依赖
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    ## 克隆项目
    git clone --depth 1 https://github.com/hiyouga/LLaMA-Factory.git
    cd LLaMA-Factory
    ## 创建环境
    conda create -n llamafactory python=3.10
    ## 激活环境
    conda activate llamafactory
    ## 安装依赖
    pip config set global.index-url https://mirrors.aliyun.com/pypi/simple
    pip install -e ".[torch,metrics]" --no-build-isolation -i https://mirrors.aliyun.com/pypi/simple

    如果出现环境冲突,请尝试使用 pip install –no-deps -e . 解决

  • 校验环境
    1
    2
    3
    4
    import torch
    torch.cuda.current_device()
    torch.cuda.get_device_name(0)
    torch.__version__
    1
    2
    3
    4
    5
    6
    7
    >>> import torch
    >>> torch.cuda.current_device()
    0
    >>> torch.cuda.get_device_name(0)
    'NVIDIA GeForce RTX 4090'
    >>> torch.__version__
    '2.8.0+cu128'
    1
    2
    # 对本库的基础安装做一下校验,输入以下命令获取训练相关的参数指导, 否则说明库还没有安装成功
    llamafactory-cli train -h
  • llamafactory-cli常见命令
    动作参数 功能说明
    version 显示版本信息
    train 命令行版本训练
    chat 命令行版本推理聊天
    export 模型合并和导出(如转换为Hugging Face/ONNX格式)
    api 启动API服务器,提供HTTP接口调用
    eval 使用标准数据集(如MMLU)评测模型性能
    webchat 启动纯推理的Web聊天页面(简易前端)
    webui 启动LlamaBoard多功能前端(含训练、预测、聊天、模型合并等可视化子页面)

    另外两个关键参数解释如下,后续的基本所有环节都会继续使用这两个参数

    参数名称 参数说明
    model_name_or_path 参数的名称(huggingface或者modelscope上的标准定义,如 Qwen/Qwen2.5-1.5B-Instruct),或者是本地下载的绝对路径,如/root/autodl-tmp/LLaMA-Factory/models/Qwen/Qwen2.5-1.5B-Instruct
    template 模型问答时所使用的prompt模板,不同模型不同,请参考 LLaMA-Factory Supported Models 获取不同模型的模板定义,否则会回答结果会很奇怪或导致重复生成等现象的出现。chat版本的模型基本都需要指定,比如Qwen/Qwen2.5-1.5B-Instruct的template就是qwen
  • 示例:下面四行命令分别是 启动webui 和对Llama3-8B-Instruct模型进行 LoRA 微调、推理、合并。
    1
    2
    3
    4
    5
    CUDA_VISIBLE_DEVICES=0 USE_MODELSCOPE_HUB=1 llamafactory-cli webui
    CUDA_VISIBLE_DEVICES=0 USE_MODELSCOPE_HUB=1 llamafactory-cli webui > runlog.log &
    llamafactory-cli train examples/train_lora/llama3_lora_sft.yaml
    llamafactory-cli chat examples/inference/llama3_lora_sft.yaml
    llamafactory-cli export examples/merge_lora/llama3_lora_sft.yaml

下载模型

我们自己手动下载并指定路径。

1
2
3
4
5
pip install modelscope
modelscope download --model Qwen/Qwen2.5-1.5B-Instruct --local_dir /root/autodl-tmp/LLaMA-Factory/models/Qwen/Qwen2.5-1.5B-Instruct
modelscope download --model Qwen/Qwen2.5-3B-Instruct --local_dir /root/autodl-tmp/LLaMA-Factory/models/Qwen/Qwen2.5-3B-Instruct
modelscope download --model Qwen/Qwen2.5-7B-Instruct --local_dir /root/autodl-tmp/LLaMA-Factory/models/Qwen/Qwen2.5-7B-Instruct
modelscope download --model Qwen/Qwen3-4B-Instruct-2507 --local_dir /root/autodl-tmp/LLaMA-Factory/models/Qwen/Qwen3-4B-Instruct-2507

原始模型推理

transformers 原始模型直接推理

为qwen创建一个推理测试python脚本

1
2
mkdir demo
touch demo/generated_text.py

python generated_text.py

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
import transformers
import torch

# 模型路径(替换成你的实际路径)
model_id = "/root/autodl-tmp/LLaMA-Factory/models/Qwen/Qwen2.5-1.5B-Instruct"

# 初始化 pipeline
pipeline = transformers.pipeline(
"text-generation",
model=model_id,
model_kwargs={"torch_dtype": torch.bfloat16},
device_map="auto",
)

# 对话模板
messages = [
{"role": "system", "content": "你是一个助手!"},
{"role": "user", "content": "你是谁?"},
]

# 生成 prompt(不要 tokenize,直接返回字符串)
prompt = pipeline.tokenizer.apply_chat_template(
messages,
tokenize=False,
add_generation_prompt=True
)

# 检查 tokenizer 的特殊 token
# print("特殊 Token 映射:", pipeline.tokenizer.special_tokens_map)

# 设置终止符(优先用 <|eot_id|>,如果不存在则用 eos_token_id 或 pad_token_id)
terminators = [
pipeline.tokenizer.convert_tokens_to_ids("<|eot_id|>"), # Qwen 专用结束 token
pipeline.tokenizer.eos_token_id, # 常规结束 token
pipeline.tokenizer.pad_token_id # 备用 token
]
terminators = [tid for tid in terminators if tid is not None] # 过滤掉 None

# 如果 terminators 为空,手动设置一个默认值(比如 2,但需确认你的模型是否适用)
if not terminators:
terminators = [2] # 常见模型的默认 EOS token,可能需要调整

# 生成文本
outputs = pipeline(
prompt,
max_new_tokens=256,
eos_token_id=terminators, # 传入有效的终止符列表
do_sample=True,
temperature=0.6,
top_p=0.9,
)

# 打印生成的回复(去掉 prompt 部分)
print(outputs[0]["generated_text"][len(prompt):])

输出:

1
我是来自阿里云的大规模语言模型,我叫通义千问。

llamafactory-cli 原始模型直接推理

touch examples/inference/qwen2.5.yaml

1
2
3
4
model_name_or_path: /root/autodl-tmp/LLaMA-Factory/models/Qwen/Qwen2.5-1.5B-Instruct
template: qwen
infer_backend: huggingface # choices: [huggingface, vllm, sglang]
trust_remote_code: true

这样就可以通过如下命令启动:

  • 终端推理: llamafactory-cli chat examples/inference/qwen2.5.yaml
    1
    2
    3
    4
    5
    [INFO|2025-08-08 15:48:45] llamafactory.model.loader:143 >> all params: 1,543,714,304
    Welcome to the CLI application, use `clear` to remove the history, use `exit` to exit the application.
    User: 你是谁?
    Assistant: 我是Qwen,由阿里云开发的语言模型。我能够回答问题、创作文字,还能表达观点、撰写代码。如果您有任何问题或需要帮助,请随时告诉我,我会尽力提供支持。
    User:
  • web推理: llamafactory-cli webchat examples/inference/qwen2.5.yaml
    效果如图,可通过 http://localhost:7860/ 进行访问
    XoHIMO
    注意:这里的localhost:7860 指的是程序启动机器自身的7860端口,云上的用户可能无法通过本地的笔记本电脑直接访问,需要找云厂商获取域名和端口号的一些配置关系进行配置
    比如阿里云用户需要做一下如下环境变量的配置才能正常运行gradio,然后再通过阿里云给的域名映射访问
    1
    export GRADIO_ROOT_PATH=/${JUPYTER_NAME}/proxy/7860/

构建自定义数据集

  • 自带的identity.json数据集

    系统自带的identity.json数据集,用于对模型自我介绍,示例:
    data/identity.json

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    [
    {
    "instruction": "你好",
    "input": "",
    "output": "您好,我是 {{name}},一个由 {{author}} 开发的 AI 助手,很高兴认识您。请问我能为您做些什么?"
    },
    {
    "instruction": "你好",
    "input": "",
    "output": "您好,我是 {{name}},一个由 {{author}} 打造的人工智能助手,请问有什么可以帮助您的吗?"
    },
    ]
    1
    2
    3
    4
    cd LLaMA-Factory
    # 其中的NAME 和 AUTHOR ,替换成我们需要的内容
    sed -i 's/{{name}}/达优AI助手/g' data/identity.json
    sed -i 's/{{author}}/达科为/g' data/identity.json
  • 企业自己的数据集
    dayou.json
    1
    2
    3
    4
    5
    6
    7
    8
    [
    {
    "instruction": "低内毒素胰酶消化液的推荐储存条件是什么,这些条件如何确保其稳定性和活性?",
    "input": "",
    "output": "低内毒素胰酶消化液的储存条件对其稳定性和活性至关重要。以下是推荐的储存条件及其如何确保稳定性和活性的详细解释:\n\n## 🧪 推荐储存条件\n\n1. **温度:**\n * **长期储存: -20°C 或更低(如 -80°C)。** 这是最核心的条件。\n * **短期储存(几天内使用): 2-8°C (冰箱冷藏)。** 仅适用于已解冻并计划在极短时间内(通常不超过1周)用完的 aliquot(分装样品)。**不推荐**将未开封的浓缩液长期存放在冷藏温度。\n\n2. **分装:**\n * **强烈建议将大瓶装的胰酶消化液分装成小体积(如 0.5 mL, 1 mL, 5 mL 等)的无菌、低蛋白吸附的离心管或冻存管中。** 分装体积应根据单次实验用量来定,避免反复冻融。\n\n3. **容器:**\n * 使用**无菌、低蛋白吸附、低内毒素**的容器。推荐使用**高质量聚丙烯 (PP)** 材质的离心管或冻存管。避免使用可能吸附蛋白或释放塑化剂(如 DEHP)的聚苯乙烯 (PS) 管或低质量塑料管。玻璃容器也可,但需确保无菌且不易碎。\n\n4. **避光:**\n * 储存于**避光**环境中。虽然胰酶对光不特别敏感,但避光储存可防止任何潜在的光氧化反应,并提供额外的保护。\n\n5. **密封:**\n * 确保容器**密封良好**,防止水分蒸发(导致浓度变化)、空气进入(导致氧化或污染)以及微生物污染。\n\n## 📊 这些条件如何确保稳定性和活性?\n\n1. **低温 (-20°C 或更低):**\n * **抑制酶活性:** 胰蛋白酶等蛋白酶在低温下其催化活性被极大抑制。这**显著减缓了胰酶分子的自水解(自我降解)**。自水解是胰酶失活的主要途径之一,即使在溶液中也会缓慢发生。低温将这一过程降至最低。\n * **减缓化学反应:** 低温降低了溶液中所有化学反应的速率,包括可能导致酶变性的氧化反应或脱酰胺反应等。\n * **维持结构稳定性:** 低温有助于维持胰酶分子的天然三维构象,防止因热运动导致的结构松散和失活。\n * **抑制微生物生长:** 低温(尤其是冷冻)能有效抑制细菌、真菌等微生物的生长繁殖。**这是维持“低内毒素”状态的关键。** 即使初始内毒素很低,如果储存过程中微生物滋生,其死亡裂解后会释放大量内毒素,导致内毒素水平飙升,严重影响细胞实验结果(如激活细胞炎症通路)。低温储存从根本上杜绝了这种污染风险。\n\n2. **分装 (Aliquoting):**\n * **避免反复冻融:** 反复冻融是导致胰酶失活的**最主要杀手**。每次冻融循环都会:\n * 产生冰晶,可能直接剪切酶分子,破坏其结构。\n * 导致溶液局部浓度和pH值的剧烈变化(如冰晶形成时溶质浓缩),加速酶变性。\n * 增加溶液与空气(氧气)的接触机会,促进氧化。\n * 增加污染风险(每次操作都引入污染可能)。\n * **分装确保每次只取出一个 aliquot 使用,用完即弃,避免了剩余消化液经历多次冻融循环**,从而最大程度地保护了酶的活性和溶液的稳定性(包括内毒素水平)。\n\n3. **合适的容器 (无菌、低蛋白吸附、低内毒素):**\n * **防止酶损失:** 低蛋白吸附的容器(如高质量PP管)能最大程度减少胰酶分子在管壁上的吸附,确保溶液中活性酶的浓度保持稳定。\n * **防止污染:** 无菌容器杜绝了初始储存时的微生物污染源。低内毒素容器确保储存过程本身不会引入新的内毒素污染。\n * **防止化学干扰:** 高质量的惰性材料不会释放可能影响酶活性或细胞毒性的化学物质(如塑化剂)。\n\n4. **避光:**\n * 虽然不是主要因素,但避光储存提供了额外的保护层,防止任何潜在的光敏性成分(可能存在痕量杂质)发生光化学反应,避免产生可能影响酶活性或细胞反应的副产物。\n\n5. **密封:**\n * **防止浓缩/稀释:** 密封防止水分蒸发,避免溶液浓度升高(导致消化过强)或吸潮导致浓度降低(导致消化不足)。\n * **防止氧化:** 减少溶液与空气(氧气)的接触,降低氧化导致酶失活的风险。\n * **防止污染:** 密封是防止储存过程中微生物(细菌、霉菌)进入的关键物理屏障,**直接保障了低内毒素状态的维持**。\n\n## 📌 总结与关键点\n\n* **核心是低温冷冻 + 分装:** -20°C 或更低温度储存是抑制酶自降解和微生物生长的基础。分装成小 aliquot 是避免反复冻融失活的**绝对必要措施**。\n* **低内毒素依赖于无菌和防污染:** 低温储存抑制微生物生长,无菌容器和密封操作防止初始和储存过程中的污染,共同确保内毒素水平在有效期内维持在极低状态。\n* **容器选择不容忽视:** 低蛋白吸附和低内毒素的容器材质对维持酶浓度和溶液纯净度至关重要。\n* **遵循说明书:** **最重要的一点是:务必遵循您所使用的具体品牌和批次胰酶消化液产品说明书上提供的储存条件和有效期。** 不同厂家、不同配方(如是否含 EDTA、酚红等)的胰酶消化液,其最佳储存条件和稳定期限可能略有差异。说明书是最权威的指导。\n* **解冻与使用:** 使用时,将所需 aliquot 从冰箱取出,**在冰上或 2-8°C 冰箱中缓慢解冻**。避免室温解冻或水浴加速解冻(温度骤变易失活)。解冻后应立即使用,**切勿再次冷冻**已解冻的 aliquot。使用前可短暂涡旋混匀,但避免剧烈振荡产生气泡(可能导致蛋白变性)。\n\n通过严格遵守这些储存条件,可以最大限度地保证低内毒素胰酶消化液的蛋白酶活性、消化效率以及内毒素水平在有效期内保持稳定,从而为细胞培养实验提供可靠、一致且无干扰的消化效果。💪🏻",
    "system": ""
    }
    ]
    需要将该数据集注册到 dataset_info.json
    1
    2
    3
    4
    5
    6
    7
    8
    {
    "identity": {
    "file_name": "identity.json"
    },
    "dayou": {
    "file_name": "dayou.json"
    }
    }

基于LoRA的sft指令微调

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
CUDA_VISIBLE_DEVICES=0 llamafactory-cli train \
--stage sft \
--do_train \
--model_name_or_path /root/autodl-tmp/LLaMA-Factory/models/Qwen/Qwen2.5-1.5B-Instruct \
--dataset identity,dayou \
--dataset_dir ./data \
--template qwen \
--finetuning_type lora \
--output_dir ./saves/Qwen2.5-1.5B-dayou/lora/sft \
--overwrite_cache \
--overwrite_output_dir \
--cutoff_len 1024 \
--preprocessing_num_workers 16 \
--per_device_train_batch_size 2 \
--per_device_eval_batch_size 1 \
--gradient_accumulation_steps 8 \
--lr_scheduler_type cosine \
--logging_steps 50 \
--warmup_steps 20 \
--save_steps 100 \
--eval_steps 50 \
--evaluation_strategy steps \
--load_best_model_at_end \
--learning_rate 5e-5 \
--num_train_epochs 5.0 \
--max_samples 1000 \
--val_size 0.1 \
--plot_loss \
--fp16

动态合并LoRA的推理

当基于LoRA的训练进程结束后,我们如果想做一下动态验证,在网页端里与新模型对话,与步骤 原始模型直接推理 相比,唯一的区别是需要通过adapter_name_or_path参数告诉LoRA的模型位置。
touch examples/inference/qwen2.5_sft.yaml

1
2
3
4
5
model_name_or_path: /root/autodl-tmp/LLaMA-Factory/models/Qwen/Qwen2.5-1.5B-Instruct
adapter_name_or_path: saves/Qwen2.5-1.5B-dayou/lora/sft
template: qwen
infer_backend: huggingface # choices: [huggingface, vllm, sglang]
trust_remote_code: true
  • 终端推理: llamafactory-cli chat examples/inference/qwen2.5_sft.yaml
  • web推理: llamafactory-cli webchat examples/inference/qwen2.5_sft.yaml

相关链接

背景

大模型领域日新月异,模型微调早已无代码化,我认为大模型训练和微调的关键步骤仅剩:高质量的数据集准备
之前微调过一次甄嬛 Mac M2之LLaMA3-8B微调(llama3-fine-tuning), 这次我想用 llama-factory + Qwen2.5-1.5B-Instruct完全无代码微调一次。

LLaMA-Factory

1
2
3
4
5
6
7
8
9
## 克隆项目
git clone https://github.com/hiyouga/LLaMA-Factory.git
cd LLaMA-Factory
## 创建环境
conda create -n llamafactory python=3.10
## 激活环境
conda activate llamafactory
## 安装依赖
pip install -e ".[torch,metrics]" --no-build-isolation -i https://mirrors.aliyun.com/pypi/simple

校验环境

1
2
3
4
import torch
torch.cuda.current_device()
torch.cuda.get_device_name(0)
torch.__version__

执行webui

1
llamafactory-cli webui

执行完毕后,会自动打开webui

数据集

本次我们依然使用该数据集:Chat-嬛嬛数据集
llama-factory 目前只支持AlpacaSharegpt两种格式的数据集。

  • Alpaca 格式
    适用于单轮任务,如问答、文本生成、摘要、翻译等。结构简洁,任务导向清晰,适合低成本的指令微调。
    1
    2
    3
    4
    5
    {  
    "instruction":"计算这些物品的总费用。",
    "input":"输入:汽车 - $3000,衣服 - $100,书 - $20。",
    "output":"汽车、衣服和书的总费用为 $3000 + $100 + $20 = $3120。"
    }
  • ShareGPT 格式
    适用于多轮对话、聊天机器人等任务。结构复杂,包含多轮对话上下文,适合高质量的对话生成和人机交互任务。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    [{
    "instruction": "今天的天气怎么样?",
    "input": "",
    "output": "今天的天气不错,是晴天。",
    "history": [
    ["今天会下雨吗?", "今天不会下雨,是个好天气。"],
    ["今天适合出去玩吗?", "非常适合,空气质量很好。"]
    ]
    }]

打开 huanhuan.json 文件,可以看到它其实就是 Alpaca 格式的数据集,仅下载这一个文件即可。
w0tYNQ
我们在 llama-factory 项目内的的data目录放置 huanhuan.json 文件,并且在 dataset_info.json 的配置文件添加一条 huanhuan.json 的json配置,这样,我们新添加的数据集才能被llama-factory注册识别到。
KfyAQY

微调

首先是模型,我们选择此次需要微调的Qwen2.5-1.5B-Instruct。

  • Instruct 版本(如 Qwen2.5-1.5B-Instruct) ✅
    • 经过指令微调的模型
    • 更适合直接对话和指令遵循
    • 已经具备基本的对话能力
    • 更适合用来进一步微调

微调方式使用默认的lora即可。

  • 训练轮数可以选择1轮,会快一些(如果后面发现效果不理想,可以多训练几轮),我这里最终选择了3轮,因为我发现仅1轮效果不佳。
  • 计算类型 默认
  • 截断长度设置小一点,为1024(默认是2048)。
  • 梯度累计设置为4。
  • 其他参数设置-预热步数是学习率预热采用的步数,通常设置范围在2-8之间,我们这里配置4。
    grGcU2
  • LoRA参数设置-lora秩越大(可以看作学习的广度),学习的东西越多,微调之后的效果可能会越好,但是也不是越大越好。太大的话容易造成过拟合(书呆子,照本宣科,不知变通),这里设置为8。
  • LoRA参数设置-lora缩放系数(可以看作学习强度),越大效果可能会越好,对于一些用于复杂场景的数据集可以设置更大一些,简单场景的数据集可以稍微小一点。我这里设置256。
    pJJRLv
    模型训练结束后,会显示:训练完毕。
    wFc3ho
    如果想重新微调,记得改一下下面红框中的两个值。
    7Yswha
    微调成功后,在检查点路径这里,下拉可以选择我们刚刚微调好的模型。把窗口切换到chat,点击加载模型。
    8GsA0p
    加载好之后就可以在输入框发送问题,测试微调模型的回复效果了。如果想切换回微调之前的模型,只需要把检查点路径置空。然后在chat这里卸载模型,再加载模型即可。
    SngtWk

导出模型与使用

切换到export,填写导出目录models/huanhuan

大语言模型的参数通常以高精度浮点数(如32位浮点数,FP32)存储,这导致模型推理需要大量计算资源。量化技术通过将高精度数据类型存储的参数转换为低精度数据类型(如8位整数,INT8)存储,可以在不改变模型参数量和架构的前提下加速推理过程。这种方法使得模型的部署更加经济高效,也更具可行性。

量化前需要先将模型导出后再量化。修改模型路径为导出后的模型路径,导出量化等级一般选择 8 或 4,太低模型会答非所问。

wOiMlb

  • 导入ollama

    出现ollama和在llama-factory的chat回答效果不一致,请查看底部 相关链接

    1
    2
    3
    ollama create Qwen2.5-1.5B-huanhuan -f Modefile
    ollama list
    ollama run Qwen2.5-1.5B-huanhuan:latest
    UhlbHS
  • vllm部署使用

    出现vllm和在llama-factory的chat回答效果不一致,请查看底部 相关链接

    • 启动
      1
      2
      3
      4
      5
      vllm serve /root/autodl-tmp/LLaMA-Factory/models/huanhuan/Qwen2.5-1.5B-huanhuan \
      --port 8000 \
      --host 0.0.0.0 \
      --gpu-memory-utilization 0.8 \
      --served-model-name huanhuan
    • 发送请求
      1
      2
      3
      4
      5
      6
      7
      8
      curl --location 'http://192.168.103.43:8000/v1/completions' \
      --header 'Content-Type: application/json' \
      --data '{
      "model": "huanhuan",
      "prompt": "你是谁",
      "max_tokens": 50,
      "temperature": 0.7
      }'
    • 效果
      oKPXPo

相关链接

背景

物理机器有显卡L20 (4 * 48G),安装vmware esxi系统,希望虚拟机ubuntu22.04 直通物理显卡。

  • ESXi-8.0U3e-24677879-standard
  • ubuntu22.04

直通模式配置

虚拟机配置

  • 创建虚拟机及配置参数
    • 预留全部内存
      wUml1N
    • 在“虚拟机设置”中,点击“添加其他设备” > “PCI设备”,在列表中找到并勾选NVIDIA显卡(例如,0000:c1:00.0)。
      PZmAZx
    • 取消UEFI安全启动
      jQILo6

为了优化GPU直通的性能和兼容性,需要在虚拟机的高级配置中添加以下参数:

1
2
3
4
5
6
# 该参数用于隐藏虚拟化环境,使得虚拟机能够更好地识别并利用NVIDIA显卡。
hypervisor.cpuid.v0 = FALSE
# 启用64位内存映射输入/输出(MMIO),提高显卡的内存访问效率。
pciPassthru.use64bitMMIO = TRUE
# 设置64位MMIO的大小,确保显卡有足够的内存资源进行高性能计算和渲染任务。
pciPassthru.64bitMMIOSizeGB = 256 (2张48G显卡,具体计算看下面)

pciPassthru.64bitMMIOSizeGB计算方式 https://earlruby.org/tag/use64bitmmio/
64bitMMIOSizeGB值的计算方法是将连接到VM的所有GPU上的显存总量(GB)相加。如果总显存为2的幂次方,则将pciPassthru.64bitMMIOSizeGB设置为下一个2的幂次方即可。
如果总显存介于2的2次方之间,则向上舍入到下一个2的幂次方,然后再次向上舍入。
2的幂数是2、4、8、16、32、64、128、256、512、1024…
例如虚拟机直通两张24G显存的显卡,则64bitMMIOSizeGB应设置为128。计算方式为242=48,在32和64之间,先舍入到64,再次舍入到128
例如虚拟机直通两张48G显存的显卡,则64bitMMIOSizeGB应设置为256。计算方式为48
2=96,在64和128之间,先舍入到128,再次舍入到256

BCylVm

linux 驱动安装

  • 更新系统
    1
    sudo apt update && sudo apt upgrade -y
  • 禁用开源驱动 Nouveau
    1
    2
    3
    4
    sudo nano /etc/modprobe.d/blacklist.conf
    # 在文件末尾添加以下内容:
    blacklist nouveau
    options nouveau modeset=0
    保存后执行:
    1
    2
    sudo update-initramfs -u
    sudo reboot
    重启后验证是否禁用成功(无输出即成功):
    1
    lsmod | grep nouveau
  • 安装驱动
    • 安装显卡驱动工具
      1
      sudo apt-get install nvidia-cuda-toolkit
    • 查看系统推荐显卡驱动

      这里要看好哪个是系统推荐的驱动(recommend),并且要记下来

      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
      sudo ubuntu-drivers devices

      (base) root@ai-03-deploy:~# sudo ubuntu-drivers devices
      == /sys/devices/pci0000:00/0000:00:0f.0 ==
      modalias : pci:v000015ADd00000405sv000015ADsd00000405bc03sc00i00
      vendor : VMware
      model : SVGA II Adapter
      manual_install: True
      driver : open-vm-tools-desktop - distro free

      == /sys/devices/pci0000:03/0000:03:00.0 ==
      modalias : pci:v000010DEd000026BAsv000010DEsd00001957bc03sc02i00
      vendor : NVIDIA Corporation
      driver : nvidia-driver-535 - distro non-free
      driver : nvidia-driver-575-server-open - distro non-free
      driver : nvidia-driver-550-open - distro non-free
      driver : nvidia-driver-575-open - distro non-free
      driver : nvidia-driver-570 - distro non-free
      driver : nvidia-driver-550 - distro non-free
      driver : nvidia-driver-570-server-open - distro non-free
      driver : nvidia-driver-570-open - distro non-free
      driver : nvidia-driver-575 - distro non-free recommended
      driver : nvidia-driver-575-server - distro non-free
      driver : nvidia-driver-535-open - distro non-free
      driver : nvidia-driver-535-server-open - distro non-free
      driver : nvidia-driver-570-server - distro non-free
      driver : nvidia-driver-535-server - distro non-free
      driver : xserver-xorg-video-nouveau - distro free builtin
    • 添加驱动源
      1
      2
      sudo add-apt-repository ppa:graphics-drivers/ppa
      sudo apt-get update
    • 选择版本安装
      1
      sudo apt install nvidia-driver-575
      1
      sudo reboot
  • 验证安装
    1
    2
    nvidia-smi
    nvitop

参考链接

从坑中爬起:ESXi 8.0直通NVIDIA显卡的血泪经验
How To Install Nvidia Drivers on Rocky Linux 10
vmware虚拟机玩GPU显卡直通

Qwen3概述

  • 多种思考模式

    可用户提示或系统消息中添加 /think 和 /no_think 来逐轮切换模型的思考模式

    • 思考模式:在这种模式下,模型会逐步推理,经过深思熟虑后给出最终答案。这种方法非常适合需要深入思考的复杂问题。
    • 非思考模式:在此模式中,模型提供快速、近乎即时的响应,适用于那些对速度要求高于深度的简单问题。
  • 多语言
    119 种语言和方言

  • MCP 支持

Qwen3-30B-A3B

  • 一个拥有约 300 亿总参数和 30 亿激活参数的小型 MoE 模型
  • 需24GB+显存

Qwen3-Embedding & Qwen3-Reranker

Model Type Models Size Layers Sequence Length Embedding Dimension MRL Support Instruction Aware
Text Embedding Qwen3-Embedding-0.6B 0.6B 28 32K 1024 Yes Yes
Text Embedding Qwen3-Embedding-4B 4B 36 32K 2560 Yes Yes
Text Embedding Qwen3-Embedding-8B 8B 36 32K 4096 Yes Yes
Text Reranking Qwen3-Reranker-0.6B 0.6B 28 32K - - Yes
Text Reranking Qwen3-Reranker-4B 4B 36 32K - - Yes
Text Reranking Qwen3-Reranker-8B 8B 36 32K - - Yes
  • 经济型:Embedding-4B + Reranker-4B(显存总需求<30GB)
  • 高性能型:Embedding-8B + Reranker-8B(需多GPU,吞吐量提升40%+)

对比BGE-M3:全方位代差优势

指标 Qwen3-8B BGE-M3 优势幅度
综合得分 70.58 59.56 ↑11.02
上下文长度 32K 8K ↑ 4倍
检索任务(MSMARCO) 57.65 40.88 ↑41%
开放问答(NQ) 10.06 -3.11 实现负分逆转
多语言理解 28.66 20.10 ↑42%

vllm 安装

  • uv

    1
    2
    3
    uv venv vllm --python 3.12 --seed
    source vllm/bin/activate
    uv pip install vllm
  • conda

    1
    2
    3
    4
    5
    conda env list ## 查看conda创建的所以虚拟环境
    conda create -n vllm python=3.12 ## 创建特定版本python
    conda activate vllm ## 进入某个虚拟环境
    conda env remove -n vllm ## 删除某个虚拟环境
    pip install vllm

模型下载

1
2
3
4
5
6
7
8
9
10
11
12
## 安装下载环境
pip install modelscope
## 下载模型
modelscope download --model Qwen/Qwen3-30B-A3B
## 下载指定目录下
modelscope download --model Qwen/Qwen3-30B-A3B-FP8 --local_dir /home/models/Qwen3-30B-A3B-FP8
modelscope download --model Qwen/Qwen3-30B-A3B-Instruct-2507-FP8 --local_dir /home/models/Qwen3-30B-A3B-Instruct-2507-FP8
modelscope download --model Qwen/Qwen3-30B-A3B-Thinking-2507-FP8 --local_dir /home/models/Qwen3-30B-A3B-Thinking-2507-FP8

modelscope download --model Qwen/Qwen3-Embedding-8B --local_dir /home/models/Qwen3-Embedding-8B
modelscope download --model Qwen/Qwen3-Reranker-8B --local_dir /home/models/Qwen3-Reranker-8B
modelscope download --model Qwen/Qwen2.5-VL-7B-Instruct --local_dir /home/models/Qwen2.5-VL-7B-Instruct

vllm 服务启动

vllm serve <model_path>

1
2
3
4
5
6
7
8
9
10
vllm serve /home/models/Qwen3-30B-A3B-Thinking-2507-FP8 \
--port 8003 \
--host 0.0.0.0 \
--gpu-memory-utilization 0.85 \
--max-model-len 12288 \
--max-num-seqs 256 \
--max-num-batched-tokens 4096 \
--tensor-parallel-size 1 \
--reasoning-parser deepseek_r1 \
--served-model-name Qwen3-30B-A3B-Thinking-2507-FP8
  • --tensor-parallel-size: 将您的模型分布到主机 GPU 中,GPU数量。
  • --GPU-memory-utilization:调整模型权重、激活和 KV 缓存的加速器内存使用率。作为 0.0 到 1.0 的比例测量,默认为 0.9.例如,您可以将此值设置为 0.8,将 AI Inference Server 的 GPU 内存消耗限制为 80%。使用部署稳定的最大值来最大化吞吐量。
  • --max-model-len: 限制模型的最大上下文长度,以令牌表示。如果模型的默认上下文长度太长,则将其设置为防止内存出现问题。
  • --max-num-batched-tokens: 每迭代的最大批处理令牌数量,将令牌的最大批处理大小限制为每个步骤处理(以令牌表示)。增加这可以提高吞吐量,但可能会影响输出令牌延迟。
  • --max-num-seqs: # 每迭代的最大序列数量,吞吐量关键!

参数相关

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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
usage: vllm serve [-h] [--model MODEL]
[--task {auto,generate,embedding,embed,classify,score,reward,transcription}]
[--tokenizer TOKENIZER] [--hf-config-path HF_CONFIG_PATH]
[--skip-tokenizer-init] [--revision REVISION]
[--code-revision CODE_REVISION]
[--tokenizer-revision TOKENIZER_REVISION]
[--tokenizer-mode {auto,slow,mistral,custom}]
[--trust-remote-code]
[--allowed-local-media-path ALLOWED_LOCAL_MEDIA_PATH]
[--download-dir DOWNLOAD_DIR]
[--load-format {auto,pt,safetensors,npcache,dummy,tensorizer,sharded_state,gguf,bitsandbytes,mistral,runai_streamer}]
[--config-format {auto,hf,mistral}]
[--dtype {auto,half,float16,bfloat16,float,float32}]
[--kv-cache-dtype {auto,fp8,fp8_e5m2,fp8_e4m3}]
[--max-model-len MAX_MODEL_LEN]
[--guided-decoding-backend GUIDED_DECODING_BACKEND]
[--logits-processor-pattern LOGITS_PROCESSOR_PATTERN]
[--model-impl {auto,vllm,transformers}]
[--distributed-executor-backend {ray,mp,uni,external_launcher}]
[--pipeline-parallel-size PIPELINE_PARALLEL_SIZE]
[--tensor-parallel-size TENSOR_PARALLEL_SIZE]
[--enable-expert-parallel]
[--max-parallel-loading-workers MAX_PARALLEL_LOADING_WORKERS]
[--ray-workers-use-nsight] [--block-size {8,16,32,64,128}]
[--enable-prefix-caching | --no-enable-prefix-caching]
[--disable-sliding-window] [--use-v2-block-manager]
[--num-lookahead-slots NUM_LOOKAHEAD_SLOTS] [--seed SEED]
[--swap-space SWAP_SPACE] [--cpu-offload-gb CPU_OFFLOAD_GB]
[--gpu-memory-utilization GPU_MEMORY_UTILIZATION]
[--num-gpu-blocks-override NUM_GPU_BLOCKS_OVERRIDE]
[--max-num-batched-tokens MAX_NUM_BATCHED_TOKENS]
[--max-num-partial-prefills MAX_NUM_PARTIAL_PREFILLS]
[--max-long-partial-prefills MAX_LONG_PARTIAL_PREFILLS]
[--long-prefill-token-threshold LONG_PREFILL_TOKEN_THRESHOLD]
[--max-num-seqs MAX_NUM_SEQS] [--max-logprobs MAX_LOGPROBS]
[--disable-log-stats]
[--quantization {aqlm,awq,deepspeedfp,tpu_int8,fp8,ptpc_fp8,fbgemm_fp8,modelopt,nvfp4,marlin,gguf,gptq_marlin_24,gptq_marlin,awq_marlin,gptq,compressed-tensors,bitsandbytes,qqq,hqq,experts_int8,neuron_quant,ipex,quark,moe_wna16,None}]
[--rope-scaling ROPE_SCALING] [--rope-theta ROPE_THETA]
[--hf-overrides HF_OVERRIDES] [--enforce-eager]
[--max-seq-len-to-capture MAX_SEQ_LEN_TO_CAPTURE]
[--disable-custom-all-reduce]
[--tokenizer-pool-size TOKENIZER_POOL_SIZE]
[--tokenizer-pool-type TOKENIZER_POOL_TYPE]
[--tokenizer-pool-extra-config TOKENIZER_POOL_EXTRA_CONFIG]
[--limit-mm-per-prompt LIMIT_MM_PER_PROMPT]
[--mm-processor-kwargs MM_PROCESSOR_KWARGS]
[--disable-mm-preprocessor-cache] [--enable-lora]
[--enable-lora-bias] [--max-loras MAX_LORAS]
[--max-lora-rank MAX_LORA_RANK]
[--lora-extra-vocab-size LORA_EXTRA_VOCAB_SIZE]
[--lora-dtype {auto,float16,bfloat16}]
[--long-lora-scaling-factors LONG_LORA_SCALING_FACTORS]
[--max-cpu-loras MAX_CPU_LORAS] [--fully-sharded-loras]
[--enable-prompt-adapter]
[--max-prompt-adapters MAX_PROMPT_ADAPTERS]
[--max-prompt-adapter-token MAX_PROMPT_ADAPTER_TOKEN]
[--device {auto,cuda,neuron,cpu,openvino,tpu,xpu,hpu}]
[--num-scheduler-steps NUM_SCHEDULER_STEPS]
[--use-tqdm-on-load | --no-use-tqdm-on-load]
[--multi-step-stream-outputs [MULTI_STEP_STREAM_OUTPUTS]]
[--scheduler-delay-factor SCHEDULER_DELAY_FACTOR]
[--enable-chunked-prefill [ENABLE_CHUNKED_PREFILL]]
[--speculative-model SPECULATIVE_MODEL]
[--speculative-model-quantization {aqlm,awq,deepspeedfp,tpu_int8,fp8,ptpc_fp8,fbgemm_fp8,modelopt,nvfp4,marlin,gguf,gptq_marlin_24,gptq_marlin,awq_marlin,gptq,compressed-tensors,bitsandbytes,qqq,hqq,experts_int8,neuron_quant,ipex,quark,moe_wna16,None}]
[--num-speculative-tokens NUM_SPECULATIVE_TOKENS]
[--speculative-disable-mqa-scorer]
[--speculative-draft-tensor-parallel-size SPECULATIVE_DRAFT_TENSOR_PARALLEL_SIZE]
[--speculative-max-model-len SPECULATIVE_MAX_MODEL_LEN]
[--speculative-disable-by-batch-size SPECULATIVE_DISABLE_BY_BATCH_SIZE]
[--ngram-prompt-lookup-max NGRAM_PROMPT_LOOKUP_MAX]
[--ngram-prompt-lookup-min NGRAM_PROMPT_LOOKUP_MIN]
[--spec-decoding-acceptance-method {rejection_sampler,typical_acceptance_sampler}]
[--typical-acceptance-sampler-posterior-threshold TYPICAL_ACCEPTANCE_SAMPLER_POSTERIOR_THRESHOLD]
[--typical-acceptance-sampler-posterior-alpha TYPICAL_ACCEPTANCE_SAMPLER_POSTERIOR_ALPHA]
[--disable-logprobs-during-spec-decoding [DISABLE_LOGPROBS_DURING_SPEC_DECODING]]
[--model-loader-extra-config MODEL_LOADER_EXTRA_CONFIG]
[--ignore-patterns IGNORE_PATTERNS]
[--preemption-mode PREEMPTION_MODE]
[--served-model-name SERVED_MODEL_NAME [SERVED_MODEL_NAME ...]]
[--qlora-adapter-name-or-path QLORA_ADAPTER_NAME_OR_PATH]
[--show-hidden-metrics-for-version SHOW_HIDDEN_METRICS_FOR_VERSION]
[--otlp-traces-endpoint OTLP_TRACES_ENDPOINT]
[--collect-detailed-traces COLLECT_DETAILED_TRACES]
[--disable-async-output-proc]
[--scheduling-policy {fcfs,priority}]
[--scheduler-cls SCHEDULER_CLS]
[--override-neuron-config OVERRIDE_NEURON_CONFIG]
[--override-pooler-config OVERRIDE_POOLER_CONFIG]
[--compilation-config COMPILATION_CONFIG]
[--kv-transfer-config KV_TRANSFER_CONFIG]
[--worker-cls WORKER_CLS]
[--worker-extension-cls WORKER_EXTENSION_CLS]
[--generation-config GENERATION_CONFIG]
[--override-generation-config OVERRIDE_GENERATION_CONFIG]
[--enable-sleep-mode] [--calculate-kv-scales]
[--additional-config ADDITIONAL_CONFIG] [--enable-reasoning]
[--reasoning-parser {deepseek_r1}]

Qwen3 底座模型部署 部署

  • docker-compose.yaml

    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
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    services:
    Qwen3-30B-A3B-Instruct-2507-FP8:
    image: vllm/vllm-openai:v0.10.1.1
    container_name: Qwen3-30B-A3B-Instruct-2507-FP8
    restart: unless-stopped
    profiles: ["Instruct"]
    volumes:
    - /home/models/Qwen3-30B-A3B-Instruct-2507-FP8:/models/Qwen3-30B-A3B-Instruct-2507-FP8
    command: ["--model", "/models/Qwen3-30B-A3B-Instruct-2507-FP8","--served-model-name", "Qwen3-30B-A3B-Instruct-2507-FP8","--gpu-memory-utilization", "0.80","--max-model-len", "32768","--tensor-parallel-size", "1"]
    ports:
    - 8003:8000
    deploy:
    resources:
    reservations:
    devices:
    - driver: nvidia
    device_ids: ["0"]
    capabilities: [gpu]

    Qwen3-30B-A3B-Thinking-2507-FP8:
    image: vllm/vllm-openai:v0.10.1.1
    container_name: Qwen3-30B-A3B-Thinking-2507-FP8
    restart: unless-stopped
    profiles: ["Thinking"]
    volumes:
    - /home/models/Qwen3-30B-A3B-Thinking-2507-FP8:/models/Qwen3-30B-A3B-Thinking-2507-FP8
    command: ["--model", "/models/Qwen3-30B-A3B-Thinking-2507-FP8","--served-model-name", "Qwen3-30B-A3B-Thinking-2507-FP8","--gpu-memory-utilization", "0.80","--max-model-len", "32768","--tensor-parallel-size", "1","--reasoning-parser", "deepseek_r1"]
    ports:
    - 8003:8000
    deploy:
    resources:
    reservations:
    devices:
    - driver: nvidia
    device_ids: ["0"]
    capabilities: [gpu]

    Qwen3-30B-A3B-FP8:
    image: vllm/vllm-openai:v0.10.1.1
    container_name: Qwen3-30B-A3B-FP8
    restart: unless-stopped
    profiles: ["Instruct&Thinking"]
    volumes:
    - /home/models/Qwen3-30B-A3B-FP8:/models/Qwen3-30B-A3B-FP8
    command: ["--model", "/models/Qwen3-30B-A3B-FP8","--served-model-name", "Qwen3-30B-A3B-FP8","--gpu-memory-utilization", "0.40","--max-model-len", "32768","--tensor-parallel-size", "1","--reasoning-parser", "deepseek_r1"]
    ports:
    - 8003:8000
    deploy:
    resources:
    reservations:
    devices:
    - driver: nvidia
    device_ids: ["0"]
    capabilities: [gpu]

    Qwen3-Embedding-8B:
    container_name: Qwen3-Embedding-8B
    restart: no
    image: vllm/vllm-openai:v0.10.1.1
    profiles: ["Embedding"]
    volumes:
    - /home/models/Qwen3-Embedding-8B:/models/Qwen3-Embedding-8B
    command: ["--model", "/models/Qwen3-Embedding-8B", "--served-model-name", "Qwen3-Embedding-8B", "--gpu-memory-utilization", "0.85"]
    ports:
    - 8001:8000
    deploy:
    resources:
    reservations:
    devices:
    - driver: nvidia
    device_ids: ["1"]
    capabilities: [gpu]

    Qwen3-Reranker-8B:
    container_name: Qwen3-Reranker-8B
    restart: no
    image: vllm/vllm-openai:v0.10.1.1
    profiles: ["Reranker"]
    volumes:
    - /home/models/Qwen3-Reranker-8B:/models/Qwen3-Reranker-8B
    command: ['--model', '/models/Qwen3-Reranker-8B', '--served-model-name', 'Qwen3-Reranker-8B', '--gpu-memory-utilization', '0.45', '--hf_overrides','{"architectures": ["Qwen3ForSequenceClassification"],"classifier_from_token": ["no", "yes"],"is_original_qwen3_reranker": true}']
    ports:
    - 8002:8000
    deploy:
    resources:
    reservations:
    devices:
    - driver: nvidia
    device_ids: ["1"]
    capabilities: [gpu]


  • 启动

    1
    2
    3
    4
    5
    docker compose --profile Instruct&Thinking up -d
    docker compose --profile Instruct up -d
    docker compose --profile Thinking up -d
    docker compose --profile Embedding up -d
    docker compose --profile Reranker up -d

    curl验证一下

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    {
    "model": "Qwen3-30B-A3B-Instruct-2507-FP8",
    "messages": [
    {
    "role": "system",
    "content": "你是一名旅游顾问,我计划在2024年夏季进行一次为期10天的欧洲之旅,主要目的地包括巴黎、米兰和马德里。预算为每人10000元人民币,希望体验当地的文化和美食,同时偏好舒适的住宿条件。用户特别强调需要包含到访每个城市的必游景点,并希望有自由活动的时间。"
    },
    {
    "role": "user",
    "content": "我计划7月中旬出发,请给我一份旅游计划"
    }
    ],
    "temperature": 0.3,
    "stream": true
    }

new api统一网关管理大模型

使用 FastAPI 集成 Qwen 大模型服务

  • 依赖文件(requirements.txt):
    1
    2
    3
    4
    5
    fastapi==0.116.1
    uvicorn==0.35.0
    openai==1.100.1
    dashscope==1.24.1
    python-dotenv==1.1.1
    安装依赖的 Python 库:
    1
    pip install -r requirements.txt
    将 DeepSeek 和 Qwen 的相关信息配置到系统环境变量中。
    1
    2
    3
    4
    5
    6
    7
    # DeepSeek 配置
    DEEPSEEK_API_KEY = "sk-your-deepseek-key"
    DEEPSEEK_BASE_URL = "https://api.deepseek.com"

    # Qwen3 配置(对接底座大模型)
    QWEN3_API_KEY = "sk-your-qwen-key"
    QWEN3_API_BASE_URL = "http://192.168.103.224:8003/v1"
    接口代码
    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
    62
    63
    64
    65
    66
    67
    68
    69
    70
    import os
    import uvicorn
    from fastapi import FastAPI, HTTPException
    from pydantic import BaseModel
    from dotenv import load_dotenv
    from openai import OpenAI as DeepSeekClient
    from openai import OpenAI as Qwen3Client

    # 配置模型参数
    MODEL_CONFIG = {
        "deepseek": {
            "client": DeepSeekClient(
                api_key=os.getenv("DEEPSEEK_API_KEY"),
                base_url=os.getenv("DEEPSEEK_BASE_URL")
            ),
            "model_name""deepseek-chat"
        },
        "qwen3": {
            "client": Qwen3Client(
                api_key=os.getenv("QWEN3_API_KEY"),
                base_url=os.getenv("QWEN3_API_BASE_URL")
            ),
            "model_name""Qwen3-30B-A3B-Instruct-2507-FP8"
        }
    }


    # 统一请求格式(兼容OpenAI)
    class ChatRequest(BaseModel):
        model: str  # deepseek 或 qwen
        messages: list
        temperature: float0.7
        max_tokens: int1024


    # 统一响应格式
    class ChatResponse(BaseModel):
        model: str
        content: str


    @app.post("/v1/chat")
    asyncdef chat_completion(request: ChatRequest):
        model_type = request.model.lower()
        if model_type notin MODEL_CONFIG:
            raise HTTPException(400f"Unsupported model: {model_type}")

        try:
            if model_type == "deepseek":
                response = MODEL_CONFIG["deepseek"]["client"].chat.completions.create(
                    model=MODEL_CONFIG["deepseek"]["model_name"],
                    messages=request.messages,
                    temperature=request.temperature,
                    max_tokens=request.max_tokens
                )
                content = response.choices[0].message.content

            elif model_type == "qwen3":
                response = MODEL_CONFIG["deepseek"]["client"].chat.completions.create(
                    model=MODEL_CONFIG["deepseek"]["model_name"],
                    messages=request.messages,
                    temperature=request.temperature,
                    max_tokens=request.max_tokens
                )
                content = response.choices[0].message.content

            return ChatResponse(model=model_type, content=content)

        except Exception as e:
            raise HTTPException(500f"API Error: {str(e)}")

背景

我们在过往尝试过使用paimon进行分层 Flink & Paimon & StarRocks & Dinky 流式湖仓分层实践验证,一共制作了如下4张表,其中流任务的merge-engine分别为:

  • order_dw.dwd_orders (partial-update)
  • order_dw.dwm_users_shops (aggregation )
  • order_dw.dws_users (aggregation )
  • order_dw.dws_shops (aggregation )

我们经常会有这样的疑问:

1、假设mysql源表中的order_dw.orders的buy_fee在下游paimon流任务表dwm_users_shopsdws_usersdws_shops中都已经完成聚合统计后,这时候,这时候突然对order_dw.orders表中的某一条数据就行修改纠正,正常的业务场景就是改价,那么下游的aggregation任务会是如何?数据是否会纠正?纠正的原理和逻辑是什么?
2、假设我的dwm_users_shops任务突然终止,并且需要从某一个checkpoint/savepoint恢复,那么这时候aggregation任务又会是如何处理聚合数据的?

带着这个疑惑,我们来实践验证一下

实践

我们以Flink & Paimon & StarRocks & Dinky 流式湖仓分层实践验证为基础

目标

本文通过huggingface的Transform类进行BERT的文本分类代码训练与验证,数据集采用网上整理包括正向和负向评论的携程网数据

通过实战完整地去掌握完整代码步骤,包括:

  • 数据的加载
  • 创建数据集
  • 划分训练集和验证集
  • 创建模型和优化器
  • 模型的训练
  • 模型的验证
  • 模型的预测

实现当输入一个对酒店的评价的一段文字,模型输出对于这个酒店的分析,判断是正向评价还是负面评价

BERT适用场景

BERT(Bidirectional Encoder Representations from Transformers)是一种基于Transformer的预训练语言模型,它在自然语言处理(NLP)领域中具有广泛的应用,以下是一些BERT特别适用的场景:

  • 1、文本分类:BERT可以用于情感分析、主题分类、垃圾邮件检测等文本分类任务。它能够捕捉到文本中细微的语义差异,从而实现更准确的分类。
  • 2、问答系统:BERT可以用于构建问答系统,它能够理解问题的上下文,并在大量文本中找到正确的答案。
  • 3、命名实体识别(NER):在NER任务中,BERT能够识别文本中的特定实体,如人名、地点、组织等。
  • 4、机器翻译:虽然BERT最初是为英语设计的,但它也可以通过多语言预训练模型来支持机器翻译任务。
  • 5、文本摘要:BERT可以用于生成文本的摘要,无论是提取式摘要还是生成式摘要。
  • 6、语言模型评估:BERT可以用于评估其他语言模型的性能,通过比较预训练模型和目标模型的表示。
  • 7、文本相似度:BERT可以用于计算文本之间的相似度,这在推荐系统、搜索引擎优化等领域非常有用。
  • 8、对话系统:BERT可以用于构建对话系统,理解用户的意图,并生成合适的回复。
  • 9、文档分类:在法律、医疗等领域,BERT可以用于对文档进行分类,帮助专业人士快速定位信息。
  • 10、文本生成:虽然BERT主要用于理解语言,但它也可以用于文本生成任务,如续写故事、生成诗歌等。
  • 11、语义匹配:BERT可以用于比较两个句子的语义相似度,这在语义搜索、信息检索等领域非常有用。
  • 12、文本纠错:BERT可以用于检测和纠正文本中的错误,提高文本质量。
  • 13、多任务学习:BERT可以同时处理多个NLP任务,通过共享表示来提高各个任务的性能。

本次数据集介绍

数据集来源于网络整理的携程网数据, 包括7000 多条酒店评论数据,5000 多条正向评论,2000 多条负向评论

地址:https://github.com/SophonPlus/ChineseNlpCorpus/tree/master/datasets/ChnSentiCorp_htl_all

字段说明

字段 说明
label 1 表示正向评论,0 表示负向评论
review 评论内容

MQPdAa

硬件环境

本例比较简单,好点配置的电脑应该都跑得了,但为了熟悉还是用GPU来玩一下,熟悉一下方便以后租借算力。
本次实验使用AutoDL AI算力云 租借算力,采用GPU卡进行训练,使用Ubuntu 24.04LTS版本,Python使用Python 3.12.3版本

基本的硬件配置如下:

  • CPU: 16 核,Xeon(R) Gold 6430
  • 内存: 120 GB
  • GPU: Nvidia RTX 4090 / 24 GB

IX3I8x

https://github.com/zyds/transformers-code/blob/master/01-Getting%20Started/07-trainer/classification_demo.ipynb

其他可用数据集

https://github.com/CLUEbenchmark/CLUEDatasetSearch

0%