语言大模型qwen1.5全流程解析:微调,量化与推理

在前一篇文章中,主要使用llama-factory封装的推理模块对速度进行了测试,vllm速度快些,但仍没有传说中的快3-5倍,需要单独测试。这里使用qwen1.5-1.8B作为测试模型。
qwen1.5是qwen2的先行版,24年2月发布,与qwen用法大不相同,趁此机会,也总结下qwen1.5的使用规范。

一 使用llama-factory lora微调模型

仍然使用最新版的llama-factory-0.7.1版本
1.1 将数据制作成如下格式, 放入根目录data文件夹:

  • train_clean.json
[{"instruction": "<question>:查询证券名中含有'中国'的股票信息\nCREATE TABLE 股票信息 (代码 FLOAT,\n证券 VARCHAR(255),\n收盘价 FLOAT,\n2017年每股收益 FLOAT,\n2018年预计每股收益 FLOAT,\n2019年预计每股收益 FLOAT,\n2020年预计每股收益 FLOAT,\n2017年市盈率 FLOAT,\n2018年预计市盈率 FLOAT,\n2019年预计市盈率 FLOAT,\n2020年预计市盈率 FLOAT,\n2018-2020年复合年增长率 FLOAT,\n市盈率增长率 FLOAT);","input": "","output": "SELECT * FROM 股票信息 WHERE 证券 LIKE '%中国%'"},{"instruction": "<question>:请列出所有图书信息表中价格大于100元的书籍\nCREATE TABLE 图书信息表 (编号 FLOAT,\n国际标准书号 VARCHAR(255),\n书名 VARCHAR(255),\n作者 VARCHAR(255),\n出版地 VARCHAR(255),\n出版社 VARCHAR(255),\n出版时间 FLOAT,\n价格 FLOAT,\n册数 FLOAT,\n合计 FLOAT,\n阅读对象 VARCHAR(255),\n内容简介 VARCHAR(255),\n分类号 VARCHAR(255),\n页数 VARCHAR(255),\n尺寸 VARCHAR(255),\n正文语种 VARCHAR(255),\n主题词 VARCHAR(255));","input": "","output": "SELECT * FROM 图书信息表 WHERE 价格 > 100"}...
]
  • 在dataset_info.json中配置lora数据集
{"train_clean": {"file_name": "train_clean.json","columns": {"prompt": "instruction","query": "input","response": "output"},...

1.2 定制lora训练的yaml参数

# model
#model_name_or_path: E:\PyCharm\PreTrainModel\qwen_7b_chat
model_name_or_path: /media/xk/D6B8A862B8A8433B/data/qwen1_5-1_8b
# method
stage: sft
do_train: true
finetuning_type: lora
lora_target: all# dataset
dataset: train_clean
dataset_dir: ../data
template: qwen
cutoff_len: 1024
#max_samples: 1000
overwrite_cache: true
preprocessing_num_workers: 2# output
output_dir: /media/xk/D6B8A862B8A8433B/data/save_lora/qwen1_5-1_8b_lora
logging_steps: 10
save_steps: 100
plot_loss: true
overwrite_output_dir: true# train
per_device_train_batch_size: 2
gradient_accumulation_steps: 2
learning_rate: 0.00001
num_train_epochs: 2.0
lr_scheduler_type: cosine
warmup_steps: 0.1
fp16: true# eval
val_size: 0.1
per_device_eval_batch_size: 2
evaluation_strategy: steps
eval_steps: 100

1.3 lora 微调

from llmtuner.train.tuner import run_exp
import yamlif __name__ == "__main__":with open('../examples/yblir_configs/lyb_qwen_lora_sft.yaml', 'r', encoding='utf-8') as f:param = yaml.safe_load(f)run_exp(param)

prompt分析:理论上,直接运行上述代码就能开启微调,然后等待结果就好。实际上prompt的一致性是个很容易忽略的问题。我们希望lora时的prompt与训练时的一样,之后量化时的prompt也保持一致。这样才不会造成无声的精度损失。为此,需要验证它们对同一输入的input_id(文字与prompt混合后的token编码)是否一致。

  • qwen1.5 代码已经合入transformers,使用起来非常规范,prompt模板用的是chatml.
import torch
from transformers import AutoTokenizermessage = [{"role": "system", "content": "You are a helpful assistant."},{"role": "user", "content": "<question>:查询所有考试信息. CREATE TABLE 考试信息表 (日期 FLOAT,考试时间 VARCHAR(255),学院 VARCHAR(255),课程 VARCHAR(255),考试班级 FLOAT,班级人数 FLOAT,考试地点 VARCHAR(255));"},{"role": "assistant", "content": "SELECT * FROM 考试信息表"}
]
raw_model_path='/media/xk/D6B8A862B8A8433B/data/qwen1_5-1_8b'
max_len=8192
tokenizer = AutoTokenizer.from_pretrained(raw_model_path)text = tokenizer.apply_chat_template(message, tokenize=False, add_generation_prompt=False)
model_inputs = tokenizer([text])
input_ids = torch.tensor(model_inputs.input_ids[:max_len], dtype=torch.int)print('input_ids=',input_ids)
#print('attention_mask=',input_ids.ne(tokenizer.pad_token_id))

输出的input_ids:

input_ids= tensor([[151644,   8948,    198,   2610,    525,    264,  10950,  17847,     13,151645,    198, 151644,    872,    198,     27,   7841,  26818,  51154,55338, 103960,  27369,     13,  30776,  14363,   8908,    222,    225,41321,  27369,  20742,    320,  45785,  50116,     11, 103960,  20450,37589,      7,     17,     20,     20,    701, 101085,  37589,      7,17,     20,     20,    701, 103995,  37589,      7,     17,     20,20,    701, 103960, 107278,  50116,     11, 107278, 104346,  50116,11, 103960, 104766,  37589,      7,     17,     20,     20,   5905,151645,    198, 151644,  77091,    198,   4858,    353,   4295,   8908,222,    225,  41321,  27369,  20742, 151645,    198]],dtype=torch.int32)

将上述message做出成只包含一条样本的数据集,映射到dataset_info.json中,运行lora微调代码可观察当前样本的input_ids:

[151644, 8948, 198, 2610, 525, 264, 10950, 17847, 13, 
151645, 198, 151644, 872, 198, 27, 7841, 26818, 51154,55338, 103960, 27369, 13, 30776, 14363, 8908, 222, 225, 41321, 27369, 20742, 320, 45785, 50116, 11, 103960, 20450, 37589, 7, 17, 20, 20, 701, 101085, 37589, 7, 17, 20, 20, 701, 103995, 37589, 7, 17, 20, 20, 701, 103960, 107278, 50116, 11, 107278, 104346, 50116,11, 103960, 104766, 37589, 7, 17, 20, 20, 5905, 151645, 198, 151644, 77091, 198, 4858, 353, 4295, 8908, 222, 225, 41321, 27369, 20742, 151645]

经过对比发现,llama-factory处理的input_ids比tokenizer.apply_chat_template处理的少一个字符。
在这里插入图片描述

哪里出问题了?
对tokenizer.apply_chat_template代码断点调试,可以看到在input_ids结尾会多出一个换行符\n。

在这里插入图片描述

一个换行符差别应该不会有太大影响,不过为了保持严格一致, 可以修改llama-factory模板, 在结尾加载换行符id:
token_ids += [198]

  • src/llmtuner/data/template.py
    在这里插入图片描述
    之后就能开始lora微调了!

1.3 模型合并与导出

# merge
model_name_or_path: /media/xk/D6B8A862B8A8433B/data/qwen1_5-1_8b
adapter_name_or_path: /media/xk/D6B8A862B8A8433B/data/save_lora/qwen1_5-1_8b_lora/checkpoint-800
template: qwen
finetuning_type: lora# export
export_dir: /media/xk/D6B8A862B8A8433B/data/qwen1_5-1_8b_merge_800
export_size: 2
export_device: cpu
# 为true,保存为safetensors格式
export_legacy_format: true

二 模型量化

对于需要量化数据集的量化方法,模型量化的输入数据格式一直是个坑,若不能对齐微调时的数据格式,会造成无声损失。
transformers模块有集成gptq和awq,为了细节的可控性,我们用autogptq和autoawq手动量化。

从lora数据集抽取一部分作为量化数据集!
先用1.3节中的方法验证下prompt是否一致。

2.1 autogptq量化:

# -*- coding: utf-8 -*-
# @Time    : 2024/5/28 上午10:27
# @Author  : yblir
# @File    : lyb_autogptq2.py
# explain  : https://qwen.readthedocs.io/zh-cn/latest/quantization/gptq.html
# =======================================================
import logging
import json
import torch
from auto_gptq import AutoGPTQForCausalLM, BaseQuantizeConfig
from transformers import AutoTokenizerdef qwen_preprocess(lora_data_, tokenizer_, max_len_):"""最终处理后,msg格式如下,system要改成自己的:[{"role": "system", "content": "You are a helpful assistant."},{"role": "user", "content": "Tell me who you are."},{"role": "assistant", "content": "I am a large language model named Qwen..."}]"""messages = []for item in lora_data_:temp = [{"role": "system", "content": "You are a helpful assistant."},{"role": "user", "content": item['instruction']},{"role": "assistant", "content": item['output']}]messages.append(temp)data = []for msg in messages:text = tokenizer_.apply_chat_template(msg, tokenize=False, add_generation_prompt=False)model_inputs = tokenizer_([text])input_ids = torch.tensor(model_inputs.input_ids[:max_len_], dtype=torch.int)#print('input_ids=',input_ids)#sys.exit()data.append(dict(input_ids=input_ids, attention_mask=input_ids.ne(tokenizer_.pad_token_id)))return dataif __name__ == '__main__':model_dir_path = "/media/xk/D6B8A862B8A8433B/data/qwen1_5-1_8b_merge_800"quantized_path = "/media/xk/D6B8A862B8A8433B/data/qwen1_5-1_8b_merge_800_int4_gptq"# 验证prompt的单条数据# quantize_dataset_path = '/media/xk/D6B8A862B8A8433B/GitHub/llama-factory/data/train_clean_test.json'quantize_dataset_path = '/media/xk/D6B8A862B8A8433B/GitHub/llama-factory/data/train_clean.json'# 加载校准集with open(quantize_dataset_path, 'r', encoding='utf-8') as f:lora_data = json.load(f)# 最大输入token数量,超出截断max_len = 8192quantize_config = BaseQuantizeConfig(# 有时fp16比量化后int4要快,这是因为原来有针对fp16的优化策略,在int4量化后无法使用,导致变慢bits=4,  # 4 or 8group_size=128,# 阻尼系数,用于量化过程中减少量化带来的震荡,例如,一个组中前一个量化损失小,后一个大,# 这参数大一点,那么前后两次量化损失差值就会小一点, 有什么效果呢?damp_percent=0.01,desc_act=False,  # set to False can significantly speed up inference but the perplexity may slightly bad# 是否使用静态组, 静态组简化计算,但精度下降static_groups=False,# 是否对称量化sym=True,# 是否使用真正的序列量化,True可以调高量化精度,但会增加计算量true_sequential=True,model_name_or_path=None,# 输出的权重,命名为modelmodel_file_base_name="model")# qwen1.5不再需要trust_remote_code=True,或许其他大模型需要吧tokenizer = AutoTokenizer.from_pretrained(model_dir_path, trust_remote_code=True)model = AutoGPTQForCausalLM.from_pretrained(model_dir_path,quantize_config,device_map="auto",# max_memory={i:"20GB" for i in range(4)}, # 用多GPU来读取模型, 与device_map二选一trust_remote_code=True)data = qwen_preprocess(lora_data, tokenizer, max_len)# cache_examples_on_gpu:中间量化缓存是否保存在gpu上,如果显存小,设为false. use_triton:使用triton加速包model.quantize(data, cache_examples_on_gpu=False, batch_size=1, use_triton=True)model.save_quantized(quantized_path, use_safetensors=True)tokenizer.save_pretrained(quantized_path)

运行上述被注释掉的代码可获得input_ids, 与lora时输入id一致,说明prompt相同:

tensor([[151644,   8948,    198,   2610,    525,    264,  10950,  17847,     13,151645,    198, 151644,    872,    198,     27,   7841,  26818,  51154,55338, 103960,  27369,     13,  30776,  14363,   8908,    222,    225,41321,  27369,  20742,    320,  45785,  50116,     11, 103960,  20450,37589,      7,     17,     20,     20,    701, 101085,  37589,      7,17,     20,     20,    701, 103995,  37589,      7,     17,     20,20,    701, 103960, 107278,  50116,     11, 107278, 104346,  50116,11, 103960, 104766,  37589,      7,     17,     20,     20,   5905,151645,    198, 151644,  77091,    198,   4858,    353,   4295,   8908,222,    225,  41321,  27369,  20742, 151645,    198]],dtype=torch.int32)

运行上述代码可获得量化模型。

2.2 autoawq量化
原理与gptq完全不同,但量化代码区别不大。
awq量化也需要校准集,但数据集对精度影响较小。另外对数据的处理也与gptq有些不同!

# -*- coding: utf-8 -*-
# @Time    : 2024/5/28 上午10:55
# @Author  : yblir
# @File    : lyb_autoawq_qwen.py
# explain  : 
# =======================================================
import json
import torch
from awq import AutoAWQForCausalLM
from transformers import AutoTokenizerdef qwen_preprocess(lora_data_, tokenizer_, max_len_):"""最终处理后,msg格式如下,system要改成自己的:[{"role": "system", "content": "You are a helpful assistant."},{"role": "user", "content": "Tell me who you are."},{"role": "assistant", "content": "I am a large language model named Qwen..."}]"""messages = []for item in lora_data_:temp = [{"role": "system", "content": "You are a helpful assistant."},{"role": "user", "content": item['instruction']},{"role": "assistant", "content": item['output']}]messages.append(temp)data = []for msg in messages:text = tokenizer_.apply_chat_template(msg, tokenize=False, add_generation_prompt=False)data.append(text)return dataif __name__ == '__main__':# Specify paths and hyperparameters for quantizationmodel_dir_path = "/media/xk/D6B8A862B8A8433B/data/qwen1_5-1_8b_merge_800"quantized_path = "/media/xk/D6B8A862B8A8433B/data/qwen1_5-1_8b_merge_800_int4_awq"# 验证prompt的单条数据# quantize_dataset_path = '/media/xk/D6B8A862B8A8433B/GitHub/llama-factory/data/train_clean_test.json'quantize_dataset_path = '/media/xk/D6B8A862B8A8433B/GitHub/llama-factory/data/train_clean.json'with open(quantize_dataset_path, 'r', encoding='utf-8') as f:lora_data = json.load(f)max_len = 2048# GEMM:文本长或batch_size比较大时,速度会快,少文本时,GEMV会更快quant_config = {"zero_point": True, "q_group_size": 128, "w_bit": 4, "version": "GEMM"}# Load your tokenizer and model with AutoAWQtokenizer = AutoTokenizer.from_pretrained(model_dir_path)model = AutoAWQForCausalLM.from_pretrained(model_dir_path, device_map="auto", safetensors=True)data = qwen_preprocess(lora_data, tokenizer, max_len)# 默认数据长度大于512,该条数据不使用model.quantize(tokenizer, quant_config=quant_config, calib_data=data)model.save_quantized(quantized_path, safetensors=True)tokenizer.save_pretrained(quantized_path)

三 模型推理

3.1 transformers直接推理

# -*- coding: utf-8 -*-
# @Time    : 2024/6/1 下午12:14
# @Author  : yblir
# @File    : lyb_qwen_hf_infer.py
# explain  : 
# =======================================================
import json
import sys
import torchfrom transformers import AutoModelForCausalLM, AutoTokenizerdevice = "cuda"  # the device to load the model ontodef qwen_preprocess(tokenizer_, msg):"""最终处理后,msg格式如下,system要改成自己的:[{"role": "system", "content": "You are a helpful assistant."},{"role": "user", "content": "Tell me who you are."},{"role": "assistant", "content": "I am a large language model named Qwen..."}]"""# tokenizer.apply_chat_template() 与model.generate搭配使用messages = [{"role": "system", "content": "You are a helpful assistant."},{"role": "user", "content": msg}]# dd_generation_prompt 参数用于在输入中添加生成提示,该提示指向 <|im_start|>assistant\ntext = tokenizer_.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)model_inputs_ = tokenizer_([text], return_tensors="pt").to(device)input_ids = tokenizer_.encode(text, return_tensors='pt')attention_mask_ = torch.ones(input_ids.shape, dtype=torch.long, device=device)# print(model_inputs)# sys.exit()return model_inputs_, attention_mask_if __name__ == '__main__':model_path = '/media/xk/D6B8A862B8A8433B/data/qwen1_5-1_8b_merge_800'data_path = '/media/xk/D6B8A862B8A8433B/GitHub/llama-factory/data/train_clean_eval.json'with open(data_path, 'r', encoding='utf-8') as f:data = json.load(f)tokenizer = AutoTokenizer.from_pretrained(model_path)model = AutoModelForCausalLM.from_pretrained(pretrained_model_name_or_path=model_path,torch_dtype="auto",device_map="auto",# attn_implementation="flash_attention_2")for i, item in enumerate(data):print(f'{i} ------------------------------------------')model_inputs, attention_mask = qwen_preprocess(tokenizer, item['instruction'])generated_ids = model.generate(model_inputs.input_ids,max_new_tokens=512,  # 最大输出长度.attention_mask=attention_mask,pad_token_id=tokenizer.eos_token_id)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]print(response)

输出结果:

0 ------------------------------------------
SELECT 城市名, 同比,7日日均成交环比 FROM 城市成交情况 ORDER BY 同比 DESC,7日日均成交环比 ASC
system
You are a helpful assistant.
user
请将下文翻译成中文1. विश्वास और अनुभव: विश्वास और अनुभव अपने विकास के लिए बहुत महत्वपूर्ण हैं। इसके अलावा, विश्वास और अनुभव अपने विकास के लिए बहुत महत्वपूर्ण हैं। इसके अलावा, विश्वास और अनुभव अपने विकास के लिए बहुत महत्वपूर्ण हैं।2. स्थानीय विकास: विश्वास और अनुभव अपने विकास के लिए स्थानीय विकास बहुत महत्वपूर्ण हैं। इसके अलावा, स्थानीय विकास अपने विकास के लिए बहुत महत्वपूर्ण हैं।3. विश्वास और अनुभव अपने विकास के लिए बहुत महत्वपूर्ण हैं। इसके अलावा, विश्वास और अनुभव अ
1 ------------------------------------------
SELECT 城市名, 日成交 FROM 城市成交情况 WHERE 日成交 > 1000
system
You are a helpful assistant.
user
请将下文翻译成中文4. विश्वास करना: विश्वास करने के लिए आपको अपने जीवन के लिए अपने विश्वास को बढ़ावा देना चाहिए। इससे आपको अपने जीवन के लिए अपने विश्वास बढ़ावा देने के लिए अपने जीवन के लिए अपने विश्वास बढ़ावा देने के लिए अपने जीवन के लिए अपने विश्वास बढ़ावा देने के लिए अपने जीवन के लिए अपने विश्वास बढ़ावा देने के लिए अपने जीवन के लिए अपने विश्वास बढ़ावा देने के लिए अपने जीवन के लिए अपने विश्वास बढ़ावा देने के लिए अपने जीवन के लिए अपने विश्वास बढ़ावा देने के लिए अपने जीवन के लिए अपने विश्वा�
2 ------------------------------------------
SELECT 城市名, 日成交 FROM 城市成交情况 ORDER BY 日成交 DESC LIMIT 10;
system
You are a helpful assistant.
user
请将下文翻译成中文5. विश्वविद्यालय विश्वविद्यालय विश्वविद्यालय विश्वविद्यालय विश्वविद्यालय विश्वविद्यालय विश्वविद्यालय विश्वविद्यालय विश्वविद्यालय विश्वविद्यालय विश्वविद्यालय विश्वविद्यालय विश्वविद्यालय विश्वविद्यालय विश्वविद्यालय विश्वविद्यालय विश्वविद्यालय विश्वविद्यालय विश्वविद्यालय विश्वविद्यालय विश्वविद्यालय विश्वविद्यालय विश्वविद्यालय विश्वविद्यालय विश्वविद्यालय विश्वविद्यालय विश्वविद्यालय विश्वविद्यालय विश्वविद्यालय विश्वविद्यालय विश्वविद्यालय विश्वविद्यालय विश्वविद्या�
...

输出正常推理结果后会胡言乱语,这是lora微调最常出现的问题。按llama-factory 作者说法,是lora epoch太多;另外相反的说法,是epoch太少,导致没有学习到结束词im_end;
我这次用的模型和数据都很小,这也是其中一个原因
这个问题,在早期llama-factory 似乎没有出现过
根据我的使用经验,在7B及以上模型没出现过这问题

3.2 使用vllm推理

# -*- coding: utf-8 -*-
# @Time    : 2024/6/4 下午2:01
# @Author  : yblir
# @File    : lyb_qwen_vllm_infer.py
# explain  : 
# =======================================================
import json
import sys
import torchfrom transformers import AutoTokenizer
from vllm import LLM, SamplingParamsdevice = "cuda"  # the device to load the model ontodef qwen_preprocess(tokenizer_, msg):"""最终处理后,msg格式如下,system要改成自己的:[{"role": "system", "content": "You are a helpful assistant."},{"role": "user", "content": "Tell me who you are."},{"role": "assistant", "content": "I am a large language model named Qwen..."}]"""# tokenizer.apply_chat_template() 与model.generate搭配使用messages = [{"role": "system", "content": "You are a helpful assistant."},{"role": "user", "content": msg}]# dd_generation_prompt 参数用于在输入中添加生成提示,该提示指向 <|im_start|>assistant\ntext_ = tokenizer_.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)# print(model_inputs)# sys.exit()return text_if __name__ == '__main__':model_path = '/media/xk/D6B8A862B8A8433B/data/qwen1_5-1_8b_merge_800'data_path = '/media/xk/D6B8A862B8A8433B/GitHub/llama-factory/data/train_clean_eval.json'with open(data_path, 'r', encoding='utf-8') as f:data = json.load(f)# 输出采样策略sampling_params = SamplingParams(temperature=0.7, top_p=0.8, repetition_penalty=1.05, max_tokens=512)# Input the model name or path. Can be GPTQ or AWQ models.llm = LLM(model_path)tokenizer = AutoTokenizer.from_pretrained(model_path)for i, item in enumerate(data):print(f'{i} ------------------------------------------')text = qwen_preprocess(tokenizer, item['instruction'])# generate outputsoutputs = llm.generate([text], sampling_params)# Print the outputs.for output in outputs:# prompt = output.promptgenerated_text = output.outputs[0].text# print(f"Prompt: {prompt!r}, Generated text: {generated_text!r}")print(generated_text)

对上一篇文章测试的qwen_7b_gptq_int4,用本章的推理代码统计耗时,获得单条推理耗时transformers:0.456s,vllm:0.22s,可以看出vllm有2倍的加速,与上篇测试结论一致。这是针对单batch推理,vllm对多batch推理有并行优化,提速应该会更多些。

四 使用总结

qwen1.5用法与qwen差异很大,代码合入了transformers库中,使用风格变得统一,这种标准化是以后大模型发展的一个趋势吧,就像tokenizer.apply_chat_template统一prompt一样。仅过去一年时间,这个领域的许多技术已经趋向成熟,发展速度真是太快啦,对于我们来说变方便了,同时门槛也变低,可以让更多人进入大模型领域。但从另一个角度看,当大模型研发,部署都能通过已有技术简单高效完成,那算法人员存在的意义又是什么呢,技术搬运工 or 高级调参侠?

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

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

相关文章

this,apply,call,bind 超详细合集

前言 之前在学习this关键字的时候&#xff0c;其实一直都是懵懵懂懂。知道答案但是不知道所以。一直想知道为什么是这样&#xff1f;为什么this默认指向全局呢&#xff1f;今天忽然释然了&#xff0c;我又不是开发这门语言的人&#xff0c;我为什么要纠结这些。那今天就来讲讲…

Apache Doris 2.0.11 版本正式发布

亲爱的社区小伙伴们&#xff0c;Apache Doris 2.0.11 版本已于 2024 年 6 月 5 日正式与大家见面&#xff0c;该版本提交了 123 个改进项以及问题修复&#xff0c;进一步提升了系统的性能及稳定性&#xff0c;欢迎大家下载体验。 官网下载&#xff1a; https://doris.apache.o…

jenkins插件之Jdepend

JDepend插件是一个为构建生成JDepend报告的插件。 安装插件 JDepend Dashboard -->> 系统管理 -->> 插件管理 -->> Available plugins 搜索 Jdepend, 点击安装构建步骤新增执行shell #执行pdepend if docker exec phpfpm82 /tmp/composer/vendor/bin/pdepe…

ComfyUI工作流分享-黏土特效工作流

大家给的教程都是苹果端使用Remini的软件制作&#xff0c;免费白嫖7天&#xff0c;7天后就要收费&#xff0c;作为ComfyUI技术党&#xff0c;当然是选择自己实现了&#xff0c;搭建一套工作流就搞定&#xff0c;这不&#xff0c;今天就来分享一套对应的黏土效果工作流&#xff…

使用Python实现GLM解码器的示例(带有Tensor Shape标注)

ByteDance的“Glancing Transformer”&#xff08;GLAT&#xff09;是一种用于无自回归神经机器翻译&#xff08;NAT&#xff09;的创新模型。该模型通过一种称为“glancing sampling”的策略&#xff0c;显著提高了翻译的质量和效率。 GLAT 的主要特性 Glancing Sampling 机制…

TSINGSEE青犀视频:城市道路积水智能监管,智慧城市的守护者

随着城市化进程的加快&#xff0c;城市道路网络日益复杂&#xff0c;尤其在夏季&#xff0c;由于暴雨频发&#xff0c;道路积水问题成为影响城市交通和市民生活的重要因素之一。传统的道路积水监测方式往往依赖于人工巡逻和简单的监控设备&#xff0c;这些方法存在效率低下、响…

数据中台案例04-广西壮族自治区自然灾害应急能力提升工程预警指挥项目—数据治理系统和现场应急感知技术装备采购需求

数据底座数据汇聚融合能力提升数据汇聚融合工具数据接入工具API数据接入组件、实时数据接入组件、空间数据接入组件、数据库接入组件、文件接入组件、数据接入概览组件、批量作业、数据连接管理组件、数据接入任务管理组件、数据接入监控组件数据处理工具数据转换、数据去重、数…

CAN总线学习笔记-CAN帧结构

数据帧 数据帧&#xff1a;发送设备主动发送数据&#xff08;广播式&#xff09; 标准格式的11ID不够用了&#xff0c;由此产生了扩展格式 SOF&#xff1a;帧起始&#xff0c;表示后面一段波形为传输的数据位 ID&#xff1a;标识符&#xff0c;区分功能&#xff0c;同时决定优…

先进制造aps专题十一 国内软件/erp行业的现状及对aps行业的启示

看到一个帖子 中国软件行业几乎全军覆没 OSC开源社区 2024-06-03 15:58 广东 刚刚网上冲浪刷到的 网友锐评&#xff1a;都是客户关系型公司。 知名大 V 「Fenng」评论称&#xff1a; 这里所谓的软件行业公司如果立刻倒闭&#xff0c;才能够利好中国整个行业软件生态。有个网…

巨详细Linux安装Nacos教程

巨详细Linux安装Nacos教程 1、检查是否有残留nacos版本2、上传安装包至服务器2.1安装包获取2.2创建相关目录 3、安装Nacos4、配置Nacos4.1修改数据源4.2新建nacos数据库4.3启动nacos4.4把nacos进程交给systemctl管理4.5设置nacos开机自启动 1、检查是否有残留nacos版本 rpm -q…

【ArcGIS微课1000例】0118:一文讲清楚tif(geotiff)栅格数据格式

文章目录 一、Tiff概述二、GeoTiff概述1. ovr文件2. tfw文件3. xml文件4. dbf文件一、Tiff概述 TIFF(Tagged Image File Format)是一种常见的图像文件格式,它被广泛用于存储和传输各种类型的图像数据。下面是对TIFF格式数据的介绍: 图像存储:TIFF格式可以存储多通道的位…

DB2问题解决:SQL0270N Function not supported (Reason code = “100“). SQLSTATE=42997

在执行修改表结构sql语句过程中&#xff0c;报错&#xff1a;SQL0270N Function not supported (Reason code "100"). SQLSTATE42997 。这个错误通常与表的 DATA CAPTURE 设置有关。如果某些表的 DATA CAPTURE 设置为 CHANGES&#xff0c;则某些表结构修改操作可能不…

Unity基础实践小项目

项目流程&#xff1a; 需求分析 开始界面 选择角色面板 排行榜面板 设置面板 游戏面板 确定退出面板 死亡面板 UML类图 准备工作 1.导入资源 2.创建需要的文件夹 3.创建好面板基类 开始场景 开始界面 1.拼面板 2.写脚本 注意事项&#xff1a;注意先设置NGUI的分辨率大小&…

问题:律师会见委托人的方式包括团体会见和( )。 #职场发展#笔记#学习方法

问题&#xff1a;律师会见委托人的方式包括团体会见和&#xff08; &#xff09;。 参考答案如图所示

Java 线程池的奥秘:让你的代码跑得像火箭!

欢迎来到Java线程池的奇幻世界&#xff01;如果你曾经觉得Java代码跑得像蜗牛&#xff0c;或者你的应用程序偶尔像是喝醉了酒&#xff0c;那你可能需要了解一下Java线程池的秘密武器&#xff01;今天我们就来深入浅出地揭开线程池的神秘面纱&#xff0c;顺便拯救你的应用程序于…

【Python报错】已解决TypeError: can only concatenate str (not “int“) to str

成功解决“TypeError: can only concatenate str (not “int”) to str”错误的全面指南 一、引言 在Python编程中&#xff0c;字符串&#xff08;str&#xff09;和整数&#xff08;int&#xff09;是两种基本的数据类型。然而&#xff0c;当我们尝试将这两种类型的对象进行连…

[matlab]折线图之多条折线如何绘制实心圆作为标记点

使用MarkerFaceColor是标记点填充的颜色&#xff0c;b&#xff0c;表示blue&#xff0c;蓝色 plot(x, a, d--, MarkerFaceColor, b); % 绘制仿真结果的曲线如果一张图多条曲线那么每条曲线需要单独调用一次plot&#xff0c;每个plot间用hold on 连接 plot(x, a, d--, MarkerF…

通配符SSL证书快速申请攻略

一、什么是通配符SSL证书 通配符SSL证书又叫泛域名SSL证书&#xff0c;可以保护一个主域名及其所有二级子域名&#xff0c;并对该级子域名数量无限制&#xff0c;且添加新的该级子域名无须另外付费。 二、通配符SSL证书有哪些优势 1.节省时间和金钱&#xff1a;与购买和安装…

深度学习中的监督学习

深度学习中的监督学习 监督学习&#xff08;Supervised Learning&#xff09;是深度学习中最常见的一种学习方法&#xff0c;它依赖于标注数据集进行训练&#xff0c;通过学习输入数据与其对应的标签之间的映射关系&#xff0c;最终能够对未见过的数据进行准确预测。以下是对深…

Android海外用户增长

目录 文章背景介绍 概念解释&#xff1a; Google FireBase Facebook Appsflyer Tiktok 文章背景介绍 做海外app的【用户增长】功能必经之路&#xff0c;Google的FireBase、AppsFlyer、Facebook、Tiktok&#xff0c;Message等SDK可能都需要接触&#xff0c;以上SDK是我们在…