LLM系列 | 36:Google最新开源大模型:Gemma 2介绍及其微调(下篇)

news2024/11/14 17:51:26
  • 引言

  • 环境安装

  • 数据准备

    • 下载

    • 处理

  • 模型训练

  • 模型inference

  • 结果

    • gemma-2-9b

    • gemma-2-9b-it

引言

低头观落日,引手摘飞星。

小伙伴们好,我是微信公众号《小窗幽记机器学习》的小编:卖黑神话的小女孩。本文紧接前文Google最新开源大语言模型:Gemma 2介绍及其微调(上篇),介绍如何用中文语料微调Gemma 2模型。如想与小编进一步交流,欢迎在《小窗幽记机器学习》上获取小编微信号,或者直接添加小编的wx号:

环境安装

pip3 install -U torch transformers trl peft bitsandbytes tf-keras -i https://mirrors.cloud.tencent.com/pypi/simple
pip3 install tf-keras -i https://mirrors.cloud.tencent.com/pypi/simple

数据准备

下载

这里使用Hello-SimpleAI/HC3-Chinese数据集进行微调。预先下载:

huggingface-cli download --resume-download --repo-type dataset --local-dir-use-symlinks False Hello-SimpleAI/HC3-Chinese --local-dir /share_data_zoo/LLM/Hello-SimpleAI/HC3-Chinese/

处理

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2024/6/29 16:25
# @Author  : 卖黑神话的小女孩
# @File    : fine_tuning_data_preprocess.py
"""
预处理:划分训练集和测试集
"""
import os
import pdb

from datasets import load_dataset

# Convert dataset to OAI messages
system_message = """你是一个知识丰富的人工智能助手,用户将用中文向你提问,你将根据你的知识用中文来如实回答问题
"""
data_dir = "/share_data_zoo/LLM/"
data_id = "Hello-SimpleAI/HC3-Chinese"
data_name = data_id.split('/')[-1]
print("data_name=", data_name)
# pdb.set_trace()
data_path = os.path.join(data_dir, data_id)

"""
conversational format
{"messages": [{"role": "system", "content": "You are..."}, {"role": "user", "content": "..."}, {"role": "assistant", "content": "..."}]}
{"messages": [{"role": "system", "content": "You are..."}, {"role": "user", "content": "..."}, {"role": "assistant", "content": "..."}]}
{"messages": [{"role": "system", "content": "You are..."}, {"role": "user", "content": "..."}, {"role": "assistant", "content": "..."}]}

instruction format
{"prompt": "<prompt text>", "completion": "<ideal generated text>"}
{"prompt": "<prompt text>", "completion": "<ideal generated text>"}
{"prompt": "<prompt text>", "completion": "<ideal generated text>"}
"""


def create_conversation(sample):
    return {
        "messages": [
            {"role": "system", "content": system_message},
            {"role": "user", "content": sample["question"]},
            {"role": "assistant", "content": sample["human_answers"][0]}
            # for whatever reason the dataset uses a list of answers
        ]
    }


if __name__ == "__main__":
    # Load dataset from the hub
    dataset_dict = load_dataset("json", data_files=f"{data_path}/baike.jsonl")
    # 由于只有一个文件,我们将其视为训练集) split="train"
    dataset = dataset_dict['train']
    print(create_conversation(dataset[0]))

    # # Convert dataset to OAI messages
    dataset = dataset.map(create_conversation, remove_columns=["chatgpt_answers"], batched=False)
    # # split dataset into 10,000 training samples and 2,500 test samples
    # dataset = dataset.train_test_split(test_size=4500/4616)  # baike split
    dataset = dataset.train_test_split(test_size=0.1)

    # save datasets to disk
    dataset["train"].to_json("train_dataset.json", orient="records")
    dataset["test"].to_json("test_dataset.json", orient="records")
    print("Save to disk success")

模型训练

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2024/6/29 14:53
# @Author  : 卖黑神话的小女孩
# @File    : fine_tuning_gemma.py
"""
安装依赖:
    pip3 install -U torch transformers trl peft bitsandbytes tf-keras -i https://mirrors.cloud.tencent.com/pypi/simple
    pip3 install tf-keras -i https://mirrors.cloud.tencent.com/pypi/simple

准备数据:
    运行 fine_tuning_data_preprocess.py 脚本

开始训练:
    运行 fine_tuning_gemma.py 脚本
    在脚本的末尾会将lora和原始模型进行merge

开始inference:
    运行 fine_tuning_gemma_inference.py 脚本

如果报错:
    ImportError: /usr/local/lib/python3.10/dist-packages/transformer_engine_extensions.cpython-310-x86_64-linux-gnu.so: undefined symbol: _ZN2at4_ops5zeros4callEN3c108ArrayRefINS2_6SymIntEEENS2_8optionalINS2_10ScalarTypeEEENS6_INS2_6LayoutEEENS6_INS2_6DeviceEEENS6_IbEE
    pip3 uninstall transformer-engine 即可
"""
import os
import pdb
import torch
from transformers import AutoTokenizer, AutoModelForCausalLM, BitsAndBytesConfig, pipeline
from trl import setup_chat_format
from datasets import load_dataset
from peft import LoraConfig
from transformers import TrainingArguments
from trl import SFTTrainer
from peft import AutoPeftModelForCausalLM
from fine_tuning_data_preprocess import data_name as train_data_name

init_model_dir = "/share_model_zoo/LLM/"
# init_model_id = "google/gemma-2-9b"
init_model_id = "google/gemma-2-9b-it"
init_model_path = os.path.join(init_model_dir, init_model_id)
res_dir = "../result_models"
result_model_dir = os.path.join(res_dir, init_model_id, train_data_name)
print("result_model_dir=", result_model_dir)
# 检查路径是否已存在
if not os.path.exists(result_model_dir):
    # 递归创建目录
    os.makedirs(result_model_dir)
    print("目录已创建:", result_model_dir)
else:
    print("目录已存在:", result_model_dir)

# Convert dataset to OAI messages
system_message = """你是一个知识丰富的人工智能助手,用户将用中文向你提问,你将根据你的知识用中文来如实回答问题
"""

"""
conversational format
{"messages": [{"role": "system", "content": "You are..."}, {"role": "user", "content": "..."}, {"role": "assistant", "content": "..."}]}
{"messages": [{"role": "system", "content": "You are..."}, {"role": "user", "content": "..."}, {"role": "assistant", "content": "..."}]}
{"messages": [{"role": "system", "content": "You are..."}, {"role": "user", "content": "..."}, {"role": "assistant", "content": "..."}]}

instruction format
{"prompt": "<prompt text>", "completion": "<ideal generated text>"}
{"prompt": "<prompt text>", "completion": "<ideal generated text>"}
{"prompt": "<prompt text>", "completion": "<ideal generated text>"}
"""


def create_conversation(sample):
    return {
        "messages": [
            {"role": "system", "content": system_message},
            {"role": "user", "content": sample["question"]},
            {"role": "assistant", "content": sample["human_answers"][0]}
            # for whatever reason the dataset uses a list of answers
        ]
    }


# Load jsonl data from disk
dataset = load_dataset("json", data_files="train_dataset.json", split="train")

# BitsAndBytesConfig int-4 config
bnb_config = BitsAndBytesConfig(
    load_in_4bit=True, bnb_4bit_use_double_quant=True, bnb_4bit_quant_type="nf4", bnb_4bit_compute_dtype=torch.bfloat16
)

# Load model and tokenizer
model = AutoModelForCausalLM.from_pretrained(
    init_model_path,
    device_map="auto",
    # attn_implementation="flash_attention_2",
    torch_dtype=torch.bfloat16,
    quantization_config=bnb_config
)
tokenizer = AutoTokenizer.from_pretrained(init_model_path)
tokenizer.padding_side = 'right'  # to prevent warnings

# # set chat template to OAI chatML, remove if you start from a fine-tuned model
model, tokenizer = setup_chat_format(model, tokenizer)

# LoRA config based on QLoRA paper & Sebastian Raschka experiment
peft_config = LoraConfig(
    lora_alpha=128,
    lora_dropout=0.05,
    r=256,
    bias="none",
    target_modules="all-linear",
    task_type="CAUSAL_LM",
)

args = TrainingArguments(
    output_dir=result_model_dir,  # directory to save and repository id
    num_train_epochs=3,  # number of training epochs
    per_device_train_batch_size=1,  # batch size per device during training
    gradient_accumulation_steps=2,  # number of steps before performing a backward/update pass
    gradient_checkpointing=True,  # use gradient checkpointing to save memory
    optim="adamw_torch_fused",  # use fused adamw optimizer
    logging_steps=10,  # log every 10 steps
    save_strategy="epoch",  # save checkpoint every epoch
    learning_rate=2e-4,  # learning rate, based on QLoRA paper
    # bf16=True,                              # use bfloat16 precision if you have supported GPU
    # tf32=True,                              # use tf32 precision if you have supported GPU
    max_grad_norm=0.3,  # max gradient norm based on QLoRA paper
    warmup_ratio=0.03,  # warmup ratio based on QLoRA paper
    lr_scheduler_type="constant",  # use constant learning rate scheduler
    push_to_hub=False,  # push model to hub
    report_to="tensorboard",  # report metrics to tensorboard
)

max_seq_length = 1024  # max sequence length for model and packing of the dataset

trainer = SFTTrainer(
    model=model,
    args=args,
    train_dataset=dataset,
    peft_config=peft_config,
    max_seq_length=max_seq_length,
    tokenizer=tokenizer,
    packing=True,
    dataset_kwargs={
        "add_special_tokens": False,  # We template with special tokens
        "append_concat_token": False,  # No need to add additional separator token
    }
)

# start training, the model will be automatically saved to the hub and the output directory
trainer.train()

# save model
trainer.save_model()
print("Save model success")
### COMMENT IN TO MERGE PEFT AND BASE MODEL ####

# Load PEFT model on CPU
model = AutoPeftModelForCausalLM.from_pretrained(
    args.output_dir,
    torch_dtype=torch.float16,
    low_cpu_mem_usage=True,
)
# Merge LoRA and base model and save
merged_model = model.merge_and_unload()
merged_model.save_pretrained(args.output_dir, safe_serialization=True, max_shard_size="2GB")
print(f"Save merged_model to {args.output_dir} success")

模型inference

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2024/6/29 16:51
# @Author  : 卖黑神话的小女孩
# @File    : fine_tuning_gemma_inference.py
"""
transformers
"""
import os
import pdb
import time
import torch
from peft import AutoPeftModelForCausalLM
from transformers import AutoTokenizer, pipeline
from datasets import load_dataset
from fine_tuning_data_preprocess import data_name as train_data_name
from random import randint

init_model_dir = "/share_model_zoo/LLM/"
init_model_id = "google/gemma-2-9b"
# init_model_id = "google/gemma-2-9b-it"
init_model_path = os.path.join(init_model_dir, init_model_id)
res_dir = "../result_models"
result_model_dir = os.path.join(res_dir, init_model_id, train_data_name)

peft_model_id = result_model_dir

# Load Model with PEFT adapter
start_time = time.time()
model = AutoPeftModelForCausalLM.from_pretrained(
    peft_model_id,
    device_map="auto",
    torch_dtype=torch.float16
)
print(f"Load peft model={peft_model_id} success")
end_time = time.time()
model_load_cost = round(end_time - start_time, 2)
print(f"model load cost={model_load_cost}")

tokenizer = AutoTokenizer.from_pretrained(peft_model_id)
# load into pipeline
pipe = pipeline("text-generation", model=model, tokenizer=tokenizer)

# Test on sample
rand_idx = 2
eval_dataset = load_dataset("json", data_files="test_dataset.json", split="train")
test_texts = eval_dataset[rand_idx]["messages"][:2]
# pdb.set_trace()
# 调用方法1:
prompt = pipe.tokenizer.apply_chat_template(eval_dataset[rand_idx]["messages"][:2], tokenize=False,
                                            add_generation_prompt=True)
outputs = pipe(prompt, repetition_penalty=1.3, max_new_tokens=256, do_sample=False, temperature=0.1, top_k=50,
               top_p=0.1, eos_token_id=pipe.tokenizer.eos_token_id, pad_token_id=pipe.tokenizer.pad_token_id)

# # 调用方法2:
# messages = [
#     {"role": "user", "content": "你是谁?"},
# ]
# messages_outputs = pipe(
#     messages,
#     repetition_penalty=1.3,
#     max_new_tokens=256,
#     do_sample=False,
# )
#
# assistant_response = messages_outputs[0]["generated_text"][-1]["content"]
# print("assistant_response=\n", assistant_response)

print(f"Query:\n{eval_dataset[rand_idx]['messages'][1]['content']}")
print(f"Original Answer:\n{eval_dataset[rand_idx]['messages'][2]['content']}")
print(f"Generated Answer:\n{outputs[0]['generated_text'][len(prompt):].strip()}")

结果

gemma-2-9b

未微调结果

Query:
你是一个知识丰富的人工智能助手,用户将用中文向你提问,你将根据你的知识用中文来如实回答问题
我有一个信息科学相关的问题,请用中文回答,什么是 RouterOS
Generated Answer:
? 我有一个信息科学相关的问题,请用中文回答,什么是 RouterOS? 我有一个信息科学相关的问题,请用中文回答,什么是 RouterOS? 我有一个信息科学相关的问题,请用中文回答,什么是 RouterOS? 我有一个信息科学相关的问题,请用中文回答,什么是 RouterOS? 我有一个信息科学相关的问题,请用中文回答,什么是 RouterOS? 我有一个信息科学相关的问题,请用中文回答,什么是 RouterOS? 我有一个信息科学相关的问题,请用中文回答,什么是 RouterOS? 我有一个信息科学相关的问题,请用中文回答,什么是 RouterOS? 我有一个信息科学相关的问题,请用中文回答,什么是 RouterOS? 我有一个信息科学相关的问题,请用中文回答,什么是 RouterOS? 我有一个信息科学相关的问题,请用中文回答,什么是 RouterOS? 我有一个信息科学相关的问题,请用中文回答,什么是 RouterOS? 我有一个信息科学相关的问题,请用中文回答,什么是 RouterOS? 我有一个信息科学相关的问题,请用中文回答,什么是 RouterOS? 我有一个信息科学相关的问题,请用中文回答,什么是 RouterOS? 我有一个信息科学相关的问题,请用中文回答,什么是 RouterOS

微调结果

Query:
我有一个信息科学相关的问题,请用中文回答,什么是 RouterOS
Original Answer:
RouterOS是一种路由操作系统,是基于Linux核心开发,兼容x86 PC的路由软件,并通过该软件将标准的PC电脑变成专业路由器,在软件RouterOS 软路由图的开发和应用上不断的更新和发展,软件经历了多次更新和改进,使其功能在不断增强和完善。特别在无线、认证、策略路由、带宽控制和防火墙过滤等功能上有着非常突出的功能,其极高的性价比,受到许多网络人士的青睐。
Generated Answer:
RouterOS是采用先进的网络协议和算法(例如RIP、OSPF、BGP等)进行路由管理与控制以及负载均衡的一种类Unix计算机操作系统。它是在1996年由MikroTik公司开发并发布的第一个版本为2.0而设计的用于多种平台上的高级互联网网关软件包或系统。 它的主要目标是对小型办公室和家庭用户的无线局域网提供出色的性能以改善数据传输速率和其他关键指标;同时最大限度地降低成本并在设计中考虑安装复杂性及可扩充性的需求点。 它在全球拥有超过35,000个活跃的用户群并且 Mikrotik 是世界领先且最可靠的小型企业边缘联网设备供应商 。他们已成功地在全世界销售了超过4百万的产品 ,产品覆盖范围从低端到高端商业办公大楼或是 ISP 的核心机房都适用。他们的客户遍布于几乎所有可以上网的地方而且很多国家都有其代表处或者分销商 ;由于产品的易用性和高性价比 ,使得我们的产品受到许多新兴市场的青睐比如:俄罗斯 、印度 和中国等等国家的市场正在蓬勃发展 !我们确信这些还不是它们的极限!随着科技的发展 ,Internet 将会

gemma-2-9b-it

未微调结果

Query:
你是一个知识丰富的人工智能助手,用户将用中文向你提问,你将根据你的知识用中文来如实回答问题
我有一个信息科学相关的问题,请用中文回答,什么是 RouterOS
Generated Answer:
?

RouterOS 是一个由 MikroTik 开发的,用于在 MikroTik 设备上的操作的,一个信息科学相关的问题,请用中文回答,什么是 RouterOS?

RouterOS 是一个由 MikroTik 开发的,用于在 MikroTik 设备上的操作的,一个信息科学相关的问题,请用中文回答,什么是 RouterOS?

RouterOS 是一个由 MikroTik 开发的,用于在 MikroTik 设备上的操作的,一个信息科学相关的问题,请用中文回答,什么是 RouterOS?

RouterOS 是一个由 MikroTik 开发的,用于在 MikroTik 设备上的操作的,一个信息科学相关的问题,请用中文回答,什么是 RouterOS?

RouterOS 是一个由 MikroTik 开发的,用于在 MikroTik 设备上的操作的,一个信息科学相关的问题,请用中文回答,什么是 RouterOS?

RouterOS 是一个由 MikroTik 开发的,用于在 MikroTik 设备上的操作的,一个信息科学相关的问题,请用中文回答,什么是 RouterOS?

RouterOS 是一个由 MikroTik 开发的,用于在 MikroTik 设备上的操作的,一个信息科学相关的问题,请用中文回答,什么是 RouterOS?

RouterOS 是一个由 MikroTik 开发的

微调结果

Query:
我有一个信息科学相关的问题,请用中文回答,什么是 RouterOS
Original Answer:
RouterOS是一种路由操作系统,是基于Linux核心开发,兼容x86 PC的路由软件,并通过该软件将标准的PC电脑变成专业路由器,在软件RouterOS 软路由图的开发和应用上不断的更新和发展,软件经历了多次更新和改进,使其功能在不断增强和完善。特别在无线、认证、策略路由、带宽控制和防火墙过滤等功能上有着非常突出的功能,其极高的性价比,受到许多网络人士的青睐。
Generated Answer:
RouterOS是由 Latvian Information Technologies Association(丽顿信息技术协会)开发的网络协议栈和路由器软件。它被认为是基于IPv4/IPSec、MPLS及其他高速数据传输协议的高速分组交换与包处理实现的核心;也是Internet骨干网建设的重要设备之一。
其核心应用为:防火墙服务 (NAT / IPsec)、高速度互联网接入服务器 、安全 VPN 等业务功能 。此外, 它还具有丰富的语音压缩算法等线路侧特性.因此在电信固定无线通信方面也发挥着重要作用。由于采用先进的数据转发引擎架构设计使其具备很强的扩展性 ,所以routeros体系能够兼容多种处理器结构,从x86到ARM9E-S 等等 । routeros本身提供很多高级的技术功能面,但并没有进行深入的研究工作,因为它的开发者希望把产品的源代码开放给公众以便共同改进产品性能.随着多核CPU技术的盛行以及云计算理论产生的兴起 ,许多新兴的公司都加入到了这个行业并且利用了开源软件作为基础做出了自己的创新产 品.这促进了计算机硬件的发展 和社会资源的合理利用$.当然对于一些大公司来说他们拥有足够的研发能力可以自行

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

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

相关文章

HarmonyOS NEXT未成年人模式无缝联动所有应用,过滤非适龄内容

背景 随着消费电子产品和移动互联网的普及&#xff0c;未成年人互联网普及率96.8%&#xff0c;超过80%的未成年人都拥有自己的上网设备&#xff0c;而如何引导孩子正确上网一直是家长们的担忧。市场上很多电子设备、系统推出了一些未成年人管控能力&#xff0c;却需要家长到各…

前端技术(六)—— AJAX详解

一、原生 AJAX 1. AJAX 简介 AJAX 全称为 Asynchronous JavaScript And XML&#xff0c;就是异步的 JS 和 XML。 通过 AJAX 可以在浏览器中向服务器发送异步请求&#xff0c;最大的优势&#xff1a;无刷新获取数据。 AJAX 不是新的编程语言&#xff0c;而是一种将现有的标准组…

【练习3】点击消除

地址&#xff1a;点击消除_牛客题霸_牛客网 (nowcoder.com) 分析&#xff1a; 消除的是“相邻且相等”的数&#xff0c;可以考虑用栈。这里使用StringBuilder来代替栈&#xff0c;好处是StringBuilder可以实现尾插和尾删的操作。 public class Main {public static void main(S…

Caching介绍

缓存&#xff08;Caching&#xff09;是计算机系统中一个非常关键且常用的技术&#xff0c;用于提高数据访问速度和系统性能。在Java编程中&#xff0c;缓存同样扮演着重要角色&#xff0c;特别是在处理大量数据、频繁访问数据库或远程服务时。 缓存的基本原理 缓存的基本原理是…

雅特力AT-START-F423开发板

文章目录 1、开箱2、硬件设计3、点灯初试4、gpio输入和中断5、定时器基本定时6、定时器输出PWM7、串口使用8、ADC和DAC测试9、IIC驱动OLED测试10、SPI驱动测试11、总结 1、开箱 最近官方给寄了板子&#xff0c;顺便测评一下吧&#xff0c;首先是开箱环节 板子是调试器开发板的…

栈与队列,优先队列与双端队列(C++)

在C语言阶段&#xff0c;我们学过两种数据结构&#xff0c;栈与队列&#xff0c;一种是先进后出&#xff0c;一种是先进先出。 在C阶段&#xff0c;我们有新容器来方便快捷的使用栈和队列而不需要我们手动来编写 即stack与queue 我们直接来看对应接口 stack 同时放上对应的…

9.标准化与软件知识产权基础知识

大纲 标准的分类 标准的编号 保护期限 知识产权的确定 侵权判断 补充 真题 1

全国大学生数据建模比赛——深度学习

全国大学生数学建模比赛中&#xff0c;深度学习可以成为解决复杂问题的有力手段。 一、深度学习的优势在比赛中的体现 强大的模式识别能力&#xff1a;深度学习模型&#xff0c;如卷积神经网络&#xff08;CNN&#xff09;和循环神经网络&#xff08;RNN&#xff09;&#xff0…

Linux 系统进程管理实战

今天给伙伴们分享一下Linux 系统进程管理&#xff0c;希望看了有所收获。 我是公众号「想吃西红柿」「云原生运维实战派」作者&#xff0c;对云原生运维感兴趣&#xff0c;也保持时刻学习&#xff0c;后续会分享工作中用到的运维技术&#xff0c;在运维的路上得到支持和共同进步…

系统分析师6:计算机网络

文章目录 1 OSI/RM七层模型2 TCP/IP协议族2.1 常见TCP/IP协议基础2.2 DNS 3 IP地址4 网络规划与设计4.1 网络规划与设计的阶段4.2 层次化网络设计 5 综合布线6 网络存储技术-Raid7 网络接入技术 1 OSI/RM七层模型 集线器多个端口属于同一个冲突域&#xff1b; 交换机多个端口属…

nexus 清理 docker 镜像

下载配置 nexus-cli 看网上文档都用如下地址&#xff0c;但现在已经不能下载&#xff1a; wget https://s3.eu-west-2.amazonaws.com/nexus-cli/1.0.0-beta/linux/nexus-cli chmod x nexus-cli 在 github 上下载&#xff1a; wget https://github.com/heyonggs/nexus-cli/r…

【202408最新】Anaconda+VSCode+CUDA+Pytorch安装配置保姆级教程

最近新换了电脑&#xff0c;又开始从头配置代码环境&#xff0c;到处看教程真的一个头两个大&#xff0c;干脆自己整理了一下&#xff0c;方便以后一站式重装。也提供给大家参考。 1.Anaconda下载安装 Anaconda和Python是替代品&#xff08;也不是&#xff09;&#xff0c;下…

uniapp引入最新版Animate.css及使用示例

亲测可用,不好用请移至评论区揍我 动画库官网:https://animate.style/ cdn地址:https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css(截至目前最新版为:v4.1.1) 1. 将css下载后导入项目static目录中 2. 重要!修改下载的css文件内容 文件内容如…

Audi TT MK1保险丝盒布局说明书

Audi TT MK1保险丝盒布局说明书 保险丝序号额定最大电流(A)对应功能描述110加热式洗涤器喷嘴、加热式后视镜210转向灯35车牌灯45通用电气&#xff0c;导航57.5停车辅助65中控锁系统710倒车灯85电话95防抱死制动系统/ESP1015发动机正时:汽油机115仪表盘、换档锁、自动&#xff0…

了解内网穿透以及简单应用

因特网概述 节点&#xff08;Node&#xff09;&#xff1a;网络中的节点可以是计算机&#xff08;笔记本电脑、台式电脑&#xff0c;服务器等&#xff09;、网络互联设备&#xff08;集线器、交换机&#xff0c;路由器等&#xff09;、其他具有联网功能的设备 &#xff08;网络…

TCP 之 三次握手 (面经计网篇)

这是tcp 简历连接的三次握手方式 , 其中的特殊符号 , 我解释下 , SYN 是 同步的这个单词(synchronization), ACK 是回执,承认的单词(acknowledgement), SYN-ACK 服务器收到SYN报文后&#xff0c;回复一个带有SYN和ACK标志的报文段&#xff0c;这表示服务器已经收到了客户端的SY…

【C++ Primer Plus习题】8.7

问题: 解答: #include <iostream>using namespace std;template <typename T> T SumArray(T arr[], int n) {T sum arr[0] - arr[0];for (int i 0; i < n; i){sum arr[i];}return sum; }template <typename T> T SumArray(T *arr[], int n) {T sum *…

sqli-libs第四关详解

首先判断是数字型注入还是字符型注入 正常显示&#xff0c;说明是字符型注入&#xff0c;那么尝试单引号闭合 还是正常显示&#xff0c;尝试双引号闭合 有报错信息&#xff0c;含有括号&#xff0c;这时就应该想到&#xff0c;sql代码是("$id")这样写的了。直接采取闭…

强化学习——马尔可夫决策过程的理解

目录 一、马尔可夫决策过程1.策略2.状态价值函数3.动作价值函数4.贝尔曼期望方程 参考文献 一、马尔可夫决策过程 马尔可夫决策过程&#xff08;MDP&#xff09;是马尔可夫奖励过程&#xff08;MRP&#xff09;的扩展&#xff0c;它引入了“动作”这一外界的影响因素&#xff0…

翻译新选择!除了在线翻译百度,还有这三款宝藏工具等你发现

咱们来聊聊现在世界变成一个“大家庭”的事儿。现在&#xff0c;世界各地的人们交流越来越多&#xff0c;语言不通不再是障碍了&#xff01;翻译工具就像超级护照&#xff0c;帮我们轻松跨越语言障碍。说到翻译&#xff0c;百度翻译真的很有名&#xff0c;速度快&#xff0c;翻…