当前位置: 首页 > news >正文

【机器学习】Qwen2大模型原理、训练及推理部署实战

目录​​​​​​​

一、引言

二、模型简介

2.1 Qwen2 模型概述

2.2 Qwen2 模型架构

三、训练与推理

3.1 Qwen2 模型训练

3.2 Qwen2 模型推理

四、总结


一、引言

刚刚写完【机器学习】Qwen1.5-14B-Chat大模型训练与推理实战 ,阿里Qwen就推出了Qwen2,相较于Qwen1.5中0.5B、1.8B、4B、7B、14B、32B、72B、110B等8个Dense模型以及1个14B(A2.7B)MoE模型共计9个模型,Qwen2包含了0.5B、1.5B、7B、57B-A14B和72B共计5个尺寸模型。从尺寸上来讲,最关键的就是推出了57B-A14B这个更大尺寸的MoE模型,有人问为什么删除了14B这个针对32G显存的常用尺寸,其实对于57B-A14B剪枝一下就可以得到。

二、模型简介

2.1 Qwen2 模型概述

Qwen2对比Qwen1.5

  • 模型尺寸:将Qwen2-7B和Qwen2-72B的模型尺寸有32K提升为128K

  • GQA(分组查询注意力):在Qwen1.5系列中,只有32B和110B的模型使用了GQA。这一次,所有尺寸的模型都使用了GQA,提供GQA加速推理和降低显存占用 

分组查询注意力 (Grouped Query Attention) 是一种在大型语言模型中的多查询注意力 (MQA) 和多头注意力 (MHA) 之间进行插值的方法,它的目标是在保持 MQA 速度的同时实现 MHA 的质量 

  • tie embedding:针对小模型,由于embedding参数量较大,使用了tie embedding的方法让输入和输出层共享参数,增加非embedding参数的占比 

 效果对比

Qwen2-72B全方位围剿Llama3-70B,同时对比更大尺寸的Qwen1.5-110B也有很大提升,官方表示来自于“预训练数据及训练方法的优化”。

2.2 Qwen2 模型架构

Qwen2仍然是一个典型decoder-only的transformers大模型结构,主要包括文本输入层embedding层decoder层输出层损失函数

​​​​​​​

通过AutoModelForCausalLM查看Qwen1.5-7B-Chat和Qwen2-7B-Instruct的模型结构,对比config.json发现:

  

 

  • 网络结构:无明显变化
  • 核心网络Qwen2DecoderLayer层:由32层减少为28层(72B是80层)
  • Q、K、V、O隐层尺寸:由4096减少为3584(72B是8192)
  • attention heads:由32减少为28(72B是64)
  • kv head:由32减少为4(72B是8)
  • 滑动窗口(模型尺寸):由32768(32K)增长为131072(128K)(72B一样)
  • 词表:由151936增长为152064(72B一样)
  • intermediate_size(MLP交叉层):由11008增长为18944(72B是29568)

可以看到其中有的参数增加有的参数减少,猜想是:

  • 减少的参数,并不会降低模型效果,反而能增加训练和推理效率,
  • 增大的参数:比如MLP中的intermediate_size,参数越多,模型表达能力越明显。

三、训练与推理

3.1 Qwen2 模型训练

在【机器学习】Qwen1.5-14B-Chat大模型训练与推理实战 中,我们采用LLaMA-Factory的webui进行训练,今天我们换成命令行的方式,对于LLaMA-Factory框架的部署,可以参考我之前的文章:

AI智能体研发之路-模型篇(一):大模型训练框架LLaMA-Factory在国内网络环境下的安装、部署及使用

该文在百度“LLaMA Factory 部署”词条排行第一:

​​

假设你已经基于上文部署了llama_factory的container,运行进入到container中

docker exec -it llama_factory bash

在app/目录下建立run_train.sh。

CUDA_VISIBLE_DEVICES=2 llamafactory-cli train \--stage sft \--do_train True \--model_name_or_path qwen/Qwen2-7B-Instruct \--finetuning_type lora \--template qwen \--flash_attn auto \--dataset_dir data \--dataset alpaca_zh \--cutoff_len 4096 \--learning_rate 5e-05 \--num_train_epochs 5.0 \--max_samples 100000 \--per_device_train_batch_size 4 \--gradient_accumulation_steps 4 \--lr_scheduler_type cosine \--max_grad_norm 1.0 \--logging_steps 10 \--save_steps 1000 \--warmup_steps 0 \--optim adamw_torch \--packing False \--report_to none \--output_dir saves/Qwen2-7B-Instruct/lora/train_2024-06-09-23-00 \--fp16 True \--lora_rank 32 \--lora_alpha 16 \--lora_dropout 0 \--lora_target q_proj,v_proj \--val_size 0.1 \--evaluation_strategy steps \--eval_steps 1000 \--per_device_eval_batch_size 2 \--load_best_model_at_end True \--plot_loss True

因为之前文章中重点讲的就是国内网络环境的LLaMA-Factory部署,核心就是采用modelscope模型源代替huggingface模型源,这里脚本启动后,就会自动从modelscope下载指定的模型,这里是"qwen/Qwen2-7B-Instruct",下载完后启动训练

训练数据可以通过LLaMA-Factory/data/dataset_info.json文件进行配置,格式参考data目录下的其他数据文件。 比如构建成类型LLaMA-Factory/data/alpaca_zh_demo.json的格式

在LLaMA-Factory/data/dataset_info.json中复制一份进行配置: 

3.2 Qwen2 模型推理

Qwen2的官方文档中介绍了多种优化推理部署的方式,包括基于hf transformers、vllm、llama.cpp、Ollama以及AWQ、GPTQ、GGUF等量化方式,主要因为Qwen2开源的Qwen2-72B、Qwen1.5-110B,远大于GLM4、Baichuan等开源的10B量级小尺寸模型。需要考虑量化、分布式推理问题。​​今天重点介绍Qwen2-7B-Instruct在国内网络环境下的hf transformers推理测试,其他方法单开篇幅进行细致讲解。

呈上一份glm-4-9b-chat、qwen/Qwen2-7B-Instruct通用的极简代码:

from modelscope import snapshot_download
from transformers import AutoTokenizer, AutoModelForCausalLM
#model_dir = snapshot_download('ZhipuAI/glm-4-9b-chat')
model_dir = snapshot_download('qwen/Qwen2-7B-Instruct')
#model_dir = snapshot_download('baichuan-inc/Baichuan2-13B-Chat')
import torchdevice = "auto" # 也可以通过"coda:2"指定GPUtokenizer = AutoTokenizer.from_pretrained(model_dir,trust_remote_code=True)
model = AutoModelForCausalLM.from_pretrained(model_dir,device_map=device,trust_remote_code=True)
print(model)prompt = "介绍一下大语言模型"
messages = [{"role": "system", "content": "你是一个智能助理."},{"role": "user", "content": prompt}
]
text = tokenizer.apply_chat_template(messages,tokenize=False,add_generation_prompt=True
)
model_inputs = tokenizer([text], return_tensors="pt").to(model.device)"""
gen_kwargs = {"max_length": 512, "do_sample": True, "top_k": 1}
with torch.no_grad():outputs = model.generate(**model_inputs, **gen_kwargs)#print(tokenizer.decode(outputs[0],skip_special_tokens=True))outputs = outputs[:, model_inputs['input_ids'].shape[1]:] #切除system、user等对话前缀print(tokenizer.decode(outputs[0], skip_special_tokens=True))"""
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]
print(response)

该代码有几个特点:

  • 网络:从modelscope下载模型文件,解决通过AutoModelForCausalLM模型头下载hf模型慢的问题
  • 通用:适用于glm-4-9b-chat、qwen/Qwen2-7B-Instruct
  • apply_chat_template() :注意!采用 generate()替代旧方法中的chat() 。这里使用了 apply_chat_template() 函数将消息转换为模型能够理解的格式。其中的 add_generation_prompt 参数用于在输入中添加生成提示,该提示指向 <|im_start|>assistant\n 。
  •  tokenizer.batch_decode() :通过 tokenizer.batch_decode() 函数对响应进行解码。

运行结果:

 

除了该极简代码,我针对网络环境对官方git提供的demo代码进行了改造:

cli_demo:

采用modelscope的AutoModelForCausalLM, AutoTokenizer模型头代替transformers对应的模型头,进行模型自动下载

# Copyright (c) Alibaba Cloud.
#
# This source code is licensed under the license found in the
# LICENSE file in the root directory of this source tree."""A simple command-line interactive chat demo."""import argparse
import os
import platform
import shutil
from copy import deepcopy
from threading import Threadimport torch
from modelscope import AutoModelForCausalLM, AutoTokenizer
from transformers import TextIteratorStreamer
from transformers.trainer_utils import set_seedDEFAULT_CKPT_PATH = 'Qwen/Qwen2-7B-Instruct'_WELCOME_MSG = '''\
Welcome to use Qwen2-Instruct model, type text to start chat, type :h to show command help.
(欢迎使用 Qwen2-Instruct 模型,输入内容即可进行对话,:h 显示命令帮助。)Note: This demo is governed by the original license of Qwen2.
We strongly advise users not to knowingly generate or allow others to knowingly generate harmful content, including hate speech, violence, pornography, deception, etc.
(注:本演示受Qwen2的许可协议限制。我们强烈建议,用户不应传播及不应允许他人传播以下内容,包括但不限于仇恨言论、暴力、色情、欺诈相关的有害信息。)
'''
_HELP_MSG = '''\
Commands::help / :h              Show this help message              显示帮助信息:exit / :quit / :q      Exit the demo                       退出Demo:clear / :cl            Clear screen                        清屏:clear-history / :clh   Clear history                       清除对话历史:history / :his         Show history                        显示对话历史:seed                   Show current random seed            显示当前随机种子:seed <N>               Set random seed to <N>              设置随机种子:conf                   Show current generation config      显示生成配置:conf <key>=<value>     Change generation config            修改生成配置:reset-conf             Reset generation config             重置生成配置
'''
_ALL_COMMAND_NAMES = ['help', 'h', 'exit', 'quit', 'q', 'clear', 'cl', 'clear-history', 'clh', 'history', 'his','seed', 'conf', 'reset-conf',
]def _setup_readline():try:import readlineexcept ImportError:return_matches = []def _completer(text, state):nonlocal _matchesif state == 0:_matches = [cmd_name for cmd_name in _ALL_COMMAND_NAMES if cmd_name.startswith(text)]if 0 <= state < len(_matches):return _matches[state]return Nonereadline.set_completer(_completer)readline.parse_and_bind('tab: complete')def _load_model_tokenizer(args):tokenizer = AutoTokenizer.from_pretrained(args.checkpoint_path, resume_download=True,)if args.cpu_only:device_map = "cpu"else:device_map = "auto"model = AutoModelForCausalLM.from_pretrained(args.checkpoint_path,torch_dtype="auto",device_map=device_map,resume_download=True,).eval()model.generation_config.max_new_tokens = 2048    # For chat.return model, tokenizerdef _gc():import gcgc.collect()if torch.cuda.is_available():torch.cuda.empty_cache()def _clear_screen():if platform.system() == "Windows":os.system("cls")else:os.system("clear")def _print_history(history):terminal_width = shutil.get_terminal_size()[0]print(f'History ({len(history)})'.center(terminal_width, '='))for index, (query, response) in enumerate(history):print(f'User[{index}]: {query}')print(f'QWen[{index}]: {response}')print('=' * terminal_width)def _get_input() -> str:while True:try:message = input('User> ').strip()except UnicodeDecodeError:print('[ERROR] Encoding error in input')continueexcept KeyboardInterrupt:exit(1)if message:return messageprint('[ERROR] Query is empty')def _chat_stream(model, tokenizer, query, history):conversation = [{'role': 'system', 'content': 'You are a helpful assistant.'},]for query_h, response_h in history:conversation.append({'role': 'user', 'content': query_h})conversation.append({'role': 'assistant', 'content': response_h})conversation.append({'role': 'user', 'content': query})inputs = tokenizer.apply_chat_template(conversation,add_generation_prompt=True,return_tensors='pt',)inputs = inputs.to(model.device)streamer = TextIteratorStreamer(tokenizer=tokenizer, skip_prompt=True, timeout=60.0, skip_special_tokens=True)generation_kwargs = dict(input_ids=inputs,streamer=streamer,)thread = Thread(target=model.generate, kwargs=generation_kwargs)thread.start()for new_text in streamer:yield new_textdef main():parser = argparse.ArgumentParser(description='QWen2-Instruct command-line interactive chat demo.')parser.add_argument("-c", "--checkpoint-path", type=str, default=DEFAULT_CKPT_PATH,help="Checkpoint name or path, default to %(default)r")parser.add_argument("-s", "--seed", type=int, default=1234, help="Random seed")parser.add_argument("--cpu-only", action="store_true", help="Run demo with CPU only")args = parser.parse_args()history, response = [], ''model, tokenizer = _load_model_tokenizer(args)orig_gen_config = deepcopy(model.generation_config)_setup_readline()_clear_screen()print(_WELCOME_MSG)seed = args.seedwhile True:query = _get_input()# Process commands.if query.startswith(':'):command_words = query[1:].strip().split()if not command_words:command = ''else:command = command_words[0]if command in ['exit', 'quit', 'q']:breakelif command in ['clear', 'cl']:_clear_screen()print(_WELCOME_MSG)_gc()continueelif command in ['clear-history', 'clh']:print(f'[INFO] All {len(history)} history cleared')history.clear()_gc()continueelif command in ['help', 'h']:print(_HELP_MSG)continueelif command in ['history', 'his']:_print_history(history)continueelif command in ['seed']:if len(command_words) == 1:print(f'[INFO] Current random seed: {seed}')continueelse:new_seed_s = command_words[1]try:new_seed = int(new_seed_s)except ValueError:print(f'[WARNING] Fail to change random seed: {new_seed_s!r} is not a valid number')else:print(f'[INFO] Random seed changed to {new_seed}')seed = new_seedcontinueelif command in ['conf']:if len(command_words) == 1:print(model.generation_config)else:for key_value_pairs_str in command_words[1:]:eq_idx = key_value_pairs_str.find('=')if eq_idx == -1:print('[WARNING] format: <key>=<value>')continueconf_key, conf_value_str = key_value_pairs_str[:eq_idx], key_value_pairs_str[eq_idx + 1:]try:conf_value = eval(conf_value_str)except Exception as e:print(e)continueelse:print(f'[INFO] Change config: model.generation_config.{conf_key} = {conf_value}')setattr(model.generation_config, conf_key, conf_value)continueelif command in ['reset-conf']:print('[INFO] Reset generation config')model.generation_config = deepcopy(orig_gen_config)print(model.generation_config)continueelse:# As normal query.pass# Run chat.set_seed(seed)_clear_screen()print(f"\nUser: {query}")print(f"\nQwen2-Instruct: ", end="")try:partial_text = ''for new_text in _chat_stream(model, tokenizer, query, history):print(new_text, end='', flush=True)partial_text += new_textresponse = partial_textprint()except KeyboardInterrupt:print('[WARNING] Generation interrupted')continuehistory.append((query, response))if __name__ == "__main__":main()

web_demo.py:

同上,采用modelscope代替transformers饮用AutoModelForCausalLM, AutoTokenizer,解决模型下载问题

输入参数:加入-g,指定运行的GPU

# Copyright (c) Alibaba Cloud.
#
# This source code is licensed under the license found in the
# LICENSE file in the root directory of this source tree."""A simple web interactive chat demo based on gradio."""from argparse import ArgumentParser
from threading import Threadimport gradio as gr
import torch
from modelscope import AutoModelForCausalLM, AutoTokenizer
from transformers import TextIteratorStreamerDEFAULT_CKPT_PATH = 'Qwen/Qwen2-7B-Instruct'def _get_args():parser = ArgumentParser()parser.add_argument("-c", "--checkpoint-path", type=str, default=DEFAULT_CKPT_PATH,help="Checkpoint name or path, default to %(default)r")parser.add_argument("--cpu-only", action="store_true", help="Run demo with CPU only")parser.add_argument("--share", action="store_true", default=False,help="Create a publicly shareable link for the interface.")parser.add_argument("--inbrowser", action="store_true", default=False,help="Automatically launch the interface in a new tab on the default browser.")parser.add_argument("--server-port", type=int, default=18003,help="Demo server port.")parser.add_argument("--server-name", type=str, default="127.0.0.1",help="Demo server name.")parser.add_argument("-g","--gpus",type=str,default="auto",help="set gpu numbers")args = parser.parse_args()return argsdef _load_model_tokenizer(args):tokenizer = AutoTokenizer.from_pretrained(args.checkpoint_path, resume_download=True,)if args.cpu_only:device_map = "cpu"elif args.gpus=="auto":device_map = args.gpuselse:device_map = "cuda:"+args.gpusmodel = AutoModelForCausalLM.from_pretrained(args.checkpoint_path,torch_dtype="auto",device_map=device_map,resume_download=True,).eval()model.generation_config.max_new_tokens = 2048   # For chat.return model, tokenizerdef _chat_stream(model, tokenizer, query, history):conversation = [{'role': 'system', 'content': 'You are a helpful assistant.'},]for query_h, response_h in history:conversation.append({'role': 'user', 'content': query_h})conversation.append({'role': 'assistant', 'content': response_h})conversation.append({'role': 'user', 'content': query})inputs = tokenizer.apply_chat_template(conversation,add_generation_prompt=True,return_tensors='pt',)inputs = inputs.to(model.device)streamer = TextIteratorStreamer(tokenizer=tokenizer, skip_prompt=True, timeout=60.0, skip_special_tokens=True)generation_kwargs = dict(input_ids=inputs,streamer=streamer,)thread = Thread(target=model.generate, kwargs=generation_kwargs)thread.start()for new_text in streamer:yield new_textdef _gc():import gcgc.collect()if torch.cuda.is_available():torch.cuda.empty_cache()def _launch_demo(args, model, tokenizer):def predict(_query, _chatbot, _task_history):print(f"User: {_query}")_chatbot.append((_query, ""))full_response = ""response = ""for new_text in _chat_stream(model, tokenizer, _query, history=_task_history):response += new_text_chatbot[-1] = (_query, response)yield _chatbotfull_response = responseprint(f"History: {_task_history}")_task_history.append((_query, full_response))print(f"Qwen2-Instruct: {full_response}")def regenerate(_chatbot, _task_history):if not _task_history:yield _chatbotreturnitem = _task_history.pop(-1)_chatbot.pop(-1)yield from predict(item[0], _chatbot, _task_history)def reset_user_input():return gr.update(value="")def reset_state(_chatbot, _task_history):_task_history.clear()_chatbot.clear()_gc()return _chatbotwith gr.Blocks() as demo:gr.Markdown("""\
<p align="center"><img src="https://qianwen-res.oss-accelerate-overseas.aliyuncs.com/logo_qwen2.png" style="height: 80px"/><p>""")gr.Markdown("""<center><font size=8>Qwen2 Chat Bot</center>""")gr.Markdown("""\
<center><font size=3>This WebUI is based on Qwen2-Instruct, developed by Alibaba Cloud. \
(本WebUI基于Qwen2-Instruct打造,实现聊天机器人功能。)</center>""")gr.Markdown("""\
<center><font size=4>
Qwen2-7B-Instruct <a href="https://modelscope.cn/models/qwen/Qwen2-7B-Instruct/summary">🤖 </a> | 
<a href="https://huggingface.co/Qwen/Qwen2-7B-Instruct">🤗</a>&nbsp | 
Qwen2-72B-Instruct <a href="https://modelscope.cn/models/qwen/Qwen2-72B-Instruct/summary">🤖 </a> | 
<a href="https://huggingface.co/Qwen/Qwen2-72B-Instruct">🤗</a>&nbsp | 
&nbsp<a href="https://github.com/QwenLM/Qwen2">Github</a></center>""")chatbot = gr.Chatbot(label='Qwen2-Instruct', elem_classes="control-height")query = gr.Textbox(lines=2, label='Input')task_history = gr.State([])with gr.Row():empty_btn = gr.Button("🧹 Clear History (清除历史)")submit_btn = gr.Button("🚀 Submit (发送)")regen_btn = gr.Button("🤔️ Regenerate (重试)")submit_btn.click(predict, [query, chatbot, task_history], [chatbot], show_progress=True)submit_btn.click(reset_user_input, [], [query])empty_btn.click(reset_state, [chatbot, task_history], outputs=[chatbot], show_progress=True)regen_btn.click(regenerate, [chatbot, task_history], [chatbot], show_progress=True)gr.Markdown("""\
<font size=2>Note: This demo is governed by the original license of Qwen2. \
We strongly advise users not to knowingly generate or allow others to knowingly generate harmful content, \
including hate speech, violence, pornography, deception, etc. \
(注:本演示受Qwen2的许可协议限制。我们强烈建议,用户不应传播及不应允许他人传播以下内容,\
包括但不限于仇恨言论、暴力、色情、欺诈相关的有害信息。)""")demo.queue().launch(share=args.share,inbrowser=args.inbrowser,server_port=args.server_port,server_name=args.server_name,)def main():args = _get_args()model, tokenizer = _load_model_tokenizer(args)_launch_demo(args, model, tokenizer)if __name__ == '__main__':main()

四、总结

本文首先对Qwen2模型概述以及模型架构进行讲解,接着基于llama_factory命令行的方式进行模型训练演示,最后基于hf transformers进行模型推理的讲解。过程中排了好几个坑,呈上的代码保证在国内网络环境下是可运行的。希望能帮助到大家。喜欢的话关注+三连噢。

如果您还有时间,可以看看我的其他文章:

《AI—工程篇》

AI智能体研发之路-工程篇(一):Docker助力AI智能体开发提效

AI智能体研发之路-工程篇(二):Dify智能体开发平台一键部署

AI智能体研发之路-工程篇(三):大模型推理服务框架Ollama一键部署

AI智能体研发之路-工程篇(四):大模型推理服务框架Xinference一键部署

AI智能体研发之路-工程篇(五):大模型推理服务框架LocalAI一键部署

《AI—模型篇》

AI智能体研发之路-模型篇(一):大模型训练框架LLaMA-Factory在国内网络环境下的安装、部署及使用

AI智能体研发之路-模型篇(二):DeepSeek-V2-Chat 训练与推理实战

AI智能体研发之路-模型篇(三):中文大模型开、闭源之争

AI智能体研发之路-模型篇(四):一文入门pytorch开发

AI智能体研发之路-模型篇(五):pytorch vs tensorflow框架DNN网络结构源码级对比

AI智能体研发之路-模型篇(六):【机器学习】基于tensorflow实现你的第一个DNN网络

AI智能体研发之路-模型篇(七):【机器学习】基于YOLOv10实现你的第一个视觉AI大模型

AI智能体研发之路-模型篇(八):【机器学习】Qwen1.5-14B-Chat大模型训练与推理实战

AI智能体研发之路-模型篇(九):【机器学习】GLM4-9B-Chat大模型/GLM-4V-9B多模态大模型概述、原理及推理实战​​​​​​​

《AI—Transformers应用》

【AI大模型】Transformers大模型库(一):Tokenizer

【AI大模型】Transformers大模型库(二):AutoModelForCausalLM

【AI大模型】Transformers大模型库(三):特殊标记(special tokens)

【AI大模型】Transformers大模型库(四):AutoTokenizer 

相关文章:

【机器学习】Qwen2大模型原理、训练及推理部署实战

目录​​​​​​​ 一、引言 二、模型简介 2.1 Qwen2 模型概述 2.2 Qwen2 模型架构 三、训练与推理 3.1 Qwen2 模型训练 3.2 Qwen2 模型推理 四、总结 一、引言 刚刚写完【机器学习】Qwen1.5-14B-Chat大模型训练与推理实战 &#xff0c;阿里Qwen就推出了Qwen2&#x…...

JetLinks开源物联网平台社区版部署教程

1.上github搜素jetlinks 2.找到源代码&#xff0c;并且下载到本地。 3.项目下载完成之后&#xff0c;还需要另外下载三个核心依赖模块。在github找到jetlinks。 4.点击进去下载&#xff0c;下载完成之后&#xff0c;你会发现里面有三个文件夹是空白的&#xff0c;先不用理会&am…...

QT学习过程中遇到的问题自记

文章目录 前言问题1问题2问题3 前言 学习QT嵌入式实战开发(从串口通信到JSON通信微课视频版)的过程中遇到的几个小问题 问题1 1.将书中的示例代码导入自己的电脑&#xff0c;然后点击工程进去&#xff0c;不能运行&#xff0c;报错 no kits are enabled for this project… 我…...

自学网络安全的三个必经阶段(含路线图)

一、为什么选择网络安全&#xff1f; 这几年随着我国《国家网络空间安全战略》《网络安全法》《网络安全等级保护2.0》等一系列政策/法规/标准的持续落地&#xff0c;网络安全行业地位、薪资随之水涨船高。 未来3-5年&#xff0c;是安全行业的黄金发展期&#xff0c;提前踏入…...

gitlab下载及安装

目录 1、gitlab下载 2、gitlab安装 3、完全卸载GitLab 1、gitlab下载 首页&#xff1a;https://about.gitlab.com 安装&#xff1a;https://about.gitlab.com/install rpm包&#xff1a;https://packages.gitlab.com/gitlab/gitlab-ce 2、gitlab安装 2.1 CentOS 7 rpm -iv…...

YOLOv10改进|采用ADown降采样模块有效融合

📚 专栏地址:《YOLOv10算法改进实战》 👉 独家改进,对现有YOLOv10进行二次创新,提升检测精度,适合科研创新度十足,强烈推荐 🌟 统一使用 YOLOv10 代码框架,结合不同模块来构建不同的YOLO目标检测模型。 💥 本博客包含大量的改进方式,降低改进难度,改进点包含【B…...

libGL.so.1: cannot open shared object file: No such file or directory

Ubuntu 安装 PaddleOCR 时报错 libGL.so.1: cannot open shared object file: No such file or directory解决办法&#xff1a; # 这个好像GPU 服务器更好用 pip install opencv-python-headless如果不行就&#xff1a; # 尝试安装缺失的libGL.so.1文件。在大多数Linux发行版…...

2024年消防设施操作员考试题库及答案

一、单选题 31.工作时间是指劳动者根据国家的法律规定&#xff0c;在1个昼夜或1周之内从事本职工作的时间。《劳动法》规定劳动者每日工作时间不超过8h&#xff0c;平均每周工作时间不超过&#xff08;&#xff09;h。 A.44 B.45 C.46 D.50 答案&#xff1a;A 解析&…...

30字以内免费翻译维吾尔语,汉维翻译工具推荐,维吾尔文字母OCR识别神器《维汉翻译通》App!

维吾尔文OCR文字识别 《维汉翻译通》App内置的OCR技术&#xff0c;能够快速识别图片中的文字和字母&#xff0c;无论是路标、菜单还是书籍&#xff0c;都能迅速转换为用户所需的语言&#xff0c;让语言障碍不再是问题。针对维吾尔语更是进行了专门的优化&#xff0c;即便是手写…...

省市县选择三级联动(使用高德API实现)

省市县选择如果自己实现是比较麻烦的&#xff0c;最近发现可以使用高德实现省市县联动选择&#xff0c;实现后来记录一下供大家参考。 文章目录 最终效果&#xff1a;一、准备工作二、完整页面代码 最终效果&#xff1a; 实现单次点击获取省市县名称&#xff0c;选择完成后返回…...

【数据结构(邓俊辉)学习笔记】图06——最小支撑树

文章目录 0. 概述1. 支撑树2. 最小支撑树3. 歧义性4. 蛮力算法5. Prim算法5.1 割与极短跨越边5.2 贪心迭代5.3 实例5.4 实现5.5 复杂度 0. 概述 学习下最小支撑树和prim算法。 1. 支撑树 最小的连通图是树。 连通图G的某一无环连通子图T若覆盖G中所有的顶点&#xff0c;则称…...

海豚调度清理:使用 API 轻松清理历史工作流实例以及日志文件

&#x1f4a1; 本系列文章是 DolphinScheduler 由浅入深的教程&#xff0c;涵盖搭建、二开迭代、核心原理解读、运维和管理等一系列内容。适用于想对 DolphinScheduler了解或想要加深理解的读者。 祝开卷有益。 大数据学习指南 大家好&#xff0c;我是小陶&#xff0c;DolphinS…...

python怎么显示行号

我们如果想让Python IDLE显示行号&#xff0c;我们可以通过扩展IDLE功能来做到。 1.我们需要下载一个LineNumber.py扩展。 2.我们打开Python安装目录&#xff0c;找到安装目录下的Lib\idlelib目录&#xff0c;复制LineNumber到这个目录。 3.然后启动扩展。 4.配置扩展的方式…...

pytorch中,load_state_dict和torch.load的区别?

在 PyTorch 中&#xff0c;load_state_dict 和 torch.load 是两个不同的函数&#xff0c;用于不同的目的。 torch.load: 用途: 从磁盘加载一个保存的对象。这个对象可以是一个模型的整个状态字典&#xff08;包含模型参数&#xff09;、优化器状态字典、甚至是任意其他 Python …...

ObjectARX打印当前图纸为PDF,无延迟(亲测有效)

CAD二次开发定制ObjectARX安装配置AutoCAD插件ZWCAD插件C++ //----------------------------------------------------------------------------- //----- acrxEntryPoint.cpp //----------------------------------------------------------------------------- #include &quo…...

torch.squeeze() dim=1 dim=-1 dim=2

对数据的维度进行压缩 使用方式&#xff1a;torch.squeeze(input, dimNone, outNone) 将输入张量形状中的1 去除并返回。 如果输入是形如(A1B1C1D)&#xff0c;那么输出形状就为&#xff1a; (ABCD) import torch x torch.rand(2, 1, 1, 3, 1, 4) print(x) print(x.shape) …...

智慧环保一体化平台简介

据悉&#xff0c;环保问题日益受到人们的关注&#xff0c;智慧环保一体化平台作为解决环保问题的有力工具&#xff0c;正逐渐走进人们的视野。朗观视觉智慧环保一体化平台通过整合各类环保资源&#xff0c;实现环境数据的实时监测、分析与管理&#xff0c;为环境保护提供智能化…...

idea在空工程中添加新模块并测试的步骤

ServicesTest是空的工程&#xff0c;没有pom文件。现在需要在ServicesTest目录下添加新模块作为新的工程&#xff0c;目的是写一下别的技术功能。 原先目录结构&#xff0c;ServicesTest是空的工程&#xff0c;没有pom文件。下面的几个模块是新的工程&#xff0c;相互独立。 1.…...

HCIE-QOS基本原理

QOS基本原理 QOS概述什么是QOSQoS服务模型区分服务模型QoS常用技术 (DiffServ模型)QoS数据处理流程 (DiffServ模型) QoS流分类和流标记QoS数据处理流程为什么需要流分类和流标记 简单流分类外部优先级 - VLAN报文外部优先级 - MPLS报文外部优先级 - IP报文各外部优先级间的对应…...

pycharm基本使用(常用快捷键)

0.下载 pycharm官网下载 选择合适的版本&#xff0c;本文以2024.1为例 1.简单应用 常用快捷键 ctrlD 复制当前行 ctrlY 删除当前行 ctrlX 剪切当前行&#xff08;可用作删除&#xff0c;更顺手&#xff09; shift↑ 选中多行ctrlshiftF10 运行 shiftF9 调试ctrl/ 注释当前…...

云计算——弹性云计算器(ECS)

弹性云服务器&#xff1a;ECS 概述 云计算重构了ICT系统&#xff0c;云计算平台厂商推出使得厂家能够主要关注应用管理而非平台管理的云平台&#xff0c;包含如下主要概念。 ECS&#xff08;Elastic Cloud Server&#xff09;&#xff1a;即弹性云服务器&#xff0c;是云计算…...

阿里云ACP云计算备考笔记 (5)——弹性伸缩

目录 第一章 概述 第二章 弹性伸缩简介 1、弹性伸缩 2、垂直伸缩 3、优势 4、应用场景 ① 无规律的业务量波动 ② 有规律的业务量波动 ③ 无明显业务量波动 ④ 混合型业务 ⑤ 消息通知 ⑥ 生命周期挂钩 ⑦ 自定义方式 ⑧ 滚的升级 5、使用限制 第三章 主要定义 …...

边缘计算医疗风险自查APP开发方案

核心目标:在便携设备(智能手表/家用检测仪)部署轻量化疾病预测模型,实现低延迟、隐私安全的实时健康风险评估。 一、技术架构设计 #mermaid-svg-iuNaeeLK2YoFKfao {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg…...

FastAPI 教程:从入门到实践

FastAPI 是一个现代、快速&#xff08;高性能&#xff09;的 Web 框架&#xff0c;用于构建 API&#xff0c;支持 Python 3.6。它基于标准 Python 类型提示&#xff0c;易于学习且功能强大。以下是一个完整的 FastAPI 入门教程&#xff0c;涵盖从环境搭建到创建并运行一个简单的…...

【快手拥抱开源】通过快手团队开源的 KwaiCoder-AutoThink-preview 解锁大语言模型的潜力

引言&#xff1a; 在人工智能快速发展的浪潮中&#xff0c;快手Kwaipilot团队推出的 KwaiCoder-AutoThink-preview 具有里程碑意义——这是首个公开的AutoThink大语言模型&#xff08;LLM&#xff09;。该模型代表着该领域的重大突破&#xff0c;通过独特方式融合思考与非思考…...

如何在看板中有效管理突发紧急任务

在看板中有效管理突发紧急任务需要&#xff1a;设立专门的紧急任务通道、重新调整任务优先级、保持适度的WIP&#xff08;Work-in-Progress&#xff09;弹性、优化任务处理流程、提高团队应对突发情况的敏捷性。其中&#xff0c;设立专门的紧急任务通道尤为重要&#xff0c;这能…...

AI编程--插件对比分析:CodeRider、GitHub Copilot及其他

AI编程插件对比分析&#xff1a;CodeRider、GitHub Copilot及其他 随着人工智能技术的快速发展&#xff0c;AI编程插件已成为提升开发者生产力的重要工具。CodeRider和GitHub Copilot作为市场上的领先者&#xff0c;分别以其独特的特性和生态系统吸引了大量开发者。本文将从功…...

学校时钟系统,标准考场时钟系统,AI亮相2025高考,赛思时钟系统为教育公平筑起“精准防线”

2025年#高考 将在近日拉开帷幕&#xff0c;#AI 监考一度冲上热搜。当AI深度融入高考&#xff0c;#时间同步 不再是辅助功能&#xff0c;而是决定AI监考系统成败的“生命线”。 AI亮相2025高考&#xff0c;40种异常行为0.5秒精准识别 2025年高考即将拉开帷幕&#xff0c;江西、…...

【从零学习JVM|第三篇】类的生命周期(高频面试题)

前言&#xff1a; 在Java编程中&#xff0c;类的生命周期是指类从被加载到内存中开始&#xff0c;到被卸载出内存为止的整个过程。了解类的生命周期对于理解Java程序的运行机制以及性能优化非常重要。本文会深入探寻类的生命周期&#xff0c;让读者对此有深刻印象。 目录 ​…...

【 java 虚拟机知识 第一篇 】

目录 1.内存模型 1.1.JVM内存模型的介绍 1.2.堆和栈的区别 1.3.栈的存储细节 1.4.堆的部分 1.5.程序计数器的作用 1.6.方法区的内容 1.7.字符串池 1.8.引用类型 1.9.内存泄漏与内存溢出 1.10.会出现内存溢出的结构 1.内存模型 1.1.JVM内存模型的介绍 内存模型主要分…...