【从零开始】11. LLaMA-Factory 微调 Qwen 模型(番外篇)
书接上回,在完成了 RAGChecker 测试后,离 RAG 应用真正发布还差最后一步 - 基础信息指令微调。考虑到模型还是需要具备一定程度的“自我认知”,因此需要将公司信息“嵌入”到模型里面的。为此,我选择了 LLaMA-Factory(以下简称“lf”)去完成这个事儿。
之所以选 lf 还是因为它简单,好使…
LLaMA-Factory 部署
本次 lf 微调我们将采用源码方式部署。
首先从 github 将代码 checkout 下来,如下图:
(base) pai@pai:~/llm/nlp$ git clone https://github.com/hiyouga/LLaMA-Factory.git
为什么要使用源码方式部署?后面会讲解原因。
创建虚拟环境并安装依赖
(base) pai@pai:~/llm/nlp$ cd LLaMA-Factory
(base) pai@pai:~/llm/nlp/LLaMA-Factory$ conda create -n lf python=3.11
Channels:- https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main- https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/r- https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/msys2- defaults
Platform: linux-64
Collecting package metadata (repodata.json): done
Solving environment: done
## Package Plan ##environment location: /home/pai/anaconda3/envs/lfadded / updated specs:- python=3.11...
使用 conda 创建运行环境后切换到源码目录通过pip install -r requirements.txt
命令安装依赖,如下图:
(base) pai@pai:~/llm/nlp/LLaMA-Factory$ conda activate lf
(lf) pai@pai:~/llm/nlp/LLaMA-Factory$ pip install -r requirements.txt
...
组件安装
根据官网的提示,if 是可以选择组件进行安装的,基础版本可以只选 torch 和 metrics 安装即可。但是装都装了,不差那么点事儿,索性全部能装的都装上吧。如下图:
(lf) pai@pai:~/llm/nlp/LLaMA-Factory$ pip install -e ".[torch,metrics,deepspeed,liger-kernel,bitsandbytes,hqq,gptq,awq,aqlm,vllm,galore,badam,adam-mini,qwen,modelscope,quality]"
...
安装过程中可能会出现一堆像“无法连接”、“依赖缺失”等情况,这时只需离线安装即可(之前文章已经提到过如何离线安装,这里就不再详述了)。
启动 webui 页面
完成组件安装后就可以尝试启动 webui 界面了,一般来说第一次启动会伴随着报错,如下图:
(lf) pai@pai:~/llm/nlp/LLaMA-Factory$ CUDA_VISIBLE_DEVICES=0 python src/webui.py
[2024-11-01 04:01:01,361] [INFO] [real_accelerator.py:203:get_accelerator] Setting ds_accelerator to cuda (auto detect)
df: /home/pai/.triton/autotune: No such file or directory[WARNING] async_io requires the dev libaio .so object and headers but these were not found.[WARNING] async_io: please install the libaio-dev package with apt[WARNING] If libaio is already installed (perhaps from source), try setting the CFLAGS and LDFLAGS environment variables to where it can be found.[WARNING] Please specify the CUTLASS repo directory as environment variable $CUTLASS_PATH[WARNING] sparse_attn requires a torch version >= 1.5 and < 2.0 but detected 2.4[WARNING] using untested triton version (3.0.0), only 1.0.0 is known to be compatible
/home/pai/anaconda3/envs/lf/lib/python3.11/site-packages/deepspeed/runtime/zero/linear.py:47: FutureWarning: `torch.cuda.amp.custom_fwd(args...)` is deprecated. Please use `torch.amp.custom_fwd(args..., device_type='cuda')` instead.@autocast_custom_fwd
/home/pai/anaconda3/envs/lf/lib/python3.11/site-packages/deepspeed/runtime/zero/linear.py:66: FutureWarning: `torch.cuda.amp.custom_bwd(args...)` is deprecated. Please use `torch.amp.custom_bwd(args..., device_type='cuda')` instead.@autocast_custom_bwd
/home/pai/anaconda3/envs/lf/lib/python3.11/site-packages/vllm/connections.py:8: RuntimeWarning: Failed to read commit hash:
No module named 'vllm._version'from vllm.version import __version__ as VLLM_VERSION
Running on local URL: http://0.0.0.0:7860To create a public link, set `share=True` in `launch()`.
以上报错是因为找不到“vllm._version”模块导致的,这时需要更新一下 vllm 依赖,如下图:
(lf) pai@pai:~/llm/nlp/LLaMA-Factory$ pip install --upgrade vllm
Looking in indexes: https://mirrors.aliyun.com/pypi/simple
Requirement already satisfied: vllm in /home/pai/anaconda3/envs/lf/lib/python3.11/site-packages (0.6.3)
Collecting vllmDownloading https://mirrors.aliyun.com/pypi/packages/4a/4c/ee65ba33467a4c0de350ce29fbae39b9d0e7fcd887cc756fa993654d1228/vllm-0.6.3.post1-cp38-abi3-manylinux1_x86_64.whl (194.8 MB)━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 194.8/194.8 MB 1.4 MB/s eta 0:00:00
...
一般将依赖更新到最新版后就能解决问题。再尝试启动 webui。
喔!抛出了另一个异常信息,如下图:
(lf) pai@pai:~/llm/nlp/LLaMA-Factory$ llamafactory-cli webui
[2024-11-01 05:46:26,356] [INFO] [real_accelerator.py:203:get_accelerator] Setting ds_accelerator to cuda (auto detect)[WARNING] async_io requires the dev libaio .so object and headers but these were not found.[WARNING] async_io: please install the libaio-dev package with apt[WARNING] If libaio is already installed (perhaps from source), try setting the CFLAGS and LDFLAGS environment variables to where it can be found.[WARNING] Please specify the CUTLASS repo directory as environment variable $CUTLASS_PATH[WARNING] sparse_attn requires a torch version >= 1.5 and < 2.0 but detected 2.4[WARNING] using untested triton version (3.0.0), only 1.0.0 is known to be compatible
/home/pai/anaconda3/envs/lf/lib/python3.11/site-packages/deepspeed/runtime/zero/linear.py:47: FutureWarning: `torch.cuda.amp.custom_fwd(args...)` is deprecated. Please use `torch.amp.custom_fwd(args..., device_type='cuda')` instead.@autocast_custom_fwd
/home/pai/anaconda3/envs/lf/lib/python3.11/site-packages/deepspeed/runtime/zero/linear.py:66: FutureWarning: `torch.cuda.amp.custom_bwd(args...)` is deprecated. Please use `torch.amp.custom_bwd(args..., device_type='cuda')` instead.@autocast_custom_bwd
Running on local URL: http://0.0.0.0:7860To create a public link, set `share=True` in `launch()`.
这次看到的是 deepspeed 警告,那么同理更新一下 deepspeed 吧。
(lf) pai@pai:~/llm/nlp/LLaMA-Factory$ pip install --upgrade deepspeed
...
更新后再启动就看不到其他异常信息抛出了。如下图:
(lf) pai@pai:~/llm/nlp/LLaMA-Factory$ llamafactory-cli webui
[2024-11-01 06:46:43,215] [INFO] [real_accelerator.py:219:get_accelerator] Setting ds_accelerator to cuda (auto detect)
Running on local URL: http://0.0.0.0:7860To create a public link, set `share=True` in `launch()`.
上传自定义数据
验证完 lf 正常启动后,在正式指令微调前,我们还需要上传自己的数据。
首先,我们需要创建自己的数据集并保存成 json 文件。我这里创建的是 alpaca 格式的数据集,具体格式如下:
[{"instruction": "<<这里是问题>>","input": "","output": "<<这里是答案>>"},...
]
在完成了数据集的整理之后将数据集上传到项目的 data 文件夹中,如下图:
接着修改 data 文件夹下的 dataset_info.json 文件,如下图:
{"enterprise":{"file_name": "enterprise_tuning.json","columns": {"prompt": "instruction","query": "input","response": "output","history": "history"}},...
}
这里的配置主要是对 columns 进行映射并将数据集作为系统级别命名为“enterprise”。
指令微调
微调数据集准备完毕,接下来需要做一下微调配置。首先,在examples/train_lora/
路径下创建一个 Lora 微调配置文件qwen2_5_lora_sft.yaml
,如下图:
### model
model_name_or_path: /home/pai/.cache/huggingface/hub/models--Qwen--Qwen2.5-7B-Instruct/snapshots/bb46c15ee4bb56c5b63245ef50fd7637234d6f75### method
stage: sft
do_train: true
finetuning_type: lora
lora_target: all### dataset
dataset: identity,enterprise
template: qwen
cutoff_len: 2048
max_samples: 4000
overwrite_cache: true
preprocessing_num_workers: 16### output
output_dir: /home/pai/llm/nlp/LLaMA-Factory/saves/Qwen2.5-7B/lora
logging_steps: 10
save_steps: 500
plot_loss: true
overwrite_output_dir: true### train
per_device_train_batch_size: 8
gradient_accumulation_steps: 2
learning_rate: 1.0e-4
num_train_epochs: 3.0
lr_scheduler_type: cosine
warmup_ratio: 0.1
bf16: true
ddp_timeout: 180000000### eval
val_size: 0.1
per_device_eval_batch_size: 1
eval_strategy: steps
eval_steps: 500
这里感谢 CSDN@路人与大师 提供的配置信息(文章里面详细地解释了每个参数的意思,受益良多,感谢分享),原文地址:llama factory lora 微调 qwen2.5 7B Instruct模型_qwen2.5 lora微调-CSDN博客
第一次的微调配置就以上面文章中提供的配置信息进行了部分调整而来的。接着执行
(lf) pai@pai:~/llm/nlp/LLaMA-Factory$ llamafactory-cli train examples/train_lora/qwen2_5_lora_sft.yaml
开始执行。
微调报错处理
在开始执行不久,也就是在读取数据集的时候就抛出了以下错误,如下图:
Converting format of dataset (num_proc=16): 0%| | 0/3601 [00:00<?, ? examples/s]
multiprocess.pool.RemoteTraceback:
"""
Traceback (most recent call last):File "/home/pai/anaconda3/envs/lf/lib/python3.11/site-packages/multiprocess/pool.py", line 125, in workerresult = (True, func(*args, **kwds))^^^^^^^^^^^^^^^^^^^File "/home/pai/anaconda3/envs/lf/lib/python3.11/site-packages/datasets/utils/py_utils.py", line 678, in _write_generator_to_queuefor i, result in enumerate(func(**kwargs)):File "/home/pai/anaconda3/envs/lf/lib/python3.11/site-packages/datasets/arrow_dataset.py", line 3528, in _map_singleexample = apply_function_on_filtered_inputs(example, i, offset=offset)^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^File "/home/pai/anaconda3/envs/lf/lib/python3.11/site-packages/datasets/arrow_dataset.py", line 3427, in apply_function_on_filtered_inputsprocessed_inputs = function(*fn_args, *additional_args, **fn_kwargs)^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^File "/home/pai/llm/nlp/LLaMA-Factory/src/llamafactory/data/aligner.py", line 84, in convert_alpacaif dataset_attr.history and isinstance(example[dataset_attr.history], list):~~~~~~~^^^^^^^^^^^^^^^^^^^^^^File "/home/pai/anaconda3/envs/lf/lib/python3.11/site-packages/datasets/formatting/formatting.py", line 277, in __getitem__value = self.data[key]~~~~~~~~~^^^^^
KeyError: 'history'
经验证,这个错误除了源码部署时出现外,在 docker 环境下也会出现(不知道是不是配置有误,按理说 docker 环境下不会出现这种情况)。在网上找了一圈,最终在 github 中找到的解决方案:
数据集history 缺省值 · Issue #2490 · hiyouga/LLaMA-Factory
这里需要对源码进行修改,如下图:
BTW,在修改代码后需要删除项目中对应的 pyc 文件,再之后直接通过python src/train.py
来启动。如下图:
(lf) pai@pai:~/llm/nlp/LLaMA-Factory$ CUDA_VISIBLE_DEVICES=0 python src/train.py examples/train_lora/qwen2_5_lora_sft.yaml
在开始微调后你或许还会遇到AttributeError: 'AdamW' object has no attribute 'train'
报错。这时可以尝试将 transformers 进行降级处理。
AttributeError: ‘AdamW’ object has no attribute ‘train’ · Issue #33620 · huggingface/transformers
按照大神的说法将 transformers 降级到 4.44.2 版本即可,亲测有效。
第一次微调
好了,现在让我们进行第一次微调吧,生成结果如下:
***** train metrics *****epoch = 3.0total_flos = 60516616GFtrain_loss = 0.4413train_runtime = 0:17:44.80train_samples_per_second = 9.506train_steps_per_second = 0.594
...
***** eval metrics *****epoch = 3.0eval_loss = 0.368eval_runtime = 0:00:18.79eval_samples_per_second = 19.955eval_steps_per_second = 19.955
嗯…这样的结果只能说是中规中矩,毕竟验证损失比训练损失小,说明模型没有过拟合,但还是有继续优化的空间。
第二次微调
鉴于第一次微调的结果,我调整了一下配置文件的参数:
### output
save_steps: 200### train
gradient_accumulation_steps: 4
learning_rate: 3.0e-5
num_train_epochs: 4.0
warmup_ratio: 0.03### eval
eval_steps: 200
- learning_rate = 1e-4 可能偏大,先尝试降到 3.0e-5 试试;
- 使用更温和的 warmup_ratio = 0.03;
- 第一次 num_train_epochs = 3.0,增加到 4 轮;
- 同时调整 eval_steps 和 save_steps 为 200 以更密切监控训练过程;
- 尝试将 gradient_accumulation_steps 调整为 2;
最终得到这样的结果:
***** train metrics *****epoch = 3.981total_flos = 80078311GFtrain_loss = 0.68train_runtime = 0:23:35.31train_samples_per_second = 9.536train_steps_per_second = 0.297
...
***** eval metrics *****epoch = 3.981eval_loss = 0.4965eval_runtime = 0:00:19.50eval_samples_per_second = 19.227eval_steps_per_second = 19.227
额…第二次的损失值反而上升了,这可能表明模型产生了一定程度的过拟合或学习率设置不够合适。
第三次微调
根据第二次微调的结果,我又做了以下的调整:
### train
gradient_accumulation_steps: 2
learning_rate: 7.0e-5
num_train_epochs: 2.0
warmup_ratio: 0.1
weight_decay: 0.1### lora
lora_rank: 8
lora_alpha: 32
lora_dropout: 0.1
- 增加了 weight_decay 参数来增加正则化;
- 取消了 ddp_timeout 参数;
- gradient_accumulation_steps 改回 2 ,因为 4 可能过大;
- 将 warmup_ratio 调回 0.1;
- 尝试减少训练轮次到 2 轮,因为当前可能训练过度;
- 第二次微调的学习率可能过小,导致模型收敛较慢,这里调整到 7.0e-5;
最终得到这样的结果:
***** train metrics *****epoch = 2.0total_flos = 40136469GFtrain_loss = 0.5282train_runtime = 0:12:54.95train_samples_per_second = 8.708train_steps_per_second = 0.545
...
***** eval metrics *****epoch = 2.0eval_loss = 0.3871eval_runtime = 0:00:18.87eval_samples_per_second = 19.872eval_steps_per_second = 19.872
Yo~,从结果看来这样的配置调整是有效的,相较于第二次微调有了明显的改善。并且 train_loss 和 eval_loss 的差距合理,没有明显过拟合。
第四次微调
好,现在明确了方向。接下来就向着这个方向走就可以了。
### dataset
max_samples: 5000### output
save_steps: 100### train
learning_rate: 8.0e-5
num_train_epochs: 2.5
warmup_ratio: 0.15### lora
lora_rank: 16
lora_alpha: 64### eval
val_size: 0.15
eval_steps: 100
- 继续提高学习率到 8.0e-5;
- 适当地增加训练轮次;
- 增加预热比例到 0.15;
- 增加 LoRA 秩到 16,alpha 值到 64;
- eval_steps 和 save_steps 降低到 100;
最终得到这样的结果:
***** train metrics *****epoch = 2.4962total_flos = 47735668GFtrain_loss = 0.4542train_runtime = 0:16:31.14train_samples_per_second = 8.036train_steps_per_second = 0.502
...
***** eval metrics *****epoch = 2.4962eval_loss = 0.3504eval_runtime = 0:00:28.31eval_samples_per_second = 19.884eval_steps_per_second = 19.884
eval_loss 持续下降到了0.3504,这是目前最好的结果。train_loss 和 eval_loss 的差距合理(约0.1),说明没有过拟合。
结论
从第四次之后其实已经找到了微调的方向,后面又陆续开展了其他参数的微调工作,这一共做了十一次。分析结果如下:
第一次:train_loss=0.4413, eval_loss=0.368 (差距0.0733)
第二次:train_loss=0.68, eval_loss=0.4965 (差距0.1835) ❌ 最差
第三次:train_loss=0.5282, eval_loss=0.3871 (差距0.1411)
第四次:train_loss=0.4542, eval_loss=0.3504 (差距0.1038)
第五次:train_loss=0.4184, eval_loss=0.3423 (差距0.0761) ✓ eval_loss最佳
第六次:train_loss=0.4413, eval_loss=0.3624 (差距0.0789)
第七次:train_loss=0.3834, eval_loss=0.3602 (差距0.0232) ✓ train_loss最佳
第八次:train_loss=0.4377, eval_loss=0.356 (差距0.0817)
第九次:train_loss=0.4069, eval_loss=0.357 (差距0.0499)
第十次:train_loss=0.4219, eval_loss=0.3553 (差距0.0666)
第十一次:train_loss=0.4393, eval_loss=0.3582 (差距0.0811)
根据观察 loss 的情况可知,train_loss 基本保持在 0.38-0.44 之间,而 eval_loss 则保持在 0.35-0.36 之间,并且最近 5 次的结果都相当稳定。其中,最佳的 train_loss 发生在第七次为 0.3834,而最佳的 eval_loss 发生在第五次为 0.3423,两者之间最小差距发生在第七次为 0.0232。
从收敛趋势来看,从第七次以后,性能提升已经相当小了,最近几次的调整没有带来明显改善且 loss 值在一个相对稳定的区间内波动。
因此我感觉已经没有继续优化的必要了,就拿回第七次的配置就可以了。
哦,在完成微调之后其实并没有结束微调工作,还有更大一部分内容在于对模型输出的验证,这个各位可以根据自己实际的业务需要进行人工校验。
至此,LLaMA-Factory 微调正式结束。
(未完待续…)
相关文章:

【从零开始】11. LLaMA-Factory 微调 Qwen 模型(番外篇)
书接上回,在完成了 RAGChecker 测试后,离 RAG 应用真正发布还差最后一步 - 基础信息指令微调。考虑到模型还是需要具备一定程度的“自我认知”,因此需要将公司信息“嵌入”到模型里面的。为此,我选择了 LLaMA-Factory(…...

WPF使用ContentControl控件实现区域导航,并使用Prism依赖注入优化
背景:使用ContentControl控件实现区域导航是有Mvvm框架的WPF都能使用的,不限于Prism 主要是将ContenControl控件的Content内容在ViewModel中切换成不同的用户控件 下面是MainViewModel: private object body;public object Body {get { retu…...

JavaWeb——MySQL-DML(1/3)-添加数据insert(DML 操作概述、INSERT 语句插入数据、语句演示、总结)
目录 DML 操作概述 INSERT 语句插入数据 INSERT 语句基础语法 INSERT 语句演示 注意事项 总结 DML 操作概述 DML 简介 DML(Data Manipulation Language)即数据操作语言,用于对数据库表中的数据进行增删改操作,包括添加数据&…...

经验证:将数据从索尼传输到Android的 4 种方法
概括 像Android Galaxy S20 这样的新型Android智能手机很酷,但除了将数据从索尼传输到Android之外。众所周知,旧的索尼手机上存储着大量的文件,因此将数据从旧的索尼手机传输到新的Android手机非常重要。为了解决这个问题,我们做…...

嵌入式应用实例→电子产品量产工具→UI界面的绘制和测试
前言 之前已经在博文https://blog.csdn.net/wenhao_ir/article/details/144747714中实现了用Freetype在LCD屏上绘制字符,本篇博文我们利用Freetype实现UI界面的绘制。 头文件include\ui.h的分析 头文件内的代码 #ifndef _UI_H #define _UI_H#include <common…...
如何删除 Docker 中的悬虚镜像?
在 Docker 中,悬虚镜像(Dangling Images)是指那些没有 标签 且没有被任何容器使用的镜像。这些镜像通常是由于构建过程中生成的中间层镜像或未正确清理的镜像残留。删除悬虚镜像可以释放磁盘空间并保持 Docker 环境的整洁。 1. 列出悬虚镜像…...
el-table树形懒加载展开改为点击行展开
思路:获取el-table中小箭头,然后调它的click事件! <el-tablerow-click"getOpenDetail":row-class-name"tableRowClassName">// 点击当前行展开节点getOpenDetail(row, column, event) {// 如果是叶子节点或点击的是…...

【Ubuntu】Ubuntu server 18.04 搭建Slurm并行计算环境(包含NFS)
Ubuntu server 18.04 搭建Slurm并行计算环境(包含NFS) 一、Munge 认证模块 1.1、安装 munge 主节点和子节点都安装munge #安装 sudo apt update && sudo apt install munge libmunge-dev#设置开机启动 sudo systemctl enable munge sudo syste…...
高并发场景下的秒杀系统架构设计与实现
引言 秒杀系统是一种高并发场景的典型应用,广泛存在于电商平台、抢票系统和促销活动中。秒杀活动的特点是短时间内吸引大量用户同时访问并尝试抢购商品,这对系统的高并发处理能力、稳定性和用户体验提出了极高的要求。 在秒杀系统中,常见的…...

搭建开源版Ceph分布式存储
系统:Rocky8.6 三台2H4G 三块10G的硬盘的虚拟机 node1 192.168.2.101 node2 192.168.2.102 node3 192.168.2.103 三台虚拟机环境准备 1、配置主机名和IP的映射关系 2、关闭selinux和firewalld防火墙 3、配置时间同步且所有节点chronyd服务开机自启 1、配置主机名和…...

QT----------多媒体
实现思路 多媒体模块功能概述: QT 的多媒体模块提供了丰富的功能,包括音频播放、录制、视频播放和摄像头操作等。 播放音频: 使用 QMediaPlayer 播放完整的音频文件。使用 QSoundEffect 播放简短的音效文件。 录制音频: 使用 QMe…...

选择器(结构伪类选择器,伪元素选择器),PxCook软件,盒子模型
结构为类选择器 伪元素选择器 PxCook 盒子模型 (内外边距,边框) 内外边距合并,塌陷问题 元素溢出 圆角 阴影: 模糊半径:越大越模糊,也就是越柔和 案例一:产品卡片 <!DOCTYPE html> <html lang&q…...
Vue2/Vue3 响应式原理对比指南
Vue2/Vue3 响应式原理对比指南 1. 基本实现原理 1.1 Vue2 响应式实现 (Object.defineProperty) // Vue2 响应式核心实现 function defineReactive(obj, key, val) {// 递归处理嵌套对象observe(val);const dep new Dep();Object.defineProperty(obj, key, {get() {// 依赖收…...
FastExcel:超越EasyExcel的新一代Excel处理工具
简介 FastExcel是由原EasyExcel作者在阿里巴巴宣布停止维护EasyExcel之后推出的升级版框架。它继承了EasyExcel的所有优点,并且在性能和功能上进行了显著的提升和创新。 FastExcel的特点 高性能读写:FastExcel专注于性能优化,能够高效处理…...

大模型系列17-RAGFlow搭建本地知识库
大模型系列17-RAGFlow搭建本地知识库 安装ollama安装open-wehui安装并运行ragflowRAG(检索、增强、生成)RAG是什么RAG三过程RAG问答系统构建步骤向量库构建检索模块生成模块 RAG解决LLM的痛点 使用ragflow访问ragflow配置ollama模型添加Embedding模型添加…...
常用的mac软件下载地址
目录 iRightMouse Pro(超级右键) xmind(思维导图) Parallels Desktop(虚拟机工具) Paste(跨平台复制粘贴) AutoSwitchInput Pro(自动切换输入法) Snipa…...

基于51单片机和16X16LED点阵屏(74HC138和74HC595驱动)的小游戏《贪吃蛇》
目录 系列文章目录前言一、效果展示二、原理分析三、各模块代码1、定时器02、自制八位独立按键3、点阵屏模块 四、主函数总结 系列文章目录 前言 《贪吃蛇》,一款经典的、怀旧的小游戏,单片机入门必写程序。 以《贪吃蛇》为载体,熟悉各种屏…...
python中常用的内置函数介绍
python中常用的内置函数介绍 1. print()2. len()3. type()4. str(), int(), float()5. list(), tuple(), set(), dict()6. range()7. sum()8. max(), min()9. sorted()10. zip()11. enumerate()12. map()13. filter()14. any(), all()15. abs()16. pow()17. round()18. ord(), …...

【微服务】Spring Cloud Config解决的问题和案例
文章目录 强烈推荐引言解决问题1. 配置管理的集中化2. 配置的版本控制3. 环境特定配置4. 配置的动态刷新5. 安全管理敏感数据6. 配置的一致性 组件1. **配置服务器(Config Server)**2. **配置客户端(Config Client)** 配置示例配置…...
华为OD机试E卷 --最小的调整次数--24年OD统一考试(Java JS Python C C++)
文章目录 题目描述输入描述输出描述用例题目解析JS算法源码Java算法源码python算法源码c算法源码c++算法源码题目描述 有一个特异性的双端队列一,该队列可以从头部或尾部添加数据,但是只能从头部移出数据。 小A依次执行2n个指令往队列中添加数据和移出数据。其中n个指令是添…...

超短脉冲激光自聚焦效应
前言与目录 强激光引起自聚焦效应机理 超短脉冲激光在脆性材料内部加工时引起的自聚焦效应,这是一种非线性光学现象,主要涉及光学克尔效应和材料的非线性光学特性。 自聚焦效应可以产生局部的强光场,对材料产生非线性响应,可能…...
在rocky linux 9.5上在线安装 docker
前面是指南,后面是日志 sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo sudo dnf install docker-ce docker-ce-cli containerd.io -y docker version sudo systemctl start docker sudo systemctl status docker …...

《从零掌握MIPI CSI-2: 协议精解与FPGA摄像头开发实战》-- CSI-2 协议详细解析 (一)
CSI-2 协议详细解析 (一) 1. CSI-2层定义(CSI-2 Layer Definitions) 分层结构 :CSI-2协议分为6层: 物理层(PHY Layer) : 定义电气特性、时钟机制和传输介质(导线&#…...

如何在网页里填写 PDF 表格?
有时候,你可能希望用户能在你的网站上填写 PDF 表单。然而,这件事并不简单,因为 PDF 并不是一种原生的网页格式。虽然浏览器可以显示 PDF 文件,但原生并不支持编辑或填写它们。更糟的是,如果你想收集表单数据ÿ…...
Java + Spring Boot + Mybatis 实现批量插入
在 Java 中使用 Spring Boot 和 MyBatis 实现批量插入可以通过以下步骤完成。这里提供两种常用方法:使用 MyBatis 的 <foreach> 标签和批处理模式(ExecutorType.BATCH)。 方法一:使用 XML 的 <foreach> 标签ÿ…...
IP如何挑?2025年海外专线IP如何购买?
你花了时间和预算买了IP,结果IP质量不佳,项目效率低下不说,还可能带来莫名的网络问题,是不是太闹心了?尤其是在面对海外专线IP时,到底怎么才能买到适合自己的呢?所以,挑IP绝对是个技…...
人工智能--安全大模型训练计划:基于Fine-tuning + LLM Agent
安全大模型训练计划:基于Fine-tuning LLM Agent 1. 构建高质量安全数据集 目标:为安全大模型创建高质量、去偏、符合伦理的训练数据集,涵盖安全相关任务(如有害内容检测、隐私保护、道德推理等)。 1.1 数据收集 描…...

Unity中的transform.up
2025年6月8日,周日下午 在Unity中,transform.up是Transform组件的一个属性,表示游戏对象在世界空间中的“上”方向(Y轴正方向),且会随对象旋转动态变化。以下是关键点解析: 基本定义 transfor…...
k8s从入门到放弃之HPA控制器
k8s从入门到放弃之HPA控制器 Kubernetes中的Horizontal Pod Autoscaler (HPA)控制器是一种用于自动扩展部署、副本集或复制控制器中Pod数量的机制。它可以根据观察到的CPU利用率(或其他自定义指标)来调整这些对象的规模,从而帮助应用程序在负…...

深入解析光敏传感技术:嵌入式仿真平台如何重塑电子工程教学
一、光敏传感技术的物理本质与系统级实现挑战 光敏电阻作为经典的光电传感器件,其工作原理根植于半导体材料的光电导效应。当入射光子能量超过材料带隙宽度时,价带电子受激发跃迁至导带,形成电子-空穴对,导致材料电导率显著提升。…...