Llama模型分布式训练(微调)
1 常见大模型
1.1 参数量对照表
| 模型 | 参数量 | 发布时间 | 训练的显存需求 |
|---|---|---|---|
| VGG-19 | 143.68M | 2014 | ~5 GB(单 224x224 图像,batch_size=32) |
| ResNet-152 | 60.19M | 2015 | ~7 GB(单 224x224 图像,batch_size=32) |
| GPT-2 117M | 117M | 2019 | ~4 GB(序列长度 1024,batch_size=8) |
| GPT-2 1.5B | 1.5B | 2019 | ~12 GB(序列长度 1024,batch_size=8) |
| BERT-base | 110M | 2018 | ~4 GB(序列长度 512,batch_size=8) |
| BERT-large | 340M | 2018 | ~12 GB(序列长度 512,batch_size=8) |
| Llama-2 7B | 7B | 2023 | ~28 GB(序列长度 2048,batch_size=8) |
| Llama-2 13B | 13B | 2023 | ~52 GB(序列长度 2048,batch_size=8) |
| Llama-2 70B | 70B | 2023 | ~280 GB(序列长度 2048,batch_size=8) |
| Chinchilla | 70B | 2022 | ~280 GB(序列长度 2048,batch_size=8) |
| GPT-3 | 175B | 2020 | ~700 GB(序列长度 2048,batch_size=8) |
| Megatron-Turing NLG 530B | 530B | 2021 | ~2 TB(序列长度 2048,batch_size=8) |
| GPT-4 | over 10000B(未公开) | 2023 | ---- |
注:
- 参数量 1M = 1 0 6 10^6 106 个浮点数,加载参数所需的内存为 1 0 6 ∗ 4 = 4 10^6 * 4 = 4 106∗4=4 MB。
- 实际训练时需要消耗的内存包括:参数 + 梯度 + 优化器状态 + 临时存储(激活值、通信缓冲区等)。其中:
- 参数、梯度、优化器状态所需显存大致分别等于参数量大小(总共3倍参数量那么大内存)。
- 激活值所需显存占比较高,且对输入大小(max_seq_length和batch_size)非常敏感。设序列长度为 𝐿,批大小为 𝐵,注意力头数为 𝐻,则: 显存需求 ∝ B × H × L 2 显存需求 \varpropto B \times H \times L^2 显存需求∝B×H×L2 。
1.2 Llama模型系列介绍
Llama 系列模型是 Meta(前 Facebook)推出的一系列高效的大规模预训练语言模型,采用了基于 Transformer 架构的设计。Llama-2 系列(包括 7B、13B 和 70B 参数版本)于 2023 年发布,旨在提供强大的自然语言处理能力,适用于文本生成、文本分类、问答等多种任务。Llama 模型的设计强调高效性和灵活性。与其他大型语言模型(如 GPT-3 和 GPT-4)相比,Llama 在训练过程中进行了显著的优化,能够在相对较少的计算资源上取得接近的性能表现。
| 模型 | 发布时间 | 应用领域 | 是否开源 |
|---|---|---|---|
| Llama-2 7B / 13B / 70B | 2023 | 各种规模下的预训练模型 | 是 |
| Llama-3.1 8B / 70B / 405B | 2024 | 各种规模下的预训练模型 | 是 |
| Llama-3.2 1B / 3B / 11B / 90B | 2024 | 各种规模下的预训练模型 | 是 |
| Llama Chat系列 | ------ | 提升对话系统的表现 | 是 |
| Llama Guard系列 | ------ | 用于安全和内容筛查任务 | 是 |
| Llama Code系列 | ------ | 优化了编程和代码生成任务 | 是 |
模型权重的下载:https://www.llama.com/llama-downloads/
2 分布式训练 Llama-2 7B 模型
文中代码已上传至 github
2.0 实验环境
使用云服务器进行训练,如果是本地GPU训练可以省去上传文件和写sbatch脚本的过程。
集群:国家广州超算 星逸A800智能AI集群
GPU:8 * Nvdia Tesla-A800 80G显存
CPU:2 * 28核 Intel Xeon Gold 6348
内存:1024GB
2.1 获取模型和权重,并简单运行测试
(1)获取llama-2模型(除权重以外部分),从 https://github.com/meta-llama/llama 上下载
(2)获取llama-2权重,需要先申请,参考:Hugging Face中下载大模型——LLaMa2-7b为例
(3)分别放到文件夹中
llama (步骤(1))
│ example_chat_completion.py
│ example_text_completion.py
│ tokenizer.model
│ tokenizer_checklist.chk
│ ......
│
└───llama-2-7b (步骤(2))
│ │ consolidated.00.pth
│ │ params.json
│ │ checklist.chk
│
(4)安装一些代码运行所需的python库
- torch 是神经网络训练的底层框架;
- transformers 集成了多种大模型,可以直接加载来训练;
- accelerate 简化了分布式训练多种模式的选择;
- sentencepiece 用于文本分词的库;
- protobuf 用于存储模型的配置信息(如模型架构、超参数等)以及数据存储格式;
- fire 用于快速实现和管理超参数调优和训练脚本的执行;
- fairscale 提供了几种优化策略,包括 ZeRO (Zero Redundancy Optimizer) 和 Mixed Precision Training,大幅提升分布式训练效率。
$ pip install torch transformers accelerate sentencepiece protobuf fire fairscale# 进入到之前下载好的 llama 文件夹
$ cd llama
(5)写个 run.sh 脚本或直接 srun 运行,测试运行一下预训练好的模型,运行 example_chat_completion.py 或 example_text_completion.py 都可以:
#!/bin/bash#SBATCH --nodes=1 # 节点数
#SBATCH --ntasks=1 # 任务数
#SBATCH --partition=gpu # 分区名称(根据集群修改)
#SBATCH --gres=gpu:1 # 设置使用的GPU数CUDA_VISIBLE_DEVICES=0
python -m torch.distributed.run \--nproc_per_node 1 \example_chat_completion.py \--ckpt_dir llama-2-7b \--tokenizer_path tokenizer.model \--max_seq_len 512 \--max_batch_size 6
然后 sbatch run.sh 运行脚本,这里注意:
- 单卡 max_seq_len 和 max_batch_size 不要太大,否则可能会导致内存不足。
- Windows系统上运行会报错。
(6)测试结果
example_chat_completion.py :

example_text_completion.py :

回复的有点意思但是对于具体问题不是很准确,所以需要根据具体问题进行微调。
2.2 模型微调(lora微调)
(1)定义问题,准备数据集
- 我们对模型进行微调的目的是让其在某个领域或问题实现更精准的回复,这需要在官方预训练好的模型权重的基础上,给它喂大量相关的数据集进行训练,但并不是修改所有权重参数,而是选一部分最重要的权重进行修正。
- 我定义的问题是:训练一个医疗专家模型,用户提出自己的诉求,模型可以给出诊断和建议。
- 我选择的数据集:从 hf-Mirror 上找了一份 病人-医生对话的数据集。可以看出数据集有三列分别是 Description, Patient, Doctor,前两列是用户的输入,最后一列是我们想要的答复,总共有25.7万条数据。

- 点击下载按钮下载数据文件即可。

(2)将权重参数从ckpt格式转换为safetensors格式
首先需要调整文件夹,将 tokenizer.model 和 tokenizer_checklist.chk 放到 llama-2-7b 文件夹中,然后再安装环境,执行转换命令。
# 文件位置
$ cd llama
$ mv ./tokenizer.model ./llama-2-7b/tokenizer.model
$ mv ./tokenizer_checklist.chk ./llama-2-7b/tokenizer_checklist.chk# 安装必要的库
$ pip install torch transformers accelerate sentencepiece protobuf fire fairscale -i https://pypi.tuna.tsinghua.edu.cn/simple# 定义执行的转换文件,并进行转换
$ TRANSFORM=`python -c"import transformers;print ('/'.join (transformers.__file__.split ('/')[:-1])+'/models/llama/convert_llama_weights_to_hf.py')"`
$ python $TRANSFORM --input_dir ./llama-2-7b --model_size 7B --output_dir ./llama-2-7b-hf
转换后的文件夹为 llama-2-7b-hf :
llama
│ example_chat_completion.py
│ example_text_completion.py
│ ......
│
└───llama-2-7b
│ │ consolidated.00.pth
│ │ params.json
│ │ checklist.chk
│ │ tokenizer_checklist.chk
│ │ tokenizer.model
│
└───llama-2-7b-hf
│ │ config.json
│ │ model-00001-of-00003.safetensors
│ │ tokenizer_config.json
│ │ tokenizer.json
│ │ ......
│
还有一种方式,这一步 llama-2-7b-hf 的内容也可以通过直接在 https://www.modelscope.cn/models/shakechen/Llama-2-7b-hf/files 上下载获得。
(3)编写训练代码 train.py :
背景知识介绍:
- lora微调:
LoRA(Low-Rank Adaptation of Large Language Models)是一种针对大规模预训练模型的参数高效微调(PEFT, Parameter-Efficient Fine-Tuning)技术。它通过引入少量可训练参数,实现对模型的高效适配,而无需对整个模型的权重进行更新。
具体思想和公式可以参考 https://www.zhihu.com/tardis/zm/art/623543497?source_id=1005- 模型的选择:
微调时可以根据任务选择加载不同的模型,但对应的数据集以及数据集预处理也要修改。可以使用同一份权重文件,transformers库会根据模型结构,自动初始化权重文件中没有的参数,进行训练。模型主要有:AutoModelForCausalLM:文本生成任务(专注于从左到右的语言生成任务,如聊天、创作等)。
AutoModelForSequenceClassification:用于文本分类任务。
AutoModelForTokenClassification:用于标注任务。
AutoModelForQuestionAnswering:用于问答任务。
AutoModelForMaskedLM:用于填充空白(填空)。
AutoModelForSeq2SeqLM:用于序列到序列的生成任务(如翻译、摘要生成等)。
等等。
import torch
from peft import LoraConfig, get_peft_model
from transformers import TrainingArguments, AutoModelForCausalLM, AutoTokenizer
from datasets import load_dataset
from trl import SFTTrainer
import time# 看一下环境中的 GPU 情况
print("Find GPUs:", torch.cuda.device_count(), [torch.cuda.get_device_name(i) for i in range(torch.cuda.device_count())]) # 加载数据集
data_files = {"train": "./data/dialogues.parquet"}
dataset = load_dataset("parquet", data_files=data_files)# 合并 Description, Patient 和 Doctor 字段,
def merge_fields(examples):examples["text"] = [f"Description: {Description} Patient: {Patient} Doctor: {Doctor}" for Description, Patient, Doctor in zip(examples["Description"], examples["Patient"], examples["Doctor"])]return examplesdataset = dataset.map(merge_fields, batched=True)# 划分数据集
split_dataset = dataset['train'].train_test_split(test_size=0.2, seed=42) # 划分数据集为训练集和测试集
train_dataset = split_dataset['train']
temp_split = split_dataset['test'].train_test_split(test_size=0.5, seed=42) # 再从测试集中划分验证集
test_dataset = temp_split['test']
eval_dataset = temp_split['train']# 打印各数据集的大小
print("Train size:", len(train_dataset))
print("Test size:", len(test_dataset))
print("Eval size:", len(eval_dataset))output_dir = './output'# 配置 lora 微调的参数
peft_config = LoraConfig(r=8,lora_alpha=8,target_modules=['q_proj', 'v_proj'],lora_dropout=0.05,bias='none',task_type='CAUSAL_LM'
)# 配置训练的参数
training_arguments = TrainingArguments(output_dir=output_dir,per_device_train_batch_size=16,optim='adamw_torch',learning_rate=10e-4,eval_steps=100,logging_steps=200,eval_strategy='steps',group_by_length=False,max_steps=200,# num_train_epochs=1,gradient_accumulation_steps=1,gradient_checkpointing=True,max_grad_norm=0.3,bf16=True,lr_scheduler_type='cosine',warmup_steps=100
)# 加载模型及权重,选择了 AutoModelForCausalLM 模型
model_path = './llama-2-7b-hf'
model = AutoModelForCausalLM.from_pretrained(model_path,torch_dtype=torch.float16,device_map='auto'
)model.enable_input_require_grads() # 允许权重参与反向传播
model = get_peft_model(model, peft_config) # 把模型用 PEFT 框架加载,以支持高效微调
model.print_trainable_parameters()
model.config.use_cache = False# 加载 tokenizer
tokenizer = AutoTokenizer.from_pretrained(model_path, trust_remote_code=True)
tokenizer.pad_token_id = 0
tokenizer.padding_side = 'right'# 定义 Trainer
trainer = SFTTrainer(model=model,train_dataset=train_dataset,eval_dataset=eval_dataset,peft_config=peft_config,tokenizer=tokenizer,args=training_arguments,max_seq_length=512,dataset_text_field='text',
)# 训练,并打印时间
print("start training")
start_time = time.time()
trainer.train()
end_time = time.time()
print("finished training")
print("time_used:", end_time-start_time, "s")trainer.model.save_pretrained(output_dir)
(4)编写训练脚本 train.sh :
#!/bin/bash#SBATCH --nodes=1 # 节点数
#SBATCH --ntasks=1 # 任务数
#SBATCH --partition=ai # 分区名称(根据集群修改)export CUDA_VISIBLE_DEVICES=0 # 只用单 GPU 训练python train.py
(5)配置环境并训练
# 安装必要的包
$ pip install torch transformers datasets trl peft# 执行训练(微调)
$ sbatch train.sh
(6)合并权重文件
训练完成后,会生成一个 ./output 文件夹,里面有需要调整的部分权重信息,需要和原权重文件合并更新。编写 merge.py :
from peft import AutoPeftModelForCausalLM
from transformers import AutoTokenizer
import torchbase_model_path = './llama-2-7b-hf'
finetune_model_path = './output'# 加载 tokenizer 和 model
tokenizer = AutoTokenizer.from_pretrained(base_model_path, trust_remote_code=True)
model = AutoPeftModelForCausalLM.from_pretrained(finetune_model_path, device_map='auto', torch_dtype=torch.bfloat16)# 合并权重
model = model.merge_and_unload()# 保存权重文件
merged_model_path = './llama-2-7b-merged'
model.save_pretrained(merged_model_path)
命令行执行:
$ module load CUDA/12.2
$ srun --partition=ai --nodes=1 python merge.py
新生成的 ./llama-2-7b-merged 文件夹里是更新后的模型和权重。
(7)训练结果测试
找了一个 prompt ,分别用合并前和合并后的权重测试一下
import torch
from transformers import LlamaForCausalLM, AutoTokenizerbase_model_path = './llama-2-7b-hf'
merged_model_path = './llama-2-7b-merged'tokenizer = tokenizer = AutoTokenizer.from_pretrained(base_model_path, trust_remote_code=True)test_prompt = """
Description: Q. Every time I eat spicy food, I poop blood. Why?
Patient: Hi doctor, I am a 26 year old male. I am 5 feet and 9 inches tall and weigh 255 pounds. When I eat spicy food, I poop blood. Sometimes when I have constipation as well, I poop a little bit of blood. I am really scared that I have colon cancer. I do have diarrhea often. I do not have a family history of colon cancer. I got blood tests done last night. Please find my reports attached.
Doctor:
"""model_input = tokenizer(test_prompt, return_tensors='pt').to('cuda')model = LlamaForCausalLM.from_pretrained(base_model_path, load_in_8bit=False, device_map='auto', torch_dtype=torch.float16)
model.eval()
with torch.no_grad():result = model.generate(**model_input, max_new_tokens=150)[0]print("---------------Result Before Finetuned---------------")print(tokenizer.decode(result, skip_special_tokens=True))model = LlamaForCausalLM.from_pretrained(merged_model_path, load_in_8bit=False, device_map='auto', torch_dtype=torch.float16)
model.eval()
with torch.no_grad():result = model.generate(**model_input, max_new_tokens=150)[0]print("---------------Result After Finetuned---------------")print(tokenizer.decode(result, skip_special_tokens=True))
输出结果对比:


可以看出,微调后对于输出格式和内容都有了一定的进步。
2.3 分布式训练微调(使用DeepSpeed分布式训练框架)
- 在上面的训练过程中,我们发现单卡80G内存只能支持最大 batch_size=16, maxmax_seq_length=512,且训练速度非常慢(大概2-3 batch/s),这个数据集本身还不是非常大(25万条),模型也不是非常大(7B)。想要进一步扩大规模 / 加速训练,必须采用分布式训练。
(1)准备deepspeed环境
$ pip install deepspeed
(2)编写deepspeed配置文件 ds_config.json :
{"train_batch_size": 64,"train_micro_batch_size_per_gpu": 16,"gradient_accumulation_steps": 1,"optimizer": {"type": "Adam","params": {"lr": 10e-4,"betas": [0.9, 0.999],"eps": 1e-8}},"zero_optimization": {"stage": 2}
}
(3)修改训练代码 deepspeed_train.py :
- 相对于单卡的代码,需要修改的地方加了注释。
- 通过 transformers.Trainer 训练非常方便,会自动初始化 deepspeed 和分布式环境,所有的分布式配置只要写到
ds_config.json中就可以了。 - 这里有两个小问题:一个是
ds_config.json中的 “train_micro_batch_size_per_gpu” 必须和deepspeed_train.py中的 “per_device_train_batch_size” 一致;一个是zero对于微调不支持 stage3。
import torch
from peft import LoraConfig, get_peft_model
from transformers import TrainingArguments, AutoModelForCausalLM, AutoTokenizer
from datasets import load_dataset
from trl import SFTTrainer
import time# 导入 deepspeed 库和 pytorch 通信后端
import deepspeed
import torch.distributed as dist# 修改:初始化分布式环境
deepspeed.init_distributed()
world_size = dist.get_world_size()
rank = dist.get_rank()data_files = {"train": "./data/dialogues.parquet"}
dataset = load_dataset("parquet", data_files=data_files)def merge_fields(examples):examples["text"] = [f"Description: {Description} Patient: {Patient} Doctor: {Doctor}" for Description, Patient, Doctor in zip(examples["Description"], examples["Patient"], examples["Doctor"])]return examplesdataset = dataset.map(merge_fields, batched=True)split_dataset = dataset['train'].train_test_split(test_size=0.2, seed=42)
train_dataset = split_dataset['train']
temp_split = split_dataset['test'].train_test_split(test_size=0.5, seed=42)
test_dataset = temp_split['test']
eval_dataset = temp_split['train']# 修改:只有 rank0 进程打印信息
if rank == 0:print("Find GPUs:", torch.cuda.device_count(), [torch.cuda.get_device_name(i) for i in range(torch.cuda.device_count())]) # 列出设备print("[rank0] Train size:", len(train_dataset))print("[rank0] Test size:", len(test_dataset))print("[rank0] Eval size:", len(eval_dataset))output_dir = './output-deepspeed'peft_config = LoraConfig(r=8,lora_alpha=8,target_modules=['q_proj', 'v_proj'],lora_dropout=0.05,bias='none',task_type='CAUSAL_LM'
)# 修改:训练参数中加入 deepspeed 配置文件
training_arguments = TrainingArguments(output_dir=output_dir,per_device_train_batch_size=16,optim='adamw_torch',learning_rate=10e-4,eval_steps=100,logging_steps=200,eval_strategy='steps',group_by_length=False,max_steps=200,# num_train_epochs=1,gradient_accumulation_steps=1,gradient_checkpointing=True,max_grad_norm=0.3,bf16=True,lr_scheduler_type='cosine',warmup_steps=100,deepspeed="./ds_config.json" # 加入 deepspeed 配置文件
)model_path = './llama-2-7b-hf'
model = AutoModelForCausalLM.from_pretrained(model_path,torch_dtype=torch.float16
)model.enable_input_require_grads()
model = get_peft_model(model, peft_config)
model.print_trainable_parameters()
model.config.use_cache = Falsetokenizer = AutoTokenizer.from_pretrained(model_path, trust_remote_code=True)
tokenizer.pad_token_id = 0
tokenizer.padding_side = 'right'trainer = SFTTrainer(model=model,train_dataset=train_dataset,eval_dataset=eval_dataset,peft_config=peft_config,tokenizer=tokenizer,args=training_arguments,max_seq_length=512,dataset_text_field='text'
)# 修改:只有 rank0 进程打印信息
if rank == 0:print("start training")start_time = time.time()trainer.train()if rank == 0:end_time = time.time()print("finished training")print("time_used:", end_time-start_time, "s")trainer.model.save_pretrained(output_dir)
(3)编写脚本进行训练,然后合并权重文件(步骤同2.2节)
其中,deepspeed_train.sh :
#!/bin/bash#SBATCH --nodes=1 # 节点数
#SBATCH --ntasks=4 # 任务数
#SBATCH --partition=ai # 分区名称(根据集群修改)module load CUDA/12.2deepspeed --num_nodes=1 --num_gpus=4 deepspeed_train.py
(4)训练时间和精度对比
单卡训练:

使用deepspeed分布式四卡训练:

可以看出训练效率有明显提升,但由于通信、等待的一些问题,加速比远远达不到4倍。
相关文章:
Llama模型分布式训练(微调)
1 常见大模型 1.1 参数量对照表 模型参数量发布时间训练的显存需求VGG-19143.68M2014~5 GB(单 224x224 图像,batch_size32)ResNet-15260.19M2015~7 GB(单 224x224 图像,batch_size32)GPT-2 117M117M2019~…...
Matlab模块From Workspace使用数据类型说明
Matlab原文连接:Load Data Using the From Workspace Block 模型: 从信号来源的数据: timeseries 数据: sampleTime 0.01; numSteps 1001;time sampleTime*[0:(numSteps-1)]; time time;data sin(2*pi/3*time);simin time…...
LangChain学习笔记(一)-LangChain简介
LangChain学习笔记(一)-LangChain简介 langChain是一个人工智能大语言模型的开发框架,主要构成为下图。 一、核心模块 (一)模型I/O模块 负责与现有大模型进行交互,由三部分组成: 提…...
k8s,声明式API对象理解
命令式API 比如: 先kubectl create,再replace的操作,我们称为命令式配置文件操作 kubectl replace的执行过程,是使用新的YAML文件中的API对象,替换原有的API对象;而kubectl apply,则是执行了一…...
KubeBlocks v0.9.2发布啦!支持容器镜像滚动更新、MySQL支持Jemalloc...快来升级体验更多新功能!
KubeBlocks v0.9.2 正式发布啦!本次发布包含了一些新功能、关键的错误修复以及各种改进。以下是详细的更新内容。 升级文档 v0.9.2 升级方式与 v0.9.1 相同,替换版本即可哦~ https://kubeblocks.io/docs/release-0.9/user_docs/upgrade/up…...
Linux-虚拟环境
文章目录 一. 虚拟机二. 虚拟化软件三. VMware WorkStation四. 安装CentOS操作系统五. 在VMware中导入CentOS虚拟机六. 远程连接Linux系统1. Finalshell安装2. 虚拟机网络配置3. 连接到Linux系统 七. 虚拟机快照 一. 虚拟机 借助虚拟化技术,我们可以在系统中&#…...
window系统下的git怎么在黑窗口配置代理
在Windows系统下,通过黑窗口(命令行界面)配置Git代理主要有两种方式:配置HTTP代理和配置SOCKS5代理。以下是具体的步骤: 配置HTTP代理 临时代理设置(仅对当前命令行会话有效): set …...
网络和通信详解
一、Java 网络编程基础 IP 地址和端口号 IP 地址: IP 地址是互联网协议地址,用于标识网络中的设备。在 Java 中,InetAddress类是用于表示 IP 地址的主要类。例如,InetAddress.getByName("www.example.com")可以获取指定…...
网络安全框架及模型-PPDR模型
网络安全框架及模型-PPDR模型 概述: 为了有效应对不断变化的网络安全环境,人们意识到需要一种综合性的方法来管理和保护网络安全。因此,PPDR模型应运而生。它将策略、防护、检测和响应四个要素结合起来,提供了一个全面的框架来处理网络安全问题。 工作原理: PPDR模型的…...
WPF+LibVLC开发播放器-LibVLC播放控制
接上一篇: LibVLC在C#中的使用 实现LibVLC播放器播放控制 界面 界面上添加一个Button按钮用于控制播放 <ButtonGrid.Row"1"Width"88"Height"24"Margin"10,0,0,0"HorizontalAlignment"Left"VerticalAlignme…...
子模块、Fork、NPM 包与脚手架概述
子模块 在 Git 仓库中嵌套另一个仓库,通过引用的方式引入到主项目,版本管理依赖 Git 提交记录或分支,更新需手动拉取并提交,适用于共享代码并保持项目独立性。 优点:子模块支持直接查看和修改,保持子模块…...
基于Java Springboot蛋糕订购小程序
一、作品包含 源码数据库设计文档万字PPT全套环境和工具资源部署教程 二、项目技术 前端技术:Html、Css、Js、Vue、Element-ui 数据库:MySQL 后端技术:Java、Spring Boot、MyBatis 三、运行环境 开发工具:IDEA/eclipse 微信…...
【el-table】表格后端排序
在需要排序的列添加属性 sortable,后端排序,需将sortable设置为custom 如果需要自定义轮转添加 sort-orders 属性,数组中的元素需为以下三者之一:ascending 表示升序,descending 表示降序,null 表示还原为原…...
APP聊天项目介绍
项目结构说明 res/layout目录:存放布局相关的 XML 文件,用于定义界面的外观,包含activity_main.xml(主界面布局)和message_item.xml(聊天消息项布局)。 res/drawable目录:存放一些…...
android user版本默认usb模式为充电模式
android插入usb时会切换至默认设置的模式,debug版本为adb,user版本为mtp protected long getChargingFunctions() {// if ADB is enabled, reset functions to ADB// else enable MTP as usual.if (isAdbEnabled()) {return UsbManager.FUNCTION_ADB;} e…...
常见问题QA的前端代码
这个的后端代码参见此文 使用语言向量建立常见问题的模糊搜索-CSDN博客https://blog.csdn.net/chenchihwen/article/details/144207262?spm1001.2014.3001.5501 这段代码实现了一个简单的问答页面,页面分为左右两部分,左侧用于展示对话记录,…...
float globalMapVIsualizationLeafSize; 的中文意思是什么
1.在visual studio 中新建文件 没有包含#include <string>头文件,也可以使用 str2.append(", C");吗? 在 Visual Studio 或任何其他 C 开发环境中,即使新建的文件中没有显式包含 #include <string> 头文件,…...
基于Java Springboot诗词学习APP且微信小程序
一、作品包含 源码数据库设计文档万字PPT全套环境和工具资源部署教程 二、项目技术 前端技术:Html、Css、Js、Vue、Element-ui 数据库:MySQL 后端技术:Java、Spring Boot、MyBatis 三、运行环境 开发工具:IDEA/eclipse微信开…...
CSS学习记录02
CSS颜色 指定颜色是通过使用预定义的颜色名称,或RGB,HEX,HSL,RGBA,HSLA值。 CSS颜色名 在CSS中,可以使用颜色名称来指定颜色: CSS背景色 您可以为HTML元素设置背景色: <h1 s…...
6.1 innoDb逻辑存储结构和架构-简介
InnoDB 是 MySQL 默认的存储引擎,以其强大的事务支持、崩溃恢复能力和高效的数据处理能力广受欢迎。本文从逻辑存储结构、内存架构、磁盘结构到后台线程,逐步剖析 InnoDB 的关键概念,帮助您更好地理解和应用。 1. 逻辑存储结构 InnoDB 的数据…...
三维GIS开发cesium智慧地铁教程(5)Cesium相机控制
一、环境搭建 <script src"../cesium1.99/Build/Cesium/Cesium.js"></script> <link rel"stylesheet" href"../cesium1.99/Build/Cesium/Widgets/widgets.css"> 关键配置点: 路径验证:确保相对路径.…...
Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)
文章目录 1.什么是Redis?2.为什么要使用redis作为mysql的缓存?3.什么是缓存雪崩、缓存穿透、缓存击穿?3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...
BCS 2025|百度副总裁陈洋:智能体在安全领域的应用实践
6月5日,2025全球数字经济大会数字安全主论坛暨北京网络安全大会在国家会议中心隆重开幕。百度副总裁陈洋受邀出席,并作《智能体在安全领域的应用实践》主题演讲,分享了在智能体在安全领域的突破性实践。他指出,百度通过将安全能力…...
成都鼎讯硬核科技!雷达目标与干扰模拟器,以卓越性能制胜电磁频谱战
在现代战争中,电磁频谱已成为继陆、海、空、天之后的 “第五维战场”,雷达作为电磁频谱领域的关键装备,其干扰与抗干扰能力的较量,直接影响着战争的胜负走向。由成都鼎讯科技匠心打造的雷达目标与干扰模拟器,凭借数字射…...
精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南
精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南 在数字化营销时代,邮件列表效度、用户参与度和网站性能等指标往往决定着创业公司的增长成败。今天,我们将深入解析邮件打开率、网站可用性、页面参与时…...
项目部署到Linux上时遇到的错误(Redis,MySQL,无法正确连接,地址占用问题)
Redis无法正确连接 在运行jar包时出现了这样的错误 查询得知问题核心在于Redis连接失败,具体原因是客户端发送了密码认证请求,但Redis服务器未设置密码 1.为Redis设置密码(匹配客户端配置) 步骤: 1).修…...
Pinocchio 库详解及其在足式机器人上的应用
Pinocchio 库详解及其在足式机器人上的应用 Pinocchio (Pinocchio is not only a nose) 是一个开源的 C 库,专门用于快速计算机器人模型的正向运动学、逆向运动学、雅可比矩阵、动力学和动力学导数。它主要关注效率和准确性,并提供了一个通用的框架&…...
推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材)
推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材) 这个项目能干嘛? 使用 gemini 2.0 的 api 和 google 其他的 api 来做衍生处理 简化和优化了文生图和图生图的行为(我的最主要) 并且有一些目标检测和切割(我用不到) 视频和 imagefx 因为没 a…...
【JVM面试篇】高频八股汇总——类加载和类加载器
目录 1. 讲一下类加载过程? 2. Java创建对象的过程? 3. 对象的生命周期? 4. 类加载器有哪些? 5. 双亲委派模型的作用(好处)? 6. 讲一下类的加载和双亲委派原则? 7. 双亲委派模…...
Selenium常用函数介绍
目录 一,元素定位 1.1 cssSeector 1.2 xpath 二,操作测试对象 三,窗口 3.1 案例 3.2 窗口切换 3.3 窗口大小 3.4 屏幕截图 3.5 关闭窗口 四,弹窗 五,等待 六,导航 七,文件上传 …...
