Transformers实战——文本相似度

文章目录

  • 一、改写文本分类
    • 1.导入相关包
    • 2.加载数据集
    • 3.划分数据集
    • 4.数据集预处理
    • 5.创建模型
    • 6.创建评估函数
    • 7.创建 TrainingArguments
    • 8.创建 Trainer
    • 9.模型训练
    • 10.模型评估
    • 11.模型预测
  • 二、交互/单塔模式
    • 1.导入相关包
    • 2.加载数据集
    • 3.划分数据集
    • 4.数据集预处理
    • 5.创建模型(区别)
    • 6.创建评估函数(区别)
    • 7.创建 TrainingArguments
    • 8.创建 Trainer
    • 9.模型训练
    • 10.模型评估
    • 11.模型预测(区别)

!pip install transformers datasets evaluate accelerate 

一、改写文本分类

1.导入相关包

from transformers import AutoTokenizer, AutoModelForSequenceClassification, Trainer, TrainingArguments
from datasets import load_dataset

2.加载数据集

dataset = load_dataset("json", data_files="./train_pair_1w.json", split="train")
dataset
'''
Dataset({
    features: ['sentence1', 'sentence2', 'label'],
    num_rows: 10000
})
'''
dataset[:3]
'''
{'sentence1': ['找一部小时候的动画片',
  '我不可能是一个有鉴赏能力的行家,小姐我把我的时间都花在书写上;象这样豪华的舞会,我还是头一次见到。',
  '胡子长得太快怎么办?'],
 'sentence2': ['求一部小时候的动画片。谢了', '蜡烛没熄就好了,夜黑得瘆人,情绪压抑。', '胡子长得快怎么办?'],
 'label': ['1', '0', '1']}
'''

3.划分数据集

datasets = dataset.train_test_split(test_size=0.2, seed=3407)
datasets['train']['sentence1'][0]
'''
王琦瑶说:你家阿大二十岁已经有儿有女了嘛
'''

4.数据集预处理

import torch

tokenizer = AutoTokenizer.from_pretrained("hfl/chinese-macbert-base")

def process_function(examples):
    tokenized_examples = tokenizer(examples["sentence1"], examples["sentence2"], max_length=128, truncation=True)
    tokenized_examples["labels"] = [int(label) for label in examples["label"]]
    return tokenized_examples

tokenized_datasets = datasets.map(process_function, batched=True, remove_columns=datasets["train"].column_names)
tokenized_datasets
'''
DatasetDict({
    train: Dataset({
        features: ['input_ids', 'token_type_ids', 'attention_mask', 'labels'],
        num_rows: 8000
    })
    test: Dataset({
        features: ['input_ids', 'token_type_ids', 'attention_mask', 'labels'],
        num_rows: 2000
    })
})
'''

5.创建模型

from transformers import BertForSequenceClassification 
model = AutoModelForSequenceClassification.from_pretrained("hfl/chinese-macbert-base", num_labels=2)

6.创建评估函数

import evaluate

acc_metric = evaluate.load("accuracy")
f1_metirc = evaluate.load("f1")
def eval_metric(eval_predict):
    predictions, labels = eval_predict
    labels = [int(l) for l in labels]
    predictions = predictions.argmax(axis=-1)
    acc = acc_metric.compute(predictions=predictions, references=labels)
    f1 = f1_metirc.compute(predictions=predictions, references=labels)
    acc.update(f1)
    return acc

7.创建 TrainingArguments

train_args = TrainingArguments(output_dir="./cross_model",      # 输出文件夹
                               per_device_train_batch_size=32,  # 训练时的batch_size
                               per_device_eval_batch_size=32,  # 验证时的batch_size
                               logging_steps=10,                # log 打印的频率
                               evaluation_strategy="epoch",     # 评估策略
                               save_strategy="epoch",           # 保存策略
                               save_total_limit=3,              # 最大保存数
                               learning_rate=2e-5,              # 学习率
                               weight_decay=0.01,               # weight_decay
                               metric_for_best_model="f1",      # 设定评估指标
                               load_best_model_at_end=True)     # 训练完成后加载最优模型
train_args
'''
TrainingArguments(
_n_gpu=1,
adafactor=False,
adam_beta1=0.9,
adam_beta2=0.999,
adam_epsilon=1e-08,
auto_find_batch_size=False,
bf16=False,
bf16_full_eval=False,
data_seed=None,
dataloader_drop_last=False,
dataloader_num_workers=0,
dataloader_pin_memory=True,
ddp_backend=None,
ddp_broadcast_buffers=None,
ddp_bucket_cap_mb=None,
ddp_find_unused_parameters=None,
ddp_timeout=1800,
debug=[],
deepspeed=None,
disable_tqdm=False,
dispatch_batches=None,
do_eval=True,
do_predict=False,
do_train=False,
eval_accumulation_steps=None,
eval_delay=0,
eval_steps=None,
evaluation_strategy=epoch,
fp16=False,
fp16_backend=auto,
fp16_full_eval=False,
fp16_opt_level=O1,
fsdp=[],
fsdp_config={'min_num_params': 0, 'xla': False, 'xla_fsdp_grad_ckpt': False},
fsdp_min_num_params=0,
fsdp_transformer_layer_cls_to_wrap=None,
full_determinism=False,
gradient_accumulation_steps=1,
gradient_checkpointing=False,
gradient_checkpointing_kwargs=None,
greater_is_better=True,
group_by_length=False,
half_precision_backend=auto,
hub_always_push=False,
hub_model_id=None,
hub_private_repo=False,
hub_strategy=every_save,
hub_token=<HUB_TOKEN>,
ignore_data_skip=False,
include_inputs_for_metrics=False,
include_tokens_per_second=False,
jit_mode_eval=False,
label_names=None,
label_smoothing_factor=0.0,
learning_rate=2e-05,
length_column_name=length,
load_best_model_at_end=True,
local_rank=0,
log_level=passive,
log_level_replica=warning,
log_on_each_node=True,
logging_dir=./cross_model/runs/Nov27_07-11-23_66feef283143,
logging_first_step=False,
logging_nan_inf_filter=True,
logging_steps=10,
logging_strategy=steps,
lr_scheduler_type=linear,
max_grad_norm=1.0,
max_steps=-1,
metric_for_best_model=f1,
mp_parameters=,
neftune_noise_alpha=None,
no_cuda=False,
num_train_epochs=3.0,
optim=adamw_torch,
optim_args=None,
output_dir=./cross_model,
overwrite_output_dir=False,
past_index=-1,
per_device_eval_batch_size=32,
per_device_train_batch_size=32,
prediction_loss_only=False,
push_to_hub=False,
push_to_hub_model_id=None,
push_to_hub_organization=None,
push_to_hub_token=<PUSH_TO_HUB_TOKEN>,
ray_scope=last,
remove_unused_columns=True,
report_to=['tensorboard'],
resume_from_checkpoint=None,
run_name=./cross_model,
save_on_each_node=False,
save_safetensors=True,
save_steps=500,
save_strategy=epoch,
save_total_limit=3,
seed=42,
skip_memory_metrics=True,
split_batches=False,
tf32=None,
torch_compile=False,
torch_compile_backend=None,
torch_compile_mode=None,
torchdynamo=None,
tpu_metrics_debug=False,
tpu_num_cores=None,
use_cpu=False,
use_ipex=False,
use_legacy_prediction_loop=False,
use_mps_device=False,
warmup_ratio=0.0,
warmup_steps=0,
weight_decay=0.01,
)
'''

8.创建 Trainer

from transformers import DataCollatorWithPadding
trainer = Trainer(model=model, 
                  args=train_args, 
                  train_dataset=tokenized_datasets["train"], 
                  eval_dataset=tokenized_datasets["test"], 
                  data_collator=DataCollatorWithPadding(tokenizer=tokenizer),
                  compute_metrics=eval_metric)

9.模型训练

trainer.train()

10.模型评估

trainer.evaluate(tokenized_datasets["test"])

11.模型预测

from transformers import pipeline, TextClassificationPipeline

model.config.id2label = {0: "不相似", 1: "相似"}
pipe = pipeline("text-classification", model=model, tokenizer=tokenizer, device=0)

result = pipe({"text": "我喜欢北京", "text_pair": "天气"})
result["label"] = "相似" if result["score"] > 0.5 else "不相似"
result
'''
{'label': '不相似', 'score': 0.8792306780815125}
'''

result = pipe({"text": "我喜欢北京", "text_pair": "我喜欢北京"})
result
'''
{'label': '相似', 'score': 0.9374899864196777}
'''

二、交互/单塔模式

  • label 设为 1,代表两个句子的相似度分数,通过设置阈值来判断类别
  • 对于同一个句子 A,存在若干候选句子,要找到与句子 A 最相似的某个候选句子(上述文本分类处理方式无法解决),此处将分类任务作为回归任务+阈值的方式进行处理,从而能够得到预测的得分,该得分可以用来判断 哪个候选句子与给定句子最相似

1.导入相关包

from transformers import AutoTokenizer, AutoModelForSequenceClassification, Trainer, TrainingArguments
from datasets import load_dataset

2.加载数据集

dataset = load_dataset("json", data_files="./train_pair_1w.json", split="train")
dataset
'''
Dataset({
    features: ['sentence1', 'sentence2', 'label'],
    num_rows: 10000
})
'''
dataset[:3]
'''
{'sentence1': ['找一部小时候的动画片',
  '我不可能是一个有鉴赏能力的行家,小姐我把我的时间都花在书写上;象这样豪华的舞会,我还是头一次见到。',
  '胡子长得太快怎么办?'],
 'sentence2': ['求一部小时候的动画片。谢了', '蜡烛没熄就好了,夜黑得瘆人,情绪压抑。', '胡子长得快怎么办?'],
 'label': ['1', '0', '1']}
'''

3.划分数据集

  • 注意这里有种子参数
datasets = dataset.train_test_split(test_size=0.2, seed=3407)
datasets['train']['sentence1'][0]
'''
王琦瑶说:你家阿大二十岁已经有儿有女了嘛
'''

4.数据集预处理

import torch

tokenizer = AutoTokenizer.from_pretrained("hfl/chinese-macbert-base")

def process_function(examples):
    tokenized_examples = tokenizer(examples["sentence1"], examples["sentence2"], max_length=128, truncation=True)
    
    # 这里float(label)的原因是要做MSE,需要float类型的数据
    tokenized_examples["labels"] = [float(label) for label in examples["label"]]
    
    return tokenized_examples

tokenized_datasets = datasets.map(process_function, batched=True, remove_columns=datasets["train"].column_names)

tokenized_datasets
'''
DatasetDict({
    train: Dataset({
        features: ['input_ids', 'token_type_ids', 'attention_mask', 'labels'],
        num_rows: 8000
    })
    test: Dataset({
        features: ['input_ids', 'token_type_ids', 'attention_mask', 'labels'],
        num_rows: 2000
    })
}
'''
print(tokenized_datasets["train"][0])
'''
{'input_ids': [101, 4374, 4425, 4457, 6432, 131, 872, 2157, 7350, 1920, 753, 1282, 2259, 2347, 5307, 3300, 1036, 3300, 1957, 749, 1658, 102, 7350, 1920, 1372, 3300, 1036, 2094, 3766, 3300, 1957, 1036, 102], 
'token_type_ids': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], 
'attention_mask': [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], 
'labels': 0.0}
'''

5.创建模型(区别)

from transformers import BertForSequenceClassification 

model = AutoModelForSequenceClassification.from_pretrained("hfl/chinese-macbert-base", num_labels=1)

6.创建评估函数(区别)

import evaluate

acc_metric = evaluate.load("accuracy")
f1_metirc = evaluate.load("f1")
def eval_metric(eval_predict):
    predictions, labels = eval_predict
    predictions = [int(p > 0.5) for p in predictions]
    labels = [int(l) for l in labels]
    # predictions = predictions.argmax(axis=-1)
    acc = acc_metric.compute(predictions=predictions, references=labels)
    f1 = f1_metirc.compute(predictions=predictions, references=labels)
    acc.update(f1)
    return acc

7.创建 TrainingArguments

train_args = TrainingArguments(output_dir="./cross_model",      # 输出文件夹
                               per_device_train_batch_size=32,  # 训练时的batch_size
                               per_device_eval_batch_size=32,   # 验证时的batch_size
                               logging_steps=10,                # log 打印的频率
                               evaluation_strategy="epoch",     # 评估策略
                               save_strategy="epoch",           # 保存策略
                               save_total_limit=3,              # 最大保存数
                               learning_rate=2e-5,              # 学习率
                               weight_decay=0.01,               # weight_decay
                               metric_for_best_model="f1",      # 设定评估指标
                               load_best_model_at_end=True)     # 训练完成后加载最优模型

train_args
'''
TrainingArguments(
_n_gpu=1,
adafactor=False,
adam_beta1=0.9,
adam_beta2=0.999,
adam_epsilon=1e-08,
auto_find_batch_size=False,
bf16=False,
bf16_full_eval=False,
data_seed=None,
dataloader_drop_last=False,
dataloader_num_workers=0,
dataloader_pin_memory=True,
ddp_backend=None,
ddp_broadcast_buffers=None,
ddp_bucket_cap_mb=None,
ddp_find_unused_parameters=None,
ddp_timeout=1800,
debug=[],
deepspeed=None,
disable_tqdm=False,
dispatch_batches=None,
do_eval=True,
do_predict=False,
do_train=False,
eval_accumulation_steps=None,
eval_delay=0,
eval_steps=None,
evaluation_strategy=epoch,
fp16=False,
fp16_backend=auto,
fp16_full_eval=False,
fp16_opt_level=O1,
fsdp=[],
fsdp_config={'min_num_params': 0, 'xla': False, 'xla_fsdp_grad_ckpt': False},
fsdp_min_num_params=0,
fsdp_transformer_layer_cls_to_wrap=None,
full_determinism=False,
gradient_accumulation_steps=1,
gradient_checkpointing=False,
gradient_checkpointing_kwargs=None,
greater_is_better=True,
group_by_length=False,
half_precision_backend=auto,
hub_always_push=False,
hub_model_id=None,
hub_private_repo=False,
hub_strategy=every_save,
hub_token=<HUB_TOKEN>,
ignore_data_skip=False,
include_inputs_for_metrics=False,
include_tokens_per_second=False,
jit_mode_eval=False,
label_names=None,
label_smoothing_factor=0.0,
learning_rate=2e-05,
length_column_name=length,
load_best_model_at_end=True,
local_rank=0,
log_level=passive,
log_level_replica=warning,
log_on_each_node=True,
logging_dir=./cross_model/runs/Nov27_06-35-36_66feef283143,
logging_first_step=False,
logging_nan_inf_filter=True,
logging_steps=10,
logging_strategy=steps,
lr_scheduler_type=linear,
max_grad_norm=1.0,
max_steps=-1,
metric_for_best_model=f1,
mp_parameters=,
neftune_noise_alpha=None,
no_cuda=False,
num_train_epochs=3.0,
optim=adamw_torch,
optim_args=None,
output_dir=./cross_model,
overwrite_output_dir=False,
past_index=-1,
per_device_eval_batch_size=32,
per_device_train_batch_size=32,
prediction_loss_only=False,
push_to_hub=False,
push_to_hub_model_id=None,
push_to_hub_organization=None,
push_to_hub_token=<PUSH_TO_HUB_TOKEN>,
ray_scope=last,
remove_unused_columns=True,
report_to=['tensorboard'],
resume_from_checkpoint=None,
run_name=./cross_model,
save_on_each_node=False,
save_safetensors=True,
save_steps=500,
save_strategy=epoch,
save_total_limit=3,
seed=42,
skip_memory_metrics=True,
split_batches=False,
tf32=None,
torch_compile=False,
torch_compile_backend=None,
torch_compile_mode=None,
torchdynamo=None,
tpu_metrics_debug=False,
tpu_num_cores=None,
use_cpu=False,
use_ipex=False,
use_legacy_prediction_loop=False,
use_mps_device=False,
warmup_ratio=0.0,
warmup_steps=0,
weight_decay=0.01,
)
'''

8.创建 Trainer

from transformers import DataCollatorWithPadding
trainer = Trainer(model=model, 
                  args=train_args, 
                  train_dataset=tokenized_datasets["train"], 
                  eval_dataset=tokenized_datasets["test"], 
                  data_collator=DataCollatorWithPadding(tokenizer=tokenizer),
                  compute_metrics=eval_metric)

9.模型训练

trainer.train()
'''
TrainOutput(global_step=750, training_loss=0.09012470634778341, metrics={'train_runtime': 558.2367, 'train_samples_per_second': 42.993, 'train_steps_per_second': 1.344, 'total_flos': 1552456398705984.0, 'train_loss': 0.09012470634778341, 'epoch': 3.0})
'''

image.png


10.模型评估

trainer.evaluate(tokenized_datasets["test"])
'''
{'eval_loss': 0.06814368069171906,
 'eval_accuracy': 0.9095,
 'eval_f1': 0.8840486867392696,
 'eval_runtime': 14.6336,
 'eval_samples_per_second': 136.672,
 'eval_steps_per_second': 4.305,
 'epoch': 3.0}
'''

11.模型预测(区别)

from transformers import pipeline, TextClassificationPipeline

model.config.id2label = {0: "不相似", 1: "相似"}

pipe = pipeline("text-classification", model=model, tokenizer=tokenizer, device=0)

# function_to_apply="none" 应对softmax / sigmoid处理
result = pipe({"text": "我喜欢北京", "text_pair": "天气怎样"}, function_to_apply="none")
result["label"] = "相似" if result["score"] > 0.5 else "不相似"

result
'''
{'label': '不相似', 'score': -0.025799434632062912}
'''

image.png


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

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

相关文章

机器学习的复习笔记2-回归

一、什么是回归 机器学习中的回归是一种预测性分析任务&#xff0c;旨在找出因变量&#xff08;目标变量&#xff09;和自变量&#xff08;预测变量&#xff09;之间的关系。与分类问题不同&#xff0c;回归问题关注的是预测连续型或数值型数据&#xff0c;如温度、年龄、薪水…

springboot自定义更换启动banner动画

springboot自定义更换启动banner动画 文章目录 springboot自定义更换启动banner动画 &#x1f4d5;1.新建banner&#x1f5a5;️2.启动项目&#x1f516;3.自动生成工具&#x1f9e3;4.彩蛋 &#x1f58a;️最后总结 &#x1f4d5;1.新建banner 在resources中新建banner.txt文…

数智赋能 锦江汽车携手苏州金龙打造高质量盛会服务

作为一家老牌客运公司&#xff0c;成立于1956年的上海锦江汽车服务有限公司&#xff08;以下简称锦江汽车&#xff09;&#xff0c;拥有1200多辆大巴和5000多辆轿车&#xff0c;是上海乃至长三角地区规模最大的专业旅游客运公司。面对客运市场的持续萎缩&#xff0c;锦江汽车坚…

打破TikTok信息壁垒:东南亚达人不实名就封小黄车?跨境新店考核规则更改!

近期&#xff0c;TKFFF得到一个模糊消息&#xff0c;不保真但是个合规的趋势&#xff0c;分享给大家&#xff01; 目前泰国已落实达人实名制&#xff0c;11月底或者12月底之前可能东南亚所有达人都需要实名制&#xff0c;后期也会同步到全球。 如果达人不实名&#xff0c;会被…

蓝桥杯-平方和(599)

【题目】平方和 【通过测试】代码 import java.util.Scanner; import java.util.ArrayList; import java.util.List; // 1:无需package // 2: 类名必须Main, 不可修改public class Main {public static void main(String[] args) {Scanner scan new Scanner(System.in);//在此…

有哪些可信的SSL证书颁发机构?

目前市面上所显示的SSL证书颁发机构可所谓不计其数&#xff0c;类型也是多样&#xff0c;就好比我们同样是买一件T恤&#xff0c;却有百家不同类型的店铺一个道理。根据CA里面看似很多&#xff0c;但能拿到99%浏览器及设备信任度的寥寥无几&#xff0c;下面小编整理出几家靠谱可…

【substance painter】如何制作一个生锈磨损的枪

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 秩沅 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a;Uni…

提升企业文档处理效率,尽在Readiris PDF Corporate下载

在现代企业中&#xff0c;大量的文档处理工作是不可避免的。然而&#xff0c;传统的文档处理方法往往效率低下&#xff0c;浪费了企业宝贵的时间和资源。为了帮助企业提升文档处理效率&#xff0c;我们推荐使用Readiris PDF Corporate软件。 Readiris PDF Corporate是一款功能…

UE4/UE5 雾

雾 UE4/UE5 雾平面雾材质效果图&#xff1a; 3D雾区材质效果图&#xff1a; UE4/UE5 雾 平面雾 做好将材质放在Plane上就行 材质 效果图&#xff1a; 3D雾区 做好将材质放在3D模型上就行 材质 效果图&#xff1a;

反转链表的三种写法

题目链接&#xff1a;https://leetcode.cn/problems/reverse-linked-list/ 方法一&#xff1a;循环&#xff0c;维护好两个节点一个前一个后 class Solution {public ListNode reverseList(ListNode head) {ListNode pre null;ListNode local head;while(local ! null){List…

信奥编程 1168:大整数加法

解析&#xff1a;在c中需要考虑这么几个问题&#xff0c;第一个是大数据的输入&#xff0c;第二个是大数据的存储&#xff0c;第三是大数据的计算方式&#xff0c;最后是输出。 针对上述几个问题&#xff0c;第一个问题&#xff0c;采用字符串的方式或者数组加循环的方式接收输…

Typora+PicGo+Minio搭建博客图床

文章目录 TyporaPicGoMinio搭建博客图床前言什么是图床?为什么需要图床?准备工作一、Typora二、Picgo1. 下载Picgo2. 下载node.js3. 下载minio插件 三、服务器端配置1. 添加端口到安全组2. 使用Docker安装minio3. 配置minio image-20231127175530696四、minio插件配置五、Typ…

c++_继承

&#x1f3f7;如被何实现一个不能被继承的类&#xff08;或是继承无意义的类&#xff09; 将构造函数定义成私有的就行了&#xff0c;即&#xff1a;私有化父类的构造函数 c 11 新增关键字final 修饰父类直接不能被继承 class A final {........ }&#x1f3f7;继承与有元 有…

Vue CLI 初体验之如何创建一个项目并打开,以及组件的简单使用案例。

目录 什么是Vue CLI? 如何使用Vue CLI 创建一个项目 1.winr 打开cmd 输入vue create 1127(1127是文件名) 2.配置基础设置 选择Manually select features 选择Router和Vuex 选中vue版本&#xff08;我这里选vue3&#xff09; 剩下的看自己需要&#xff0c;如果不确定就一…

zabbix 6.0 原理与部署

一、zabbix简介&#xff1a; zabbix 是一个基于 Web 界面的提供分布式系统监视以及网络监视功能的企业级的开源解决方案。 zabbix 能监视各种网络参数&#xff0c;保证服务器系统的安全运营&#xff1b;并提供灵活的通知机制以让系统管理员快速定位/解决存在的各种问题。 zabbi…

如何迁移数据到水经微图64位版?

我们在《为什么要升级水经微图到64位&#xff1f;》一文中&#xff0c;为大家分享了升级水经微图到64位的原因。 这里&#xff0c;我们再为大家分享一下在哪些情况下升级需要迁移已标注的数据&#xff0c;以及如何迁移已标注绘制的数据到水经微图64位中。 哪些情况需要迁移数…

Vue路由跳转页面刷新

案例使用映射路由 百度的时候各种操作就是没有注意keepAlive&#xff0c;发现那个为缓存开启之后前端有个小后台Vue生命周期函数失效。同一个页面刷新时这个keep Alive需要关闭。

11 OAuth2.0实战:网关统一认证授权

上一节介绍了认证中心,这节介绍下网关如何集成认证中心实现网关的统一认证授权。 木谷博客系统的整个认证授权架构设计如下图: 网关在这里的主要功能就是6-8这三步: 校验token:对令牌的过期时间、签名进行校验鉴权:对令牌的权限进行校验转发:解析令牌中的相关信息,通过…

Proto3语法详解02

目录 1.默认值 2.更新消息 2.1更新规则 2.2保留字段reserved 2.2.1创建通讯录3.0版本---验证错误删除字段造成的数据损坏 2.3未知字段 2.3.1未知字段从哪获取 3.3.2升级通讯录3.1版本--验证未知字段 2.4前后兼容性 3.选项option 3.1选项分类 3.2常用选项列举 1.默认值…

如何解决主从数据库同步延迟问题?

如何解决主从数据库同步延迟问题&#xff1f; 前言 最近&#xff0c;系统上频繁出现主从延迟的问题&#xff0c;因此针对主从架构、主从同步以及主从延迟问题进行了一次学习。 主从架构浅析 在了解主从延迟之前&#xff0c;我们有必要对主从架构有一些简单的认识。在如今的…