使用PaddleNLP 从0构建一个属于你自己的心理大模型

项目源于:EmoLLM心理大模型,一直就有用paddle实践心理大模型的想法,终于实现了哈~。接下来就手把手带大家一块做一个心理大模型吧!!! 简单画了个框架图: 

环境配置

In [ ]

# !git clone -b develop https://github.com/PaddlePaddle/PaddleNLP.git
%cd PaddleNLP
!pip install -e .

# 为了解决一个环境依赖问题,在训练的时候随机出现的,稍微有点离谱,大概是环境的问题

%cd ~
# !git clone https://github.com/PaddlePaddle/PaddleSlim
%cd PaddleSlim/csrc
!python ./setup_cuda.py install 

数据集构建

参考飞桨大模型精调文档,PaddleNLP支持的数据格式是每行包含一个字典,每个字典包含以下字段:

  • src : str, List(str), 模型的输入指令(instruction)、提示(prompt),模型应该执行的任务。

  • tgt : str, List(str), 模型的输出。

多轮对话时如下:

{"src": ["user-1", "user-2", ..., "user-n"], "tgt": ["bot-1", "bot-2", ..., "bot-n"]}

为了使我们的心理大模型有更好的表达效果,我们必须要有高质量的数据集。自己构建数据集相当麻烦呜呜,因此决定借用文心大模型的强大能力,通过调用文心一言的API来生成对应的数据集。因为心理活动往往是复杂的,为了保证数据的多样性。我们选择了16 * 28 共 448个场景(如下)进行数据集生成,

emotions_list : [
        "钦佩",
        "崇拜",
        "欣赏",
        "娱乐",
        "焦虑",
        "敬畏",
        "尴尬",
        "厌倦",
        "冷静",
        "困惑",
        "渴望",
        "厌恶",
        "同情",
        "痛苦",
        "着迷",
        "嫉妒",
        "兴奋",
        "恐惧",
        "痛恨",
        "有趣",
        "快乐",
        "怀旧",
        "浪漫",
        "悲伤",
        "满意",
        "性欲",
        "同情",
        "满足"
    ]
areas_of_life : [
    "工作",
    "学业",
    "生活",
    "身体",
    "家人",
    "朋友",
    "社交",
    "恋爱",
    "就业",
    "责任",
    "爱好",
    "环境",
    "隐私",
    "安全",
    "梦想",
    "自由"
]

需要配置config.yml,将自己的访问令牌放入即可。

配置文心一言

In [ ]

!pip install erniebot

In [2]

import erniebot
erniebot.api_type = 'aistudio'
erniebot.access_token = "{个人中心的访问令牌}"#请输入自己的访问令牌

数据生成

In [ ]

import json
import random
import yaml 
import erniebot
with open('config.yml', 'r', encoding='utf-8') as f:
    configs = yaml.load(f.read(), Loader=yaml.FullLoader)

erniebot.api_type = 'aistudio'
#此处需要将你的token也就是AIstudio主页的访问令牌放到下方
erniebot.access_token = configs['aistudio _token']
system = configs['system']
areas_of_life = configs['areas_of_life']
emotions_list = configs['emotions_list']
words = ''
# prompt = '''
# 你是一个研究过无数具有心理健康问题的病人与心理健康医生对话案例的专家,请你构造一些符合实际情况的具有心理健康问题的病人和心理健康医生的多轮对话案例。要求医生的回复尽可能包含心理辅导知识,并且能够一步步诱导病人说出自己的问题进而提供解决问题的可行方案。注意,构造的数据必须以医生的陈述为结束语。请以如下格式返回生成的数据:
# 病人:病人的咨询或陈述
# 医生:医生的安抚和建议
# '''
res = []
for data in areas_of_life[:2]:
    for emo in emotions_list[:2]:
        print(f'正在为{data}_{emo}场景生成对应数据集')
        
        prompt = f'''你是一个研究过无数具有心理健康问题的病人与心理健康医生对话的专家,请你构造一些符合实际情况的具有心理健康问题的病人和心理健康医生的连续的多轮对话记录。
        要求病人的问题属于{data}场景,具有{emo}情感,医生的回复尽可能包含心理辅导知识,并且能够一步步诱导病人说出自己的问题进而提供解决问题的可行方案。
        注意,构造的数据必须以医生的陈述为结束语,每次只需要构造一个案例并且不需要写案例一、二等等,请返回完整的对话内容。
        请以如下格式返回生成的数据:
        病人:病人的咨询或陈述 
        医生:医生的安抚和建议
        '''
        try :
        for i in range(1):
            response = erniebot.ChatCompletion.create(
                model='ernie-3.5',
                messages=[{'role': 'user', 'content': f"{prompt}"}],
                # top_p=random.uniform(0.5, 0.99),
                # penalty_score = random.uniform(1.0, 2.0)
            )
            tmp = response.result
            print(tmp)
            ls = tmp.split('\n')
            ls = [i for i in ls if i!='']
            # conversation = {'src':[], 'tgt':[]}
            src = []
            tgt = []
        except:
            pass 
            for j in range(0, len(ls)-1, 2):
                src.append(ls[j].split(":")[-1])
                tgt.append(ls[j+1].split(":")[-1])
            res.append({'src':src, 'tgt':tgt, "context": {"system": "现在你是一个心理专家,我有一些心理问题,请你用专业的知识帮我解决。" }})
        print(f'第{i}条数据生成完成!!')
    print('================================')
    print(f'{data}_{emo}场景对应数据集生成完毕')
    # 将数据写入JSON文件  
    
    # with open('./tmp_data.json', 'w', encoding='utf-8') as file:  
    #     json.dump(res, file, ensure_ascii=False, indent=4)

In [25]

with open('output.json', 'w', encoding='utf-8') as f:
    for item in res:
        json.dump(item, f, ensure_ascii=False,)
        f.write('\n')

生成部分数据如下: 

 考虑到生成时间较慢,我们之前也开源过相应的EmoLLM心理数据集,不过需要将其进行格式转换。接下来就直接使用对已有数据集进行格式转化后的数据 原始数据: 

In [ ]

!unzip /home/aistudio/data/data276450/datasets.zip -d  /home/aistudio # 解压后的数据集在datasets目录下,使用data.json

In [27]

import json
EmoLLM_Data = []
with open('/home/aistudio/datasets/data.json', 'r') as f:  
    data = json.load(f)

for data_item in data:
    # print(data_item)
    src = []
    tgt = [] 
    for j in data_item['conversation']:
        src.append(j['input'])
        tgt.append(j['output'])
        print(j['input'])
        print(j['output'])
    assert len(src) == len(tgt)
    EmoLLM_Data.append({'src':src, 'tgt':tgt, "context": {"system": f"{data_item['conversation'][0]['system']}"}})

with open('EmoLLM.json', 'w', encoding='utf-8') as f:
    for item in EmoLLM_Data:
        json.dump(item, f, ensure_ascii=False)
        f.write('\n')
IOPub data rate exceeded.
The Jupyter server will temporarily stop sending output
to the client in order to avoid crashing it.
To change this limit, set the config variable
`--ServerApp.iopub_data_rate_limit`.

Current values:
ServerApp.iopub_data_rate_limit=1000000.0 (bytes/sec)
ServerApp.rate_limit_window=3.0 (secs)

In [24]

data_item['conversation']
[{'system': '现在你是一个心理专家,我有一些心理问题,请你用专业的知识帮我解决。',
  'input': '医生,我最近总是感觉很沮丧,做什么都提不起兴趣,甚至觉得生活没有意义。',
  'output': '我非常理解你的感受,这种情况在心理学中被称为抑郁症状。首先,请不要责怪自己,许多人都会有类似的情绪低落时期。你是否可以试着分享一下近期生活中有什么具体的压力或变故,或者是什么事情让你开始有这种感觉的呢?'},
 {'input': '其实,我最近失业了,然后跟女朋友的关系也变得紧张,我觉得自己好像一无是处,无法承担起生活的责任。',
  'output': '明白了,失业和人际关系的压力确实是导致情绪低落的常见原因。首先,对于失业问题,这是社会环境和个人能力不匹配的结果,并不代表你个人价值的缺失。你可以尝试提升技能、拓宽职业道路,或者寻找临时工作以缓解经济压力。其次,关系问题上,建议你与女友坦诚沟通,表达你的困扰与担忧,寻求共同解决问题的方法。同时,我也建议你尝试进行一些能带来积极情绪的活动,比如运动、阅读或是参加社交活动,这些都有助于改善心情。此外,如有需要,我们可以进一步探讨并制定专业的心理治疗方案,比如认知行为疗法,帮助你更有效地应对这些问题。请记住,寻求帮助是一种力量,而非软弱的表现。'}]

执行以上代码之后,我们会得到EmoLLM.json文件,也就是我们测试所用的数据集。 内容大致如下: 

训练开始

模型转化

不太想将torch的模型转为paddle(偷个懒), 大家在paddlenlp上找到可以适配的模型之后,替换以下代码,执行等待模型下载完毕。

from paddlenlp.transformers import AutoModelForCausalLM, AutoTokenizer
model = AutoModelForCausalLM.from_pretrained("meta-llama/Llama-2-7b-chat")
tokenizer = AutoTokenizer.from_pretrained("meta-llama/Llama-2-7b-chat")

现在模型已经下载到我们的studio上 ,执行以下命令(具体路径可自行更改)。然后就有了paddle版本的模型

mv .paddlenlp/models/meta-llama/Llama-2-7b-chat /home/aistudio/model

这里我刚开始写的时候没注意,PaddleNlP可以自动转huggingface上的模型,很方便的。不必要和我的操作一样

PaddleNLP 初体验

In [ ]

from paddlenlp.transformers import AutoModelForCausalLM, AutoTokenizer
model = AutoModelForCausalLM.from_pretrained("/home/aistudio/model/Llama-2-7b-chat")
tokenizer = AutoTokenizer.from_pretrained("/home/aistudio/model/Llama-2-7b-chat")

In [2]

print(type(model))
<class 'paddlenlp.transformers.llama.modeling.LlamaForCausalLM'>

In [6]

input_features = tokenizer("你好!请自我介绍一下。", return_tensors="pd")

In [7]

input_features
{'input_ids': Tensor(shape=[1, 15], dtype=int64, place=Place(gpu:0), stop_gradient=True,
       [[1    , 29871, 30919, 31076, 30584, 31088, 30688, 30672, 31633, 234  ,
         190  , 144  , 30287, 30557, 30267]]), 'position_ids': Tensor(shape=[1, 15], dtype=int64, place=Place(gpu:0), stop_gradient=True,
       [[0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10, 11, 12, 13, 14]]), 'attention_mask': Tensor(shape=[1, 15], dtype=int64, place=Place(gpu:0), stop_gradient=True,
       [[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]])}

In [8]

outputs = model.generate(**input_features, max_length=128)
[2024-06-09 14:23:40,260] [ WARNING] - `max_length` will be deprecated in future releases, use `max_new_tokens` instead.
W0609 14:23:40.592916 21392 dygraph_functions.cc:52647] got different data type, run type protmotion automatically, this may cause data type been changed.

In [9]

tokenizer.batch_decode(outputs[0])
["\n\nHello! Please introduce yourself.\n\nIntroducing yourself can be a bit tricky, but here are some tips to help you:\n\n1. Start with your name: This might seem obvious, but it's important to start with your name when introducing yourself. Make sure to pronounce it correctly and clearly.\n2. Share your profession: What do you do for a living? Are you a student, a teacher, a doctor, or a business owner? Share your profession and any relevant details.\n3. Mention your hobbies: What do you enjoy doing in your free time? Do"]

精调开始

测试已完成,接下来就是开始精调了 出错了

按照上图命令依次执行即可(tips:我出现的状况 有点稍稍逆天。就是按照命令执行成功之后(在vscode环境下) pip显示也有。但是就是出现这个错误。解决办法:关闭终端,卸载重复执行 会成功的哈)

git clone https://github.com/PaddlePaddle/PaddleSlim
cd Paddleslim/csrc
python ./setup_cuda.py install

修复完bug之后,再执行下面的命令,即可成功开始微调

python  finetune_generation.py ./llama/lora_argument.json --model_name_or_path /home/aistudio/model/Llama-2-7b-chat --dataset_name_or_path /home/aistudio/work --num_train_epochs 1 --per_device_train_batch_size 1 --gradient_accumulation_steps 1 --per_device_eval_batch_size 1 --chat_template /home/aistudio/model/Llama-2-7b-chat/chat_template.json

微调成功画面和微调后权重路径如下: 

现在我们得到了一个微调好的模型,但是为了后续的压缩和静态图推理方便,需要进行参数合并。 执行以下命令即可

python merge_lora_params.py \
    --lora_path ./checkpoints/llama_lora_ckpts \
    --merge_lora_model_path ./checkpoints/llama_lora_merge \
    --device "gpu" \
    --low_gpu_mem True

merge_lora_params.py脚本参数介绍 - lora_path: LoRA参数和配置路径,对LoRA参数进行初始化,默认为None。

- merge_model_path: 必须,合并参数后保存路径,默认为None。

- device: 运行环境,默认为gpu。

- low_gpu_mem:降低合参时候所需显存,默认为False。如果合参时显存不足,建议开启

合并成功画面如下:

模型量化

可参考仓库文档

模型推理

cd ~
cd PaddleNLP/llm

确保此时还在 PaddleNLP/llm 运行目录中

动态图推理

注意使用develop版本的Paddle 否则会出现如下错误,我查了issue是develop版本修复这个问题。然后怎么做呢?卸载重装Paddle啦。 这里还有一个bug(太菜了导致的) 以下是错误示范:使用nvidia-smi查看cuda版本,发现是12.0,然后无脑去官网pip下载12.0版本的paddle。安装成功之后,喜提报错:paddle都灭法用。历经曲折在散步大佬的帮助下,终于解决了。以下是在aistudio上安装develop 版本 paddle的过程:

下载的GPU版本Paddle 对应的应是11.8的。

pip uninstall paddlepaddle-gpu

python -m pip install paddlepaddle-gpu==0.0.0.post118 -f https://www.paddlepaddle.org.cn/whl/linux/gpu/develop.html

执行以下推理开始:

python predictor.py --model_name_or_path /home/aistudio/model/Llama-2-7b-chat --lora_path ./checkpoints/llama_lora_ckpts --data_file ~/work/dev.json --dtype float16

开始推理: 

推理成功图片: 

推理时资源占用情况:(分析 32G的环境跑起来也可以,因为还没有量化啥的,量化后资源会占用的更少)

静态图推理
# 静态图模型推理命令参考, LoRA需要先合并参数,Prefix Tuning暂不支持
# step1 : 静态图导出
python export_model.py --model_name_or_path /home/aistudio/model/Llama-2-7b-chat --output_path ./inference --dtype float16 --lora_path ./checkpoints/llama_lora_ckpts
# step2: 静态图推理
python predictor.py --model_name_or_path ./inference --data_file ~/work/dev.json --dtype float16 --mode static 

导出时图片: 

静态图推理时图片:

静态图推理时资源占用情况:

高性能模型推理

这一块就不写了运行一遍挺慢的 可以参考大模型推理教程

为了进一步提升推理的吞吐,PaddleMLP基于PageAttention的思想设计并实现了BlockAttention,在保持高性能推理和动态插入的基础上可以动态地为cachekv分配存储空间,极大地节省显存,从而在同一时刻处理更多的query以获得吞吐的提升。

结果结果显示:

经过以上我们也得到了对应的模型,接下来调用一下paddlenlp的API推理一下试试哈~

In [5]

from paddlenlp.transformers import AutoModelForCausalLM, AutoTokenizer
model = AutoModelForCausalLM.from_pretrained("/home/aistudio/PaddleNLP/llm/checkpoints/llama_lora_merge")
tokenizer = AutoTokenizer.from_pretrained("/home/aistudio/PaddleNLP/llm/checkpoints/llama_lora_merge")
[2024-06-12 21:22:07,547] [    INFO] - We are using <class 'paddlenlp.transformers.llama.modeling.LlamaForCausalLM'> to load '/home/aistudio/PaddleNLP/llm/checkpoints/llama_lora_merge'.
[2024-06-12 21:22:07,549] [    INFO] - Loading configuration file /home/aistudio/PaddleNLP/llm/checkpoints/llama_lora_merge/config.json
[2024-06-12 21:22:07,552] [    INFO] - Loading weights file /home/aistudio/PaddleNLP/llm/checkpoints/llama_lora_merge/model_state.pdparams.index.json
W0612 21:22:07.560400 448099 gpu_resources.cc:119] Please NOTE: device: 0, GPU Compute Capability: 7.0, Driver API Version: 12.0, Runtime API Version: 11.8
W0612 21:22:07.561983 448099 gpu_resources.cc:164] device: 0, cuDNN Version: 8.9.
Loading checkpoint shards: 100%|██████████| 2/2 [02:14<00:00, 67.29s/it] 
[2024-06-12 21:24:48,040] [    INFO] - All model checkpoint weights were used when initializing LlamaForCausalLM.

[2024-06-12 21:24:48,041] [    INFO] - All the weights of LlamaForCausalLM were initialized from the model checkpoint at /home/aistudio/PaddleNLP/llm/checkpoints/llama_lora_merge.
If your task is similar to the task the model of the checkpoint was trained on, you can already use LlamaForCausalLM for predictions without further training.
[2024-06-12 21:24:48,046] [    INFO] - Loading configuration file /home/aistudio/PaddleNLP/llm/checkpoints/llama_lora_merge/generation_config.json
[2024-06-12 21:24:48,053] [    INFO] - We are using <class 'paddlenlp.transformers.llama.tokenizer.LlamaTokenizer'> to load '/home/aistudio/PaddleNLP/llm/checkpoints/llama_lora_merge'.

In [7]

input_features = tokenizer("医生,我最近总是感觉很沮丧,做什么都提不起兴趣,甚至觉得生活没有意义。", return_tensors="pd")
outputs = model.generate(**input_features, max_length=128)
tokenizer.batch_decode(outputs[0])
[2024-06-12 21:49:56,337] [ WARNING] - `max_length` will be deprecated in future releases, use `max_new_tokens` instead.
['\n\n 医生: 我明白你的感受,这种持续的情绪低落可能是抑郁症的症状。首先,请尝试接纳自己的情绪,允许自己有这种感受,这是正常的。然后,我们可以一步步来,先从日常生活中�']

大功告成了!! 为了加快训练速度我选用的数据集比较小,效果不是很好。大家可以再生成一些数据,或者将EmoLLM的数据集再整理一下继续训练。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

新安装的gcc编译出现编译器内部错误

在原本的环境中已经安装gcc了&#xff0c;但是版本比较低&#xff0c;想用新的版本。 重新下载安装gcc源码编译安装 make install安装好之后想用新的gcc来编译 先改下头文件搜索路径&#xff0c;xxxxxx就是安装后的include/c/xxx/这个路径 CPLUS_INCLUDE_PATH xxxxxx:$CPL…

建筑幕墙甲级设计资质:申请条件与评分标准

建筑幕墙甲级设计资质的申请条件与评分标准可以清晰归纳如下&#xff1a; 申请条件 一、企业基本情况 独立企业法人资格&#xff1a;企业需具有独立企业法人资格。注册资本&#xff1a;注册资本不少于300万元人民币。 二、技术人员条件 主要技术负责人或总工程师&#xff…

Nuxt.js 深入浅出:目录结构与文件组织详解

title: Nuxt.js 深入浅出&#xff1a;目录结构与文件组织详解 date: 2024/6/18 updated: 2024/6/18 author: cmdragon excerpt: 摘要&#xff1a;本文详述了Nuxt.js框架中关键目录与配置文件的作用及使用方法&#xff0c;包括布局设定、页面结构管理、插件集成、静态资源处理…

1999-2020年各地级市农村居民人均纯收入数据

1999-2020年各地级市农村居民人均纯收入数据 1、时间&#xff1a;1999-2020年 2、指标&#xff1a;年份、城市、农村居民人均纯收入 3、来源&#xff1a;区域年鉴、各省市年鉴 4、范围&#xff1a;地级市&#xff0c;具体每年城市数量参看下文图片&#xff0c;具体城市名单…

macbook屏幕录制技巧,这2个方法请你收好

在当今数字化时代&#xff0c;屏幕录制成为了一项不可或缺的技能&#xff0c;无论是教学演示、游戏直播&#xff0c;还是软件操作教程&#xff0c;屏幕录制都能帮助我们更直观地传达信息。MacBook作为苹果公司的标志性产品&#xff0c;其屏幕录制功能也备受用户关注。本文将详细…

【小白专用24.6.18】C# SqlSugar:连接数据库实现简单的,增、删、改、查

【小白专用 已验证24.6.18】C# SqlSugar操作MySQL数据库实现增删改查-CSDN博客 通过NuGet包管理器搜索SqlSugar&#xff08;MySql还要安装MySql.Data、Newtonsoft.Json&#xff09;包并安装 SqlSugarClient db new SqlSugarClient(new ConnectionConfig(){ConnectionString …

计数类DP——AcWing 900. 整数划分

计数类DP 定义 计数类DP主要是通过动态规划的方法来计算满足特定条件的方案数、组合数等数量相关的问题。 运用情况 需要计算不同排列、组合或情况的数量。问题具有明显的阶段性&#xff0c;且每个阶段的选择会对后续阶段产生影响。可以通过逐步构建较小规模问题的解来推导…

mumu 模拟器如何模拟指纹识别?

最近在帮朋友解决一些任务时&#xff0c;有些比较复杂的任务需要批量使用模拟器&#xff0c;但是模拟器存在一个缺点&#xff0c;就是缺少很多物理功能&#xff0c;比如说陀螺仪、温度传感器和生物识别模块等等&#xff0c;但是有些任务是需要这些功能的。没有办法&#xff0c;…

vue3-openlayers 使用tianditu,wmts和xyz等source加载天地图切片服务

本篇介绍一下使用vue3-openlayers加载天地图切片&#xff0c;三种方法&#xff1a; 使用tianditu&#xff08;ol-source-tianditu内部实现其实用的wmts&#xff09;使用wmts&#xff08;ol-source-wmts&#xff09;使用xyz&#xff08;ol-source-xyz&#xff09; 1 需求 vue…

为什么动态代理接口中可以不加@Mapper注解

为什么动态代理接口中可以不加Mapper注解 如下图&#xff1a; 我们上面的UserMapper上面没有加Mapper注解&#xff0c;按道理来说UserMapper这个类应该是注入不到IOC容器里面的&#xff0c;但是为什么我们程序的运行效果仍然是正常的呢&#xff1f;这是因为你的启动类上加了m…

zabbix“专家坐诊”第242期问答

问题一 Q&#xff1a;snmp检查用的什么性能啊&#xff1f;设备多了就检测失败&#xff0c;实际是能通的。 A&#xff1a;把大批量请求取消&#xff0c;把异常获取不到的监控项都禁用 Q&#xff1a;是这个吧&#xff0c;显示不一样。 A&#xff1a;什么版本&#xff1f;用的是v3…

ggpicrust2包:简化和直观化微生物功能预测分析

简介 ggpicrust2是一个强大的R语言包&#xff0c;旨在简化和直观化PICRUSt2输出的分析。通过预定义的图表和函数&#xff0c;研究人员可以轻松生成关于微生物功能预测的统计图&#xff0c;并提供丰富的自定义选项。本文将演示如何使用ggpicrust2包进行分析和可视化。 安装ggp…

VBA学习(9):按指定名单一键删除工作表

今天继续给大家聊VBA编程中工作表对象的常用操作&#xff0c;主要内容是如何批量删除工作表&#xff1b;也就是删除单个工作表、删除全部工作表和删除指定名单内的工作表。 1.删除单个工作表 删除工作表需要使用到工作表对象的delete方法&#xff0c;语法格式如下&#xff1a…

Python单行代码:一招鲜,吃遍天

大家好&#xff0c;在Python编程中&#xff0c;我们时常需要高效、简洁的代码来解决复杂的问题。今天&#xff0c;我将向大家介绍10个非常有用的Python单行代码。 一行代码指的是将复杂的任务浓缩在一行代码中完成。它充分利用Python的简洁和强大&#xff0c;使代码更简洁、更…

智能穿梭,无缝连接:迈威通信助力AGV智慧物流系统高效运转

随着智能制造模式的兴起&#xff0c;在工业4.0和“中国制造2025”的推动下&#xff0c;智能物流迎来了重大的发展机遇。AGV作为智慧仓储物流系统的“关键角色”之一&#xff0c;通过联系、调节离散型物流管理系统&#xff0c;使各环节有效地衔接起来&#xff0c;实现全厂物流运…

git使用摘樱桃的方式,实现特定需求进行提交合并

文章目录 先checkOut到主要的分支(需求提交到这) 然后双击点别的需求分支,对提交内容选定 进行摘樱桃操作 然后双击回到主要分支,会发现那2个提交内容代码已经在主要分支的本地里,选中其 右键选择Squash Commits进行合并 标注自己的需求标题提交名更改后, 最后进行push推送到…

grafana连接influxdb2.x做数据大盘

连接influxdb 展示数据 新建仪表盘 选择存储库 设置展示

【嵌入式】SD NAND:SD卡的集成与优化

嵌入式SD卡&#xff0c;也称为SD NAND或贴片式SD卡&#xff0c;是一种专为空间受限的设备设计的存储解决方案。这种存储卡与传统的SD卡不同&#xff0c;它采用贴片式封装&#xff0c;可以直接焊接到设备的PCB上&#xff0c;从而为电子设备提供内置存储功能。以下是嵌入式SD卡的…

Google 新 AI 为视频生成配乐和对白;Runway 发布 Gen-3 视频生成模型丨 RTE 开发者日报 Vol.226

开发者朋友们大家好&#xff1a; 这里是 「RTE 开发者日报」 &#xff0c;每天和大家一起看新闻、聊八卦。我们的社区编辑团队会整理分享 RTE&#xff08;Real-Time Engagement&#xff09; 领域内「有话题的新闻」、「有态度的观点」、「有意思的数据」、「有思考的文章」、「…

python+selenium之点击元素报错:‘NoneType‘ object has no attribute ‘click‘

今日遇到一个很奇怪的问题 case1:当使用顺序结构直接从登录到点击页面菜单&#xff0c;则可以正常点击菜单 case2&#xff1a;若把登录分离开&#xff0c;采用封装的方法点击菜单则会提示&#xff1a;‘NoneType’ object has no attribute ‘click’ 具体页面如下&#xff0c…