Qwen2.5-7B大模型微调记录

Qwen2.5-7B大模型微调记录

研究需要,需要搞一个大模型出来,没有太多的时间自己训练,准备用现成的开源大模型,然后结合研究方向进行微调

前前后后折腾大半个月,总算做完了第一个微调的大模型,模型基于阿里的千问2.5大模型,然后微调的训练集是一些法律相关的问题

记录一下流程

一、硬件设备

特意找联想配了个工作站(联想thinkstation P920),基础配置如下:

  • CPU,英特尔至强金牌系列5218
  • GPU,英伟达RTX4090,显存24G
  • 内存128G

二、软件环境

1、python编译环境

python版本为3.12.7,直接用anaconda安装的

编译器使用的是pycharm2024.3专业版,试用版

2、cuda环境

在这里插入图片描述

个人的操作系统是win10,

安装的cuda toolkit版本为12.1,cudnn版本为8.9.6.50

安装cuda toolkit时记住安装目录,然后将cudnn安装压缩文件中解压得到的几个文件夹拷贝至cuda安装目录下

在这里插入图片描述

3、第三方python依赖包

pip3 install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu121
pip install modelscope==1.20.0
pip install transformers==4.46.2
pip install accelerate==1.1.1
pip install peft==0.13.2
pip install datasets==3.1.0
pip install swanlab==0.3.25

三、模型及数据下载

1、千问2.5-7B模型下载

模型从hugging-face镜像站下载

Qwen2.5-7B-Instruct地址

我选择从git上拉远程仓库,拉取流程如下:

git lfs install
git clone https://hf-mirror.com/Qwen/Qwen2.5-7B-Instruct

总共28G左右,其中git目录占了一半,我大概拉了大半天,和本地网速相关

下载完之后,把git目录删掉,可以节省一些空间

2、微调训练数据集下载

使用 DISC-Law-SFT 数据集,主要是中文法律相关的问答,内容如下:

在这里插入图片描述

这个json格式的文件并不满足qwen大模型训练集的格式,需要把它处理成如下格式:

{"instruction": "你是一个法律专家,请根据用户的问题给出专业的回答","input": "诈骗罪量刑标准是什么?","output": "诈骗罪指的是以非法占有为目的,使用欺骗方法,骗取数额较大的公私财物的行为..."
}

处理代码如下:

import json# 定义固定的instruction
INSTRUCTION = "你是一个法律专家,请根据用户的问题给出专业的回答"def process_jsonl(input_file, output_file):with open(input_file, 'r', encoding='utf-8') as infile, open(output_file, 'w', encoding='utf-8') as outfile:for line in infile:# 读取每一行并解析JSONdata = json.loads(line)# 创建新的字典,包含instruction, input和outputnew_data = {"instruction": INSTRUCTION,"input": data["input"],"output": data["output"]}# 将新的字典写入输出文件json.dump(new_data, outfile, ensure_ascii=False)outfile.write('\n')# 使用示例
input_file = "DISC-Law-SFT-Pair-QA-released.jsonl"
output_file = "DISC-Law-SFT-Pair-QA-released-new.jsonl"process_jsonl(input_file, output_file)
print(f"处理完成。输出文件:{output_file}")

四、模型微调

进入重点

1、集成SwanLab

SwanLab是一个云上的AI实验平台,一站式跟踪、比较、分享你的模型,一站式AI实验协作,跟踪超参数和指标,监控GPU与硬件情况。

实际上就是在云端监控模型,它和transformers已经进行了集成,在transformers.Trainer的回调中添加SwanLabCallback实例即可,然后会在云端记录训练过程,具体实现如下:

trainer = Trainer(model=peft_model,args=args,train_dataset=train_dataset,data_collator=DataCollatorForSeq2Seq(tokenizer=tokenizer, padding=True),callbacks=[swanlab_callback],
)

swanlab_callback即SwanLabCallback实例

在训练开始之前,控制台会让你输入SwanLab的API key,需要去SwanLab官网注册

2、微调

按以下步骤开始微调:

  1. 加载Qwen2___5-7B-Instruct大模型
  2. 加载模型权重
  3. 加载处理好的微调训练集DISC-Law-SFT-Pair-QA-released-new.jsonl
  4. 配置Lora
  5. 开启梯度检查点,并设置微调的参数requires_grad = True
  6. 启用SwanLab记录模型训练过程
  7. 训练1个epoch

模型训练代码如下:

import json
import pandas as pd
import torch
from datasets import Dataset
from modelscope import snapshot_download, AutoTokenizer
from swanlab.integration.transformers import SwanLabCallback
from peft import LoraConfig, TaskType, get_peft_model
from transformers import (AutoModelForCausalLM,TrainingArguments,Trainer,DataCollatorForSeq2Seq,
)
import swanlabdef process_func(example):"""将数据集进行预处理"""MAX_LENGTH = 384input_ids, attention_mask, labels = [], [], []instruction = tokenizer(f"<|im_start|>system\n{example['instruction']}<|im_end|>\n<|im_start|>user\n{example['input']}<|im_end|>\n<|im_start|>assistant\n",add_special_tokens=False,)response = tokenizer(f"{example['output']}", add_special_tokens=False)input_ids = (instruction["input_ids"] + response["input_ids"] + [tokenizer.pad_token_id])attention_mask = instruction["attention_mask"] + response["attention_mask"] + [1]labels = ([-100] * len(instruction["input_ids"])+ response["input_ids"]+ [tokenizer.pad_token_id])if len(input_ids) > MAX_LENGTH:  # 做一个截断input_ids = input_ids[:MAX_LENGTH]attention_mask = attention_mask[:MAX_LENGTH]labels = labels[:MAX_LENGTH]return {"input_ids": input_ids, "attention_mask": attention_mask, "labels": labels}def predict(messages, model, tokenizer):device = "cuda"text = tokenizer.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)model_inputs = tokenizer([text], return_tensors="pt").to(device)generated_ids = model.generate(model_inputs.input_ids, max_new_tokens=512)generated_ids = [output_ids[len(input_ids):]for input_ids, output_ids in zip(model_inputs.input_ids, generated_ids)]response = tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0]return response# 在modelscope上下载Qwen模型到本地目录下
# model_dir = snapshot_download("Qwen/Qwen2.5-Coder-7B-Instruct", cache_dir="/root/autodl-tmp", revision="master")# Transformers加载模型权重
tokenizer = AutoTokenizer.from_pretrained("Qwen2___5-7B-Instruct", use_fast=False, trust_remote_code=True)
model = AutoModelForCausalLM.from_pretrained("Qwen2___5-7B-Instruct", device_map="auto",torch_dtype=torch.bfloat16)
model.enable_input_require_grads()  # 开启梯度检查点时,要执行该方法
for param in model.parameters():param.requires_grad = True# 处理数据集
train_jsonl_path = "DISC-Law-SFT-Pair-QA-released-new.jsonl"
train_df = pd.read_json(train_jsonl_path, lines=True)[5:5000]
train_ds = Dataset.from_pandas(train_df)
train_dataset = train_ds.map(process_func, remove_columns=train_ds.column_names)
test_df = pd.read_json(train_jsonl_path, lines=True)[:5]config = LoraConfig(task_type=TaskType.CAUSAL_LM,target_modules=["q_proj","k_proj","v_proj","o_proj","gate_proj","up_proj","down_proj",],inference_mode=False,  # 训练模式r=64,  # Lora 秩lora_alpha=16,  # Lora alaph,具体作用参见 Lora 原理lora_dropout=0.1,  # Dropout 比例
)peft_model = get_peft_model(model, config)args = TrainingArguments(output_dir="./output/Qwen2.5-Coder-7b",per_device_train_batch_size=2,gradient_accumulation_steps=8,logging_steps=10,num_train_epochs=1,save_steps=100,learning_rate=1e-4,save_on_each_node=True,gradient_checkpointing=True,report_to="none",
)class RewriteSwanLabCallback(SwanLabCallback):def on_train_begin(self, args, state, control, model=None, **kwargs):if not self._initialized:self.setup(args, state, model, **kwargs)print("训练开始")print("未开始微调,先取3条主观评测:")test_text_list = []for index, row in test_df[:3].iterrows():instruction = row["instruction"]input_value = row["input"]messages = [{"role": "system", "content": f"{instruction}"},{"role": "user", "content": f"{input_value}"},]response = predict(messages, peft_model, tokenizer)messages.append({"role": "assistant", "content": f"{response}"})result_text = f"【Q】{messages[1]['content']}\n【LLM】{messages[2]['content']}\n"print(result_text)test_text_list.append(swanlab.Text(result_text, caption=response))swanlab.log({"Prediction": test_text_list}, step=0)def on_epoch_end(self, args, state, control, **kwargs):# ===================测试阶段======================test_text_list = []for index, row in test_df.iterrows():instruction = row["instruction"]input_value = row["input"]ground_truth = row["output"]messages = [{"role": "system", "content": f"{instruction}"},{"role": "user", "content": f"{input_value}"},]response = predict(messages, peft_model, tokenizer)messages.append({"role": "assistant", "content": f"{response}"})if index == 0:print("epoch", round(state.epoch), "主观评测:")result_text = f"【Q】{messages[1]['content']}\n【LLM】{messages[2]['content']}\n【GT】 {ground_truth}"print(result_text)test_text_list.append(swanlab.Text(result_text, caption=response))swanlab.log({"Prediction": test_text_list}, step=round(state.epoch))swanlab_callback = RewriteSwanLabCallback(project="Qwen2.5-LoRA-Law",experiment_name="7b",config={# "model": "https://modelscope.cn/models/Qwen/Qwen2.5-7B-Instruct",# "dataset": "https://huggingface.co/datasets/ShengbinYue/DISC-Law-SFT",# "github": "https://github.com/datawhalechina/self-llm","system_prompt": "你是一个法律专家,请根据用户的问题给出专业的回答","lora_rank": 64,"lora_alpha": 16,"lora_dropout": 0.1,},
)trainer = Trainer(model=peft_model,args=args,train_dataset=train_dataset,data_collator=DataCollatorForSeq2Seq(tokenizer=tokenizer, padding=True),callbacks=[swanlab_callback],
)trainer.train()

其中RewriteSwanLabCallback是重写的SwanLabCallback类

运行程序开始输入SwanLab的api key后,就进入正式训练过程,控制台训练如下:

在这里插入图片描述

大概经过20来分钟的训练,训练结束

SwanLab中记录的信息如下:

  1. 训练环境

在这里插入图片描述

在这里插入图片描述

  1. 日志
swanlab: Tracking run with swanlab version 0.3.25
swanlab: Run data will be saved locally in D:\python\test\swanlog\run-20241122_090504-a3b1799d
swanlab: 👋 Hi huanggang, welcome to swanlab!
swanlab: Syncing run 7b to the cloud
swanlab: 🌟 Run `swanlab watch D:\python\test\swanlog` to view SwanLab Experiment Dashboard locally
swanlab: 🏠 View project at https://swanlab.cn/@huanggang/Qwen2.5-LoRA-Law
swanlab: 🚀 View run at https://swanlab.cn/@huanggang/Qwen2.5-LoRA-Law/runs/iazecr183ybpg7frii6sk
<IPython.core.display.HTML object>
训练开始
未开始微调,先取3条主观评测:
【Q】违章停车与违法停车是否有区别?
【LLM】违章停车与违法停车在某些情况下可以视为同一概念,但也有细微的区别。具体来说:1. 从法律层面来看,“违法停车”是法律术语,是指机动车违反《中华人民共和国道路交通安全法》等法律法规关于道路通行的规定,随意停放的行为��2. 在实际操作中,交警部门通常使用“违法停车”来指代违
【Q】人民法院执行实际施工人对发包人的到期债权的,转包人或者违法分包人是否有权提异议?
【LLM】根据《最高人民法院关于审理建设工程施工合同纠纷案件适用法律问题的解释(一)》第三十二条的规定,在执行程序中,实际施工人依据《最��
【Q】诈骗罪量刑标准是什么?
【LLM】诈骗罪的量刑标准如下:1. 诈骗公私财物价值三千元至一万元以上、三万元至十万元以上、五十万元以上的,应当分别认定为刑法第二百六十六条规定的“数额较大”、“数额��2. 诈骗公私财物达到上述规定的数额标准,具有下列情形之一的,可以依照刑法第二百六十六条的规定酌情从严惩处:(一)通过发送短信、拨打电话或者利用互联网、广播电视、报
{'loss': 1.2572, 'grad_norm': 0.08469390869140625, 'learning_rate': 9.67948717948718e-05, 'epoch': 0.03}
{'loss': 1.2308, 'grad_norm': 0.0997992530465126, 'learning_rate': 9.35897435897436e-05, 'epoch': 0.06}
{'loss': 1.2639, 'grad_norm': 0.08235415071249008, 'learning_rate': 9.038461538461538e-05, 'epoch': 0.1}
{'loss': 1.2288, 'grad_norm': 0.0755847841501236, 'learning_rate': 8.717948717948718e-05, 'epoch': 0.13}
{'loss': 1.1631, 'grad_norm': 0.08808039873838425, 'learning_rate': 8.397435897435898e-05, 'epoch': 0.16}
{'loss': 1.1797, 'grad_norm': 0.1106221154332161, 'learning_rate': 8.076923076923078e-05, 'epoch': 0.19}
{'loss': 1.122, 'grad_norm': 0.0844917893409729, 'learning_rate': 7.756410256410257e-05, 'epoch': 0.22}
{'loss': 1.3052, 'grad_norm': 0.08663339167833328, 'learning_rate': 7.435897435897436e-05, 'epoch': 0.26}
{'loss': 1.248, 'grad_norm': 0.09729356318712234, 'learning_rate': 7.115384615384616e-05, 'epoch': 0.29}
{'loss': 1.1938, 'grad_norm': 0.09329406917095184, 'learning_rate': 6.794871794871795e-05, 'epoch': 0.32}
{'loss': 1.1853, 'grad_norm': 0.09835438430309296, 'learning_rate': 6.474358974358975e-05, 'epoch': 0.35}
{'loss': 1.1068, 'grad_norm': 0.09713883697986603, 'learning_rate': 6.153846153846155e-05, 'epoch': 0.38}
{'loss': 1.0862, 'grad_norm': 0.08877339214086533, 'learning_rate': 5.833333333333334e-05, 'epoch': 0.42}
{'loss': 1.1636, 'grad_norm': 0.10562986135482788, 'learning_rate': 5.512820512820514e-05, 'epoch': 0.45}
{'loss': 1.1875, 'grad_norm': 0.09118109941482544, 'learning_rate': 5.192307692307693e-05, 'epoch': 0.48}
{'loss': 1.1602, 'grad_norm': 0.08926469832658768, 'learning_rate': 4.871794871794872e-05, 'epoch': 0.51}
{'loss': 1.2864, 'grad_norm': 0.11161018162965775, 'learning_rate': 4.5512820512820516e-05, 'epoch': 0.54}
{'loss': 1.1301, 'grad_norm': 0.08431420475244522, 'learning_rate': 4.230769230769231e-05, 'epoch': 0.58}
{'loss': 1.1538, 'grad_norm': 0.10437046736478806, 'learning_rate': 3.9102564102564105e-05, 'epoch': 0.61}
{'loss': 1.1516, 'grad_norm': 0.10058578848838806, 'learning_rate': 3.58974358974359e-05, 'epoch': 0.64}
{'loss': 1.113, 'grad_norm': 0.11428198963403702, 'learning_rate': 3.269230769230769e-05, 'epoch': 0.67}
{'loss': 1.1714, 'grad_norm': 0.08926127105951309, 'learning_rate': 2.948717948717949e-05, 'epoch': 0.7}
{'loss': 1.1466, 'grad_norm': 0.10032324492931366, 'learning_rate': 2.6282051282051285e-05, 'epoch': 0.74}
{'loss': 1.2202, 'grad_norm': 0.08911648392677307, 'learning_rate': 2.307692307692308e-05, 'epoch': 0.77}
{'loss': 1.092, 'grad_norm': 0.12006554007530212, 'learning_rate': 1.987179487179487e-05, 'epoch': 0.8}
{'loss': 1.2104, 'grad_norm': 0.1142987385392189, 'learning_rate': 1.6666666666666667e-05, 'epoch': 0.83}
{'loss': 1.1644, 'grad_norm': 0.09815921634435654, 'learning_rate': 1.3461538461538462e-05, 'epoch': 0.86}
{'loss': 1.1737, 'grad_norm': 0.11947522312402725, 'learning_rate': 1.0256410256410256e-05, 'epoch': 0.9}
{'loss': 1.1912, 'grad_norm': 0.10772272199392319, 'learning_rate': 7.051282051282052e-06, 'epoch': 0.93}
{'loss': 1.2978, 'grad_norm': 0.09548761695623398, 'learning_rate': 3.846153846153847e-06, 'epoch': 0.96}
{'loss': 1.1699, 'grad_norm': 0.10331740230321884, 'learning_rate': 6.41025641025641e-07, 'epoch': 0.99}
epoch 1 主观评测:
【Q】违章停车与违法停车是否有区别?
【LLM】违章停车和违法停车都是违反了道路交通安全法,但二者是有区别的。违法停车是指机动车违反道路交通安全法律法规关于道路通行条件的规定��
【Q】人民法院执行实际施工人对发包人的到期债权的,转包人或者违法分包人是否有权提异议?
【LLM】人民法院在审理民事案件中,根据当事人的申请,可以对被告所有的财产采取保全措施。保全的范围限于请求的范围,或者与本案有关的财物。��
【Q】诈骗罪量刑标准是什么?
【LLM】1、诈骗公私财物,数额较大的,处三年以下有期徒刑、拘役或者管制,并处或者单处罚金;数额巨大或者有其他严重情节的,处三年以上十年以下
2、法律依据:《中华人民共和国刑法》第二百六十六条 诈骗公私财物,数额较大的,处三年以下有期徒刑、拘役或者管制,并处
【Q】被管制罪犯的义务是什么?
【LLM】1、遵守法律、行政法规,服从监督;2、未经执行机关批准,不得行使言论、出版、集会、结社、游行、示威自由的权利;3、按照执行机关规定��
【GT】 被管制罪犯的义务为:1、遵守执行机关关于会客的规定;2、离开所居住的市、县或者迁居,应当报经执行机关批准。3、
【Q】管制的后果有哪些?
【LLM】1、被判处管制的犯罪分子,可以根据犯罪情况,在执行期间同时禁止进入特定区域、场所,接触特定的人。2、被判处管制的犯罪分子,依法实行
{'train_runtime': 1361.4247, 'train_samples_per_second': 3.669, 'train_steps_per_second': 0.229, 'train_loss': 1.1852481304070888, 'epoch': 1.0}
  1. 图表记录

在这里插入图片描述

3、输出结果

输出结果在根目录output文件夹下,结构如下:

在这里插入图片描述

因为设置了梯度检查点,所以记录了4个点的训练结果

五、训练完成的模型调用

直接上代码吧

from transformers import AutoModelForCausalLM, AutoTokenizer
from peft import PeftModel, LoraConfig, TaskType
import torch# 加载微调后的模型
model = AutoModelForCausalLM.from_pretrained("./output/Qwen2.5-Coder-7b/checkpoint-312")# LoRA 配置
config = LoraConfig(task_type=TaskType.CAUSAL_LM,r=64,lora_alpha=16,lora_dropout=0.1,
)# 加载 LoRA 微调模型
peft_model = PeftModel(model, config)# 加载分词器
tokenizer = AutoTokenizer.from_pretrained("./output/Qwen2.5-Coder-7b/checkpoint-312", use_fast=False)# 设置设备
device = "cuda" if torch.cuda.is_available() else "cpu"
peft_model.to(device)# 定义预测函数
def predict(messages, model, tokenizer):# 将对话消息转化为输入格式text = ""for msg in messages:text += f"&lt;|im_start|&gt;{msg['role']}\n{msg['content']}&lt;|im_end|&gt;\n"# 模型生成输入inputs = tokenizer([text], return_tensors="pt").to(device)# 使用生成方法生成回答outputs = model.generate(inputs["input_ids"],max_new_tokens=512,temperature=0.7,top_k=50,top_p=0.9,)# 解码模型输出response = tokenizer.decode(outputs[0], skip_special_tokens=True)return response# 定义对话消息
messages = [{"role": "system", "content": "你是一个法律专家。"},{"role": "user", "content": "什么是合同法?"},
]# 调用预测函数
response = predict(messages, peft_model, tokenizer)
print(response)

如果直接运行上面的代码,会报错,说是找不到config.json文件,我从原始qwen模型文件夹下将这个config.json文件拷贝到checkpoint-312文件夹下,又报错找不到分词器,所以我的做法是将Qwen2___5-7B-Instruct文件夹下和分词配置相关的文件都拷贝到checkpoint-312文件夹下,主要是tokenize_config.json、vocab.json和mergs.txt这几个文件

补充好之后,程序正常运行,控制台结果如下:

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/887528.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

docker 的各种操作

Docker pull拉取镜像报错“Error response from daemon: Get "https://registry-1.docker.io/v2”解决办法&#xff1a; 解决方法&#xff1a;将 /etc/docker/daemon.json 中的"registry-mirrors"的内容换成如下内容 { "registry-mirrors": [ "…

动态规划之背包问题

0/1背包问题 1.二维数组解法 题目描述&#xff1a;有一个容量为m的背包&#xff0c;还有n个物品&#xff0c;他们的重量分别为w1、w2、w3.....wn&#xff0c;他们的价值分别为v1、v2、v3......vn。每个物品只能使用一次&#xff0c;求可以放进背包物品的最大价值。 输入样例…

蓝桥杯模拟题不知名题目

题目:p是一个质数&#xff0c;但p是n的约数。将p称为是n的质因数。求2024最大质因数。 #include<iostream> #include<algorithm> using namespace std; bool fun(int x) {for(int i 2 ; i * i < x ; i){if(x % i 0)return false;}return true; } int main() …

cocoscreater3.8.4生成图集并使用

1.安装texturepacker&#xff0c;去官网下载https://www.codeandweb.com/texturepacker 2.将图片拖动进来&#xff0c;即可自动生成精灵表&#xff0c;这里输出选用cocos2d-x&#xff0c;打包用免费版的“基本”就行&#xff0c;高级模式是收费的&#xff0c;然后点击“发布精…

解决SSL VPN客户端一直提示无法连接服务器的问题

近期服务器更新VPN后&#xff0c;我的win10电脑一致无法连接到VPN服务器&#xff0c; SSL VPN客户端总是提示无法连接到服务端。网上百度尝试了各种方法后&#xff0c;终于通过以下设置方式解决了问题&#xff1a; 1、首先&#xff0c;在控制面板中打开“网络和共享中心”窗口&…

从零开始学GeoServer源码(二)添加支持arcgis切片功能

文章目录 参考文章环境背景1、配置打包好的程序1.1、下载GeoServer的war包1.2、下载GeoWebCache1.3、拷贝jar包1.4、修改配置文件1.4.1、拷贝geowebcache-arcgiscache-context.xml1.4.2、修改geowebcache-core-context.xml1.4.3、修改geowebcache-servlet.xml 1.5、配置切片信息…

【Docker】Centos7 Jenkins 踩坑笔记

文章目录 1. docker pull 超时2. 初始化找不到 initialAdminPassword 1. docker pull 超时 docker pull 命令拉不下来 docker pull jenkins/jenkins:lts-jdk17 Error response from daemon: Get "https://registry-1.docker.io/v2/": 编辑docker配置 sudo mkdir -…

Java中的JSONObject详解

文章目录 Java中的JSONObject详解一、引言二、JSONObject的创建与基本操作1、创建JSONObject2、添加键值对3、获取值 三、JSONObject的高级特性1、遍历JSONObject2、从字符串创建JSONObject3、JSONObject与JSONArray的结合使用4、更新和删除键值对 四、错误处理1. 键值存在性检…

【大数据学习 | Spark-Core】Spark中的join原理

join是两个结果集之间的链接&#xff0c;需要进行数据的匹配。 演示一下join是否存在shuffle。 1. 如果两个rdd没有分区器&#xff0c;分区个数一致 &#xff0c;会发生shuffle。但分区数量不变。 scala> val arr Array(("zhangsan",300),("lisi",…

111.有效单词

class Solution {public boolean isValid(String word) {if(word.length()<3){return false;}int countV0,countC0;//分别统计原音和辅音for(int i0;i<word.length();i){if(Character.isLetterOrDigit(word.charAt(i))){if(word.charAt(i)a||word.charAt(i)e||word.charA…

安装python拓展库pyquery相关问题

我采用的是离线whl文件安装, 从官方库地址: https://pypi.org/, 下载whl文件, 然后在本地电脑上执行pip install whl路径文件名.whl 但是在运行时报错如下图 大体看了看, 先是说了说找到了合适的 lxml>2.1, 在我的python库路径中, 然后我去看了看我的lxml版本, 是4.8.0, 对…

如何启动多个libvirtd进程

导语:如何启动多个libvirtd,咋一想这不简单,多运行几个libvirtd不就完事,其实不然?为什么启动多个libvirtd,有何应用场景?当前libvirt代码架构是否支持启动多个libvirtd? 一、如何启动libvirtd # /usr/local/sbin/libvirtd --listen --listen 必须参数,监控tcp/ip c…

架构-微服务-服务网关

文章目录 前言一、网关介绍1. 什么是API网关2. 核心功能特性3. 解决方案 二、Gateway简介三、Gateway快速入门1. 基础版2. 增强版3. 简写版 四、Gateway核心架构1. 基本概念2. 执行流程 五、Gateway断言1. 内置路由断言工厂2. 自定义路由断言工厂 六、过滤器1. 基本概念2. 局部…

idea怎么打开两个窗口,运行两个项目

今天在开发项目的时候&#xff0c;前端希望运行一下以前的项目&#xff0c;于是就需要开两个 idea 窗口&#xff0c;运行两个项目 这里记录一下如何设置&#xff1a;首先依次点击&#xff1a; File -> Settings -> Appearance & Behavior ->System Settings 看到如…

零碎04 MybatisPlus自定义模版生成代码

目录 背景 动手开干 需要的依赖包&#xff0c;需要注意mybatis-plus-generator的3.5版本是没有兼容历史版本的。 定义一个CodeGenerator类&#xff0c;负责生成代码和配置属性 Entity模版 背景 MybatisPlus代码生成使用默认的velocity模版解决不了定制化的需求&#xff0…

CentOS8.5.2111(7)完整的Apache综合实验

一、实验目标 1.掌握Linux系统中Apache服务器的安装与配置&#xff1b; 2.掌握个人主页、虚拟目录、基于用户和主机的访问控制及虚拟主机的实现方法。 二、实验要求 练习使用linux系统下WEB服务器的配置方法。 三、实验背景 重庆工程学院为筹备“重庆工程大学”特申请了c…

Cocos编辑器

1、下载 下载地址&#xff1a;https://www.cocos.com/creator-download 2、编辑器界面介绍 官方链接&#xff1a;https://docs.cocos.com/creator/3.8/manual/zh/editor/ 3、项目结构 官方链接&#xff1a;https://docs.cocos.com/creator/3.8/manual/zh/getting-started/…

Easyui 实现订单拆分开票功能

Easyui 实现订单拆分开票功能 需求 1、实现一个订单开具多分发票功能&#xff1b; 2、支持拆行&#xff1b; 3、支持拆数量&#xff1b; 流程设计 1、操作页面展示订订单头信息&#xff0c;订单明细信息 2、点击新增发票按钮弹出一个弹出框用于创建一张拆分发票&#xff0c;弹…

解决 java -jar 报错:xxx.jar 中没有主清单属性

问题复现 在使用 java -jar xxx.jar 命令运行 Java 应用程序时&#xff0c;遇到了以下错误&#xff1a; xxx.jar 中没有主清单属性这个错误表示 JAR 文件缺少必要的启动信息&#xff0c;Java 虚拟机无法找到应用程序的入口点。本文将介绍该错误的原因以及如何通过修改 pom.xm…

推荐一款龙迅HDMI2.0转LVDS芯片 LT6211UX LT6211UXC

龙迅的HDMI2.0转LVDS芯片LT6211UX和LT6211UXC是两款高性能的转换器芯片&#xff0c;它们在功能和应用上有所差异&#xff0c;同时也存在一些共同点。以下是对这两款芯片的详细比较和分析&#xff1a; 一、LT6211UX 主要特性&#xff1a; HDMI2.0至LVDS和MIPI转换器。HDMI2.0输…