背景

  • 行业:生物试剂
  • 手上有自产试剂的所有说明书,大概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

可行性总结与分析

硬件环境

1
2
3
4
nvidia-smi

pip install nvitop
nvitop

TnPQDZ

环境准备

  • 安装依赖
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    ## 克隆项目
    git clone 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
  • 校验环境
    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
    CUDA_VISIBLE_DEVICES=0 USE_MODELSCOPE_HUB=1 llamafactory-cli webui
    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系统,希望虚拟机rocky linux 10 直通物理显卡。

  • vmware ESXi-8.0U2-22380479
  • rocky linux 10

直通模式配置

vmware esxi 配置

由于ESXi 8.0没有对12代以后的CPU做默认的支持,所以在安装ESXi 8.0过程中会遇到紫屏的问题。为了解决这一问题,需要对ESXi的启动参数进行修改。

    1. 修改启动参数
      在ESXi启动界面,按 Shift + O 进入启动选项编辑模式,然后添加以下参数:cpuUniformityHardCheckPanic=FALSE
      完整的启动参数示例如下:kernelopt=… cpuUniformityHardCheckPanic=FALSE
    1. 启动后通过SSH调整系统配置
      启动进入ESXi系统后,通过SSH连接到主机,并执行以下命令以永久应用修改:
      1
      esxcli system settings kernel set -s cpuUniformityHardCheckPanic -v FALSE
      此命令将启动参数持久化,确保每次启动ESXi时都应用该设置,防止紫屏问题再次出现。
    1. 配置NVIDIA显卡直通
      为了在虚拟机中成功直通NVIDIA显卡,还需要进行特定的配置
    • lspci -v | grep -i nvidia
      1
      2
      3
      4
      0000:81:00.0 Display controller 3D controller: NVIDIA Corporation Device 26ba
      0000:82:00.0 Display controller 3D controller: NVIDIA Corporation Device 26ba
      0000:c1:00.0 Display controller 3D controller: NVIDIA Corporation Device 26ba
      0000:c2:00.0 Display controller 3D controller: NVIDIA Corporation Device 26ba
    • lspci -v | grep -i nvidia -A1
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      0000:81:00.0 Display controller 3D controller: NVIDIA Corporation Device 26ba
      Class 0302: 10de:26ba
      --
      0000:82:00.0 Display controller 3D controller: NVIDIA Corporation Device 26ba
      Class 0302: 10de:26ba
      --
      0000:c1:00.0 Display controller 3D controller: NVIDIA Corporation Device 26ba
      Class 0302: 10de:26ba
      --
      0000:c2:00.0 Display controller 3D controller: NVIDIA Corporation Device 26ba
      Class 0302: 10de:26ba
    • 编辑ESXi配置文件:
      通过SSH连接到ESXi主机,执行以下命令将显卡设备标记为直通设备:
      1
      2
      3
      4
      echo '/device/0000:c2:00.0/owner = "passthru"' >> /etc/vmware/esx.conf
      echo '/device/0000:81:00.0/owner = "passthru"' >> /etc/vmware/esx.conf
      echo '/device/0000:c1:00.0/owner = "passthru"' >> /etc/vmware/esx.conf
      echo '/device/0000:82:00.0/owner = "passthru"' >> /etc/vmware/esx.conf
      其中,0000:01:00.0为NVIDIA显卡的PCI地址,请根据实际硬件调整。
    • 更新Passthru映射文件:
      为了确保显卡的各项功能能够正确直通,需在passthru.map文件中添加相关配置。执行以下命令:
      1
      2
      3
      echo '10de 26ba bridge false' >> /etc/vmware/passthru.map
      echo '10de 26ba link false' >> /etc/vmware/passthru.map
      echo '10de 26ba d3d0 false' >> /etc/vmware/passthru.map
      这里的10de 26ba代表NVIDIA显卡的厂商ID和设备ID,请根据你的显卡型号进行相应调整。
    • 重启ESXi服务:
      为使上述配置生效,需要重启ESXi的管理代理服务。执行以下命令:
      1
      2
      /etc/init.d/hostd restart
      /etc/init.d/vpxa restart
      或者,您也可以选择重启整个ESXi主机。

虚拟机配置

  • 创建虚拟机及配置参数
    • 预留全部内存
      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 = 128

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。计算方式为24*2=48,在32和64之间,先舍入到64,再次舍入到128

BCylVm

linux 驱动安装

  • 内核版本及更新

    1
    2
    uname -r
    sudo dnf update -y
  • 安装基本开发工具

    1
    2
    sudo dnf install epel-release -y
    sudo dnf groupinstall "Development Tools" -y
  • 内核制备

    安装内核开发包;提高兼容性,安装与当前内核版本匹配的内核头文件

    1
    2
    sudo dnf install kernel-devel -y
    sudo dnf install kernel-headers-$(uname -r) -y
  • 安装 Dynamic Kernel Module Support (DKMS)

    DKMS 会在内核更新发生时自动重建内核模块,确保您的 NVIDIA 驱动程序在系统更新后仍然正常运行:

    1
    sudo dnf install dkms -y
  • 将官方 NVIDIA CUDA 存储库添加到您的系统。对于 Rocky Linux 10,请使用 RHEL 9 兼容存储库:

    1
    2
    3
    sudo dnf config-manager --add-repo http://developer.download.nvidia.com/compute/cuda/repos/rhel9/$(uname -i)/cuda-rhel9.repo
    # 更新您的包缓存以识别新的仓库:
    sudo dnf makecache
  • 在安装实际的 NVIDIA 驱动程序之前,请确保存在所有必要的依赖项:

    1
    sudo dnf install kernel-headers-$(uname -r) kernel-devel-$(uname -r) tar bzip2 make automake gcc gcc-c++ pciutils elfutils-libelf-devel libglvnd-opengl libglvnd-glx libglvnd-devel acpid pkgconfig dkms -y
  • 禁用 Nouveau 驱动程序

    Nouveau 驱动程序提供基本功能,但缺乏 CUDA 支持、最佳游戏性能和专业工作站功能等高级功能。专有的 NVIDIA 驱动程序提供完整的功能集和更好的性能优化。
    使用 grubby 命令修改内核参数并将 Nouveau 驱动程序列入黑名单:

    1
    sudo grubby --args="nouveau.modeset=0 rd.driver.blacklist=nouveau" --update-kernel=ALL
    • 为了提高安全性,创建一个黑名单配置文件
      1
      2
      echo "blacklist nouveau" | sudo tee /etc/modprobe.d/blacklist-nouveau.conf
      echo 'omit_drivers+=" nouveau "' | sudo tee /etc/dracut.conf.d/blacklist-nouveau.conf
    • 重新生成初始 RAM 文件系统:
      1
      2
      sudo dracut --regenerate-all --force
      sudo depmod -a
  • 基本驱动程序验证

    1
    2
    3
    yum install pciutils
    sudo lspci | grep NVIDIA
    nvidia-smi
  • GUI 验证方法

    1
    nvidia-settings

参考链接

从坑中爬起: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(有 license 问题)

    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
## 安装下载环境
pip install modelscope
## 下载模型
modelscope download --model Qwen/Qwen3-30B-A3B
## 下载指定目录下
modelscope download --model Qwen/Qwen3-30B-A3B --local_dir /home/models
modelscope download --model Qwen/Qwen3-Embedding-8B --local_dir /home/models
modelscope download --model Qwen/Qwen3-Reranker-8B --local_dir /home/models

vllm 服务启动

vllm serve <model_path>

1
2
3
4
5
6
7
vllm serve /home/models/Qwen3-30B-A3B \
--port 8000 \
--host 0.0.0.0 \
--gpu-memory-utilization 0.95 \
--enable-reasoning \
--reasoning-parser deepseek_r1 \
--served-model-name Qwen3-30B-A3B

参数相关

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}]

docker compose 部署

  • Qwen3-30B-A3B

    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
    version: '3.8'

    services:
    qwen3:
    image: vllm/vllm-openai:latest # 使用最新的vLLM镜像
    container_name: qwen3-vllm
    restart: unless-stopped
    environment:
    - HF_ENDPOINT=https://hf-mirror.com
    - MODEL_PATH=/models/Qwen3-30B-A3B # 模型路径
    - SERVED_MODEL_NAME=Qwen3-30B-A3B # 对外服务时使用的模型名称
    - API_KEY=dakewe # 设置API密钥
    - MEMORY_UTILIZATION=0.95 # GPU内存利用率,接近但不超过显存限制
    volumes:
    - ./models:/models # 将本地的模型目录挂载到容器内的/models路径
    runtime: nvidia # 使用NVIDIA运行时以支持GPU
    deploy:
    resources:
    reservations:
    devices:
    - driver: nvidia
    count: all
    capabilities: [gpu]
    ports:
    - "8000:8000" # 将容器的8000端口映射到主机的8000端口
  • Qwen3-Embedding-8B

    临时,等vllm-openai 支持
    issue: https://github.com/vllm-project/vllm/issues/19229

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    services:
    Qwen3-Embedding-8B:
    container_name: Qwen3-Embedding-8B
    restart: no
    image: dengcao/vllm-openai:v0.9.2-dev #采用vllm最新的开发版制作的镜像,经测试正常,可放心使用
    ipc: host
    volumes:
    - ./models:/models
    command: ["--model", "/models/Qwen3-Embedding-8B", "--served-model-name", "Qwen3-Embedding-8B", "--gpu-memory-utilization", "0.90"]
    ports:
    - 8001:8000
    deploy:
    resources:
    reservations:
    devices:
    - driver: nvidia
    count: all
    capabilities: [gpu]
  • Qwen3-Reranker-8B

    临时,等vllm-openai 支持
    issue: https://github.com/vllm-project/vllm/issues/19229

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    services:  
    Qwen3-Reranker-8B:
    container_name: Qwen3-Reranker-8B
    restart: no
    image: dengcao/vllm-openai:v0.9.2-dev #采用vllm最新的开发版制作的镜像,经在NVIDIA RTX3060平台主机上测试正常,可放心使用。
    ipc: host
    volumes:
    - ./models:/models
    command: ['--model', '/models/Qwen3-Reranker-8B', '--served-model-name', 'Qwen3-Reranker-8B', '--gpu-memory-utilization', '0.90', '--hf_overrides','{"architectures": ["Qwen3ForSequenceClassification"],"classifier_from_token": ["no", "yes"],"is_original_qwen3_reranker": true}']
    deploy:
    resources:
    reservations:
    devices:
    - driver: nvidia
    count: all
    capabilities: [gpu]
    ports:
    - 8002:8000

背景

解决文档内容提取

前期调研

整体上看,大部分都是基于PaddleOCR基础上集成,比较有特点的是 MinerU

部署

docker-compose.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
version: '3.8'

services:
mineru-api:
image: mineru-api-full
container_name: mineru-api
runtime: nvidia # 需要NVIDIA Container Runtime支持
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: all
capabilities: [gpu]
shm_size: 32g
ports:
- "8888:8888"
- "30000:30000"
restart: unless-stopped

相关链接

基于MinerU 2.0的PDF解析API

背景

我们在过往尝试过使用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

安装依赖

1
2
3
pip install transformers datasets tokenizers
pip install torch==2.2.0
pip install "numpy<2"

下载

我们来尝试一下下载并使用模型

  • bert-base-chinese
  • gpt2-chinese-cluecorpussmall
  • roberta-base-chinese-extractive-qa

download_LLM.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from transformers import AutoModel, AutoTokenizer
# 分类模型
# model_name = "bert-base-chinese"
# cache_dir = "./models/bert-base-chinese"

# 文本生成模型
# model_name = "uer/gpt2-chinese-cluecorpussmall"
# cache_dir = "./models/gpt2-chinese-cluecorpussmall"

# 问答模型
model_name = "uer/roberta-base-chinese-extractive-qa"
cache_dir = "./models/roberta-base-chinese-extractive-qa"

model = AutoModel.from_pretrained(model_name, cache_dir=cache_dir)
tokenizer = AutoTokenizer.from_pretrained(model_name, cache_dir=cache_dir)

使用

使用本地模型

  • 文本生成模型

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    from transformers import pipeline, AutoTokenizer, AutoModelForCausalLM
    model_dir = f"{绝对路径}/huggingFace/models/gpt2-chinese-cluecorpussmall/models--uer--gpt2-chinese-cluecorpussmall/snapshots/c2c0249d8a2731f269414cc3b22dff021f8e07a3"
    tokenizer = AutoTokenizer.from_pretrained(model_dir)
    model = AutoModelForCausalLM.from_pretrained(model_dir)
    generator = pipeline("text-generation", model=model, tokenizer=tokenizer, device=0)
    result = generator("你好,我是一款大模型",
    max_length=150,
    num_return_sequences=1,
    truncation=True,
    temperature=0.7,
    top_k=50,
    top_p=0.9,
    clean_up_tokenization_spaces=False
    )
    print(result)
  • 分类模型

    1
    2
    3
    4
    5
    6
    7
    from transformers import pipeline, BertTokenizer, BertForSequenceClassification
    model_dir = f"{绝对路径}/huggingFace/models/bert-base-chinese/models--bert-base-chinese/snapshots/c30a6ed22ab4564dc1e3b2ecbf6e766b0611a33f"
    model = BertForSequenceClassification.from_pretrained(model_dir)
    tokenizer = BertTokenizer.from_pretrained(model_dir)
    classifier = pipeline("text-classification", model=model, tokenizer=tokenizer)
    result = classifier("你好,我是一款大模型")
    print(result)
  • 问答模型

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    from transformers import pipeline, AutoTokenizer, AutoModelForQuestionAnswering
    model_dir = f"{绝对路径}/huggingFace/models/roberta-base-chinese-extractive-qa/models--uer--roberta-base-chinese-extractive-qa/snapshots/9b02143727b9c4655d18b43a69fc39d5eb3ddd53"
    tokenizer = AutoTokenizer.from_pretrained(model_dir)
    model = AutoModelForQuestionAnswering.from_pretrained(model_dir)
    qa_pipeline = pipeline("question-answering", model=model, tokenizer=tokenizer)
    result = qa_pipeline({
    "question":"Hugging Face 是什么",
    "context": "Hugging Face 是一个自然语言处理平台"
    })
    print(result)

背景与目标

我们之前曾评估使用过seatunnel做cdc入湖验证:seatunnel-cdc入湖实践,这些场景都是能直连数据库的场景,
业务需求中经常会出现无法直连数据库做cdc进行数据同步的场景,而这些场景就需要使用api进行数据对接,用海豚调度定时同步数据。

举个实际中的例子:

  • ERP(SAP)的库存数据进行同步入湖仓做库存分析

同时,本次目标希望其他同事能依样画葫芦,在以后的对接http接口到湖仓的时候能够自行完成,而非每遇到一个对接需求,就需要通过代码方式进行对接。

准备工作

  • seatunnel 2.3.10

    首先,您需要在${SEATUNNEL_HOME}/config/plugin_config文件中加入连接器名称,然后,执行命令来安装连接器,确认连接器在${SEATUNNEL_HOME}/connectors/目录下即可。
    本例中我们会用到:connector-jdbcconnector-paimon
    写入StarRocks也可以使用connector-starrocks,本例中的场景比较适合用connector-jdbc,所以使用connector-jdbc

    1
    2
    3
    4
    5
    6
    # 配置连接器名称
    --connectors-v2--
    connector-jdbc
    connector-starrocks
    connector-paimon
    --end--
    1
    2
    # 安装连接器
    sh bin/install-plugin.sh 2.3.10

seatunnel 任务

我们先至少保证能在本地完成seatunnel任务,再完成对海豚调度的对接

  • http to starRocks
    example/http2starrocks

    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
    98
    99
    100
    101
    102
    env {
    parallelism = 1
    job.mode = "BATCH"
    }

    source {
    Http {
    plugin_output = "stock"
    url = "https://ip/http/prd/query_sap_stock"
    method = "POST"
    headers {
    Authorization = "Basic XXX"
    Content-Type = "application/json"
    }
    body = """{"IT_WERKS": [{"VALUE": "1080"}]}"""
    format = "json"
    content_field = "$.ET_RETURN.*"
    schema {
    fields {
    MATNR = "string"
    MAKTX = "string"
    WERKS = "string"
    NAME1 = "string"
    LGORT = "string"
    LGOBE = "string"
    CHARG = "string"
    MEINS = "string"
    LABST = "double"
    UMLME = "double"
    INSME = "double"
    EINME = "double"
    SPEME = "double"
    RETME = "double"
    }
    }
    }
    }

    # 此转换操作主要用于字段重命名等用途
    transform {
    Sql {
    plugin_input = "stock"
    plugin_output = "stock-tf-out"
    query = "select MATNR, MAKTX, WERKS,NAME1,LGORT,LGOBE,CHARG,MEINS,LABST,UMLME,INSME,EINME,SPEME,RETME from stock"
    }
    }

    # 连接starRocks 进行数据分区覆写,本例适用starRocks建表,按照分区insert overwrite 覆写
    sink {
    jdbc {
    plugin_input = "stock-tf-out"
    url = "jdbc:mysql://XXX:9030/scm?useUnicode=true&characterEncoding=UTF-8&rewriteBatchedStatements=true"
    driver = "com.mysql.cj.jdbc.Driver"
    user = "lab"
    password = "XXX"
    compatible_mode="starrocks"
    query = """insert overwrite ods_sap_stock PARTITION (WERKS='1080') (MATNR, MAKTX, WERKS,NAME1,LGORT,LGOBE,CHARG,MEINS,LABST,UMLME,INSME,EINME,SPEME,RETME) values(?,?,?,?,?,?,?,?,?,?,?,?,?,?)"""
    }
    }

    # connector-starrocks进行对接 (未看到支持sql语句进行数据insert overwrite,本例子场景不适合),比较适合表数据全部删除重建场景
    // sink {
    // StarRocks {
    // plugin_input = "stock-tf-out"
    // nodeUrls = ["ip:8030"]
    // base-url = "jdbc:mysql://ip:9030/"
    // username = "lab"
    // password = "XXX"
    // database = "scm"
    // table = "ods_sap_stock"
    // batch_max_rows = 1000
    // data_save_mode="DROP_DATA"
    // starrocks.config = {
    // format = "JSON"
    // strip_outer_array = true
    // }
    // schema_save_mode = "RECREATE_SCHEMA"
    // save_mode_create_template="""
    // CREATE TABLE IF NOT EXISTS `scm`.`ods_sap_stock` (
    // MATNR STRING COMMENT '物料',
    // WERKS STRING COMMENT '工厂',
    // LGORT STRING COMMENT '库存地点',
    // MAKTX STRING COMMENT '物料描述',
    // NAME1 STRING COMMENT '工厂名称',
    // LGOBE STRING COMMENT '地点描述',
    // CHARG STRING COMMENT '批次编号',
    // MEINS STRING COMMENT '单位',
    // LABST DOUBLE COMMENT '非限制使用库存',
    // UMLME DOUBLE COMMENT '在途库存',
    // INSME DOUBLE COMMENT '质检库存',
    // EINME DOUBLE COMMENT '受限制使用的库存',
    // SPEME DOUBLE COMMENT '已冻结的库存',
    // RETME DOUBLE COMMENT '退货'
    // ) ENGINE=OLAP
    // PRIMARY KEY ( MATNR,WERKS,LGORT)
    // COMMENT 'sap库存'
    // DISTRIBUTED BY HASH (WERKS) PROPERTIES (
    // "replication_num" = "1"
    // )
    // """
    // }
    // }
  • http to paimon
    example/http2paimon

    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
    env {
    parallelism = 1
    job.mode = "BATCH"
    }

    source {
    Http {
    plugin_output = "stock"
    url = "https://ip/http/prd/query_sap_stock"
    method = "POST"
    headers {
    Authorization = "Basic XXX"
    Content-Type = "application/json"
    }
    body = """{"IT_WERKS": [{"VALUE": "1080"}]}"""
    format = "json"
    content_field = "$.ET_RETURN.*"
    schema {
    fields {
    MATNR = "string"
    MAKTX = "string"
    WERKS = "string"
    NAME1 = "string"
    LGORT = "string"
    LGOBE = "string"
    CHARG = "string"
    MEINS = "string"
    LABST = "double"
    UMLME = "double"
    INSME = "double"
    EINME = "double"
    SPEME = "double"
    RETME = "double"
    }
    }
    }
    }
    # 此转换操作主要用于字段从命名等方便用途
    transform {
    Sql {
    plugin_input = "stock"
    plugin_output = "stock-tf-out"
    query = "select MATNR, MAKTX, WERKS,NAME1,LGORT,LGOBE,CHARG,MEINS,LABST,UMLME,INSME,EINME,SPEME,RETME from stock"
    }
    }

    # 连接paimon进行数据同步,paimon 暂时 未看到有支持 insert overwrite 分区覆写,此例仅作为参考,不适用本此例子需求
    sink {
    Paimon {
    warehouse = "s3a://test/"
    database = "sap"
    table = "ods_sap_stock"
    paimon.hadoop.conf = {
    fs.s3a.access-key=XXX
    fs.s3a.secret-key=XXX
    fs.s3a.endpoint="http://minio:9000"
    fs.s3a.path.style.access=true
    fs.s3a.aws.credentials.provider=org.apache.hadoop.fs.s3a.SimpleAWSCredentialsProvider
    }
    }
    }

dolphinscheduler 集成seatunnel

  • 制作worker镜像
    1
    2
    3
    4
    5
    FROM dolphinscheduler.docker.scarf.sh/apache/dolphinscheduler-worker:3.2.2
    RUN mkdir /opt/seatunnel
    RUN mkdir /opt/seatunnel/apache-seatunnel-2.3.10
    # 容器集成seatunnel
    COPY apache-seatunnel-2.3.10/ /opt/seatunnel/apache-seatunnel-2.3.10/
    打包镜像,推送到镜像仓库
    1
    docker build --platform=linux/amd64 -t apache/dolphinscheduler-worker:3.2.2-seatunnel .
  • 使用新镜像部署一个worker,此处修改 docker-compose.yaml,增加一个 dolphinscheduler-worker-seatunnel节点
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    ...
    dolphinscheduler-worker-seatunnel:
    image: xxx/dolphinscheduler-worker:3.2.2-seatunnel
    profiles: ["all"]
    env_file: .env
    healthcheck:
    test: [ "CMD", "curl", "http://localhost:1235/actuator/health" ]
    interval: 30s
    timeout: 5s
    retries: 3
    depends_on:
    dolphinscheduler-zookeeper:
    condition: service_healthy
    volumes:
    - ./dolphinscheduler-worker-seatunnel-data:/tmp/dolphinscheduler
    - ./dolphinscheduler-logs:/opt/dolphinscheduler/logs
    - ./dolphinscheduler-shared-local:/opt/soft
    - ./dolphinscheduler-resource-local:/dolphinscheduler
    networks:
    dolphinscheduler:
    ipv4_address: 172.15.0.18
    ...
  • dolphinscheduler配置seatunnel 分组及环境配置
    • 安全中心-Worker分组管理,创建一个这个节点ip的分组,用于以后需要seatunnel的任务跑该分组
      iX5FOs
    • 环境管理-创建环境,增加一个用于执行seatunnel的环境,同时需要绑定Worker分组为上一步创建的seatunnel分组
      GXYYpj
    • 创建工作流定义,把上面的seatunnel任务配置填写上
      fwe13Y
    • 运行时候,选择seatunnel的worker分组和环境即可跑在这个集成了seatunnel的环境上
      n8Y2w9
0%