全套解决方案:基于pytorch、transformers的中文NLP训练框架,支持大模型训练和文本生成,快速上手,海量训练数据!

news2025/2/28 6:26:01

全套解决方案:基于pytorch、transformers的中文NLP训练框架,支持大模型训练和文本生成,快速上手,海量训练数据!

1.简介

  1. 目标:基于pytorchtransformers做中文领域的nlp开箱即用的训练框架,提供全套的训练、微调模型(包括大模型、文本转向量、文本生成、多模态等模型)的解决方案;
  2. 数据
    • 从开源社区,整理了海量的训练数据,帮助用户可以快速上手;
    • 同时也开放训练数据模版,可以快速处理垂直领域数据;
    • 结合多线程、内存映射等更高效的数据处理方式,即使需要处理百GB规模的数据,也是轻而易举;
  3. 流程:每一个项目有完整的模型训练步骤,如:数据清洗、数据处理、模型构建、模型训练、模型部署、模型图解;
  4. 模型:当前已经支持gpt2clipgpt-neoxdollyllamachatglm-6bVisionEncoderDecoderModel等多模态大模型;
  5. 多卡串联
    :当前,多数的大模型的尺寸已经远远大于单个消费级显卡的显存,需要将多个显卡串联,才能训练大模型、才能部署大模型。因此对部分模型结构进行修改,实现了训练时推理时
    的多卡串联功能。
  • 模型训练
中文名称文件夹名称数据数据清洗大模型模型部署图解
中文文本分类chinese_classifier
中文gpt2chinese_gpt2
中文clipchinese_clip
图像生成中文文本VisionEncoderDecoderModel
vit核心源码介绍vit model
Thu-ChatGlm-6b(v1)simple_thu_chatglm6b
🌟chatglm-v2-6b🎉chatglm_v2_6b_lora
中文dolly_v2_3bdolly_v2_3b
中文llamachinese_llama
中文bloomchinese_bloom
中文falcon(注意:falcon模型和bloom结构类似)chinese_bloom
中文预训练代码model_clm
百川大模型model_baichuan
模型修剪✂️model_modify
llama2 流水线并行pipeline

2.文本分类模型

本部分,介绍中文的文本分类模型,适用于二分类、多分类等情况。使用transformers库。

  • 处理数据code_01_processdata.ipynb
  • 数据介绍
    1. 本案例使用的是一个外卖平台的评论数据,对评论的文本做了分类(分为好评和差评)
    2. 当你把code_01_processdata.ipynb文件跑完之后,就可以看到在📁data_all里面有一个📁data,里面有三个文件,样式都是像下面👇这样的

上图是一个batch的数据,或者所有的文本分类的数据样式:

  1. text下面的红色条,就是一个个句子。
  2. label里面有红色有绿色,就是表示标签分类。
  3. transformers包做分类的时候,数据要求就这两列。

注意点:

  1. 数据需要分为train_data.csv,test_data.csv,valid_data.csv,这三个csv文件注意是使用,分割开的。
  2. 数据不可以有缺失值
  3. 数据最好只含有两列:label,text
  • label:表示标签,最好为整型数值。0,1,2,3,4等
  • text:表示文本,(看你需求,可以有符号,也可以没有标点符号)
  1. train_data.csv,test_data.csv,valid_data.csv这三个数据里面,不要有数据相同的,不然会造成数据泄漏。
  • 训练模型code_02_trainmodel.ipynb

  • 数据训练流程
    以一个batch为例:

    1. Tokenizer会将数据中的text转换成三个矩阵(或者叫三个Tensor),分别叫input_ids,token_type_ids,attention_mask,至于怎么转换的,我们先不做详细介绍(本仓库后续会介绍)。
    2. pretrained model在被加载之前,需要设置一大堆模型的参数,至于要设置什么参数,我们也不做详细介绍。
    3. Trainer就是一个训练器,也需要预先设置好一大堆参数。至于要设置什么参数,我们也不做详细介绍。
    4. Trainer会把input_ids,token_type_ids,attention_mask;还有数据自带的标签label;还有pretrained model都加载进来,进行训练;
    5. 当所有batch的数据更新完之后,最终就会生成一个模型。your new model就诞生了。
    6. 对于刚开始学习大模型做nlp分类的任务,其实不需要考虑那么多细节,只需要注意数据流程。
  • 注意点:

    1. 这个步骤非常看显存大小。显卡显存越大越好。batch_size,eval_size大小取决于显存大小。
    2. 在实际工程中,会先使用Tokenizer把所有的文本转换成input_ids,token_type_ids,attention_mask,然后在训练的时候,这步就不再做了,目的是减少训练过程中cpu处理数据的时间,不给显卡休息时间。
    3. 在使用Tokenizer把所有的文本做转换的期间,如果设置的文本的长度上限为64,那么会把大于64的文本截断;那些少于64的文本,会在训练的时候,在喂入模型之前,把长度补齐,这么做就是为了减少数据对内存的占用。
    1. 预测code_03_predict.ipynb

    2. 这个时候,就是搞个句子,然后丢给一个pipeline(这个就是把Tokenizer你的大模型放在一起了),然后这个pipeline就给你返回一个分类结果。

    3. 常见的就是使用pipeline,如果更加复杂的话,比如修改模型,这个时候,就比较复杂了(后面会再次介绍)。

    1. 部署

    2. 简单的部署相对于预测,其实就是再加一层web端口,fastapi包就可以实现。

    3. 高级一点的部署相对于预测,就需要把模型从pytorch转换成onnx格式的,这样可以提高推理效率(也不一定,就是举个例子),可能也不会使用web端口(http协议)了,会使用rpc协议等方法。这部分现在先不看。

3.中文gpt2

  1. 本文,将介绍如何使用中文语料,训练一个gpt2
  2. 可以使用你自己的数据训练,用来:写新闻、写古诗、写对联等
  3. 我这里也训练了一个中文gpt2模型,使用了612万个样本,每个样本有512个tokens,总共相当于大约31亿个tokens
  • 安装包

需要准备好环境,也就是安装需要的包

pip install -r requirements.txt

像是pytorch这种基础的包肯定也是要安装的,就不提了。

  • 数据来源

    1. 获得数据:数据链接,关注公众号【统计学人】,然后回复【gpt2】即可获得。
    2. 获得我训练好的模型(使用了15GB的数据(31亿个tokens),在一张3090上,训练了60多小时)
  • 数据格式

    1. 数据其实就是一系列文件夹📁,然后每一个文件夹里面有大量的文件,每一个文件都是.csv格式的文件。其中有一列数据是content
    2. 每一行的content就代表一句话
    3. 虽然数据有15GB那么大,但是处理起来一点也不复杂,使用 datasets
      包,可以很轻松的处理大数据,而我只需要传递所有的文件路径即可,这个使用 glob 包就能完成。
  • 训练代码train_chinese_gpt2.ipynb

    1. 现在训练一个gpt2代码,其实很简单的。抛开处理数据问题,技术上就三点:tokenizergpt2_modelTrainer
    2. tokenizer使用的是bert-base-chinese
      ,然后再添加一下bos_tokeneos_tokenpad_token
    3. gpt2_model使用的是gpt2,这里的gpt2我是从0开始训练的。而不是使用别人的预训练的gpt2模型。
    4. Trainer训练器使用的就是transformersTrainer模块。(支撑多卡并行,tensorboard等,都写好的,直接调用就行了,非常好用)
  • 模型

  • 推理代码infer.ipynb

这个是chinese-gpt2的推理代码

  1. 将代码中的model_name_or_path = "checkpoint-36000"里面的"checkpoint-36000",修改为模型所在的路径。
  2. 然后运行下面一个代码块,即可输出文本生成结果
  3. 可以参考这个代码,制作一个api,或者打包成一个函数或者类。
  • 交互机器人界面chatbot.py
  1. 修改代码里面的第4行,这一行值为模型所在的位置,修改为我分享的模型文件路径。
model_name_or_path = "checkpoint-36000"
  1. 运行
python chatbot.py
  1. 点击链接,即可在浏览器中打开机器人对话界面
  • 更多
  1. 这个完整的项目下来,其实我都是全靠huggingface文档、教程度过来的.
  2. 我做的东西,也就是把Tokenizer改成中文的了,然后也整理了数据,别的大部分东西,都不是我做的了.
  3. 原文链接为https://huggingface.co/course/zh-CN/chapter7/6?fw=pt.

其实,我更喜欢做应用,但是也要理解相关的背后原理,目前还在研究相关的gpt2原理还有相关的推理细节,这是我整理的链接,希望可以共同进步

  1. https://huggingface.co/blog/how-to-generate
  2. https://huggingface.co/gpt2
  3. https://huggingface.co/gpt2-large

4.中文clip模型

  1. 本文将介绍,如何从0到1的训练一个中文clip模型。
  2. 在处理数据的过程中,训练的过程中,需要的注意事项。
  3. 从数据流的角度,看看clip模型是怎么处理数据的,模型是怎么构建的。image和text的模型的差异性,两个模型是怎么合并起来计算loss的。
  • clip模型介绍

CLIP的英文全称是Contrastive Language-Image Pre-training,即一种基于对比文本-图像对的预训练方法或者模型。
CLIP是一种基于对比学习的多模态模型,与CV中的一些对比学习方法如moco和simclr不同的是,
CLIP的训练数据是文本-图像对:一张图像和它对应的文本描述,这里希望通过对比学习,
模型能够学习到文本-图像对的匹配关系。
如下图所示,CLIP包括两个模型:

  1. Text Encoder和Image Encoder,其中Text Encoder用来提取文本的特征,可以采用NLP中常用的text transformer模型;

  2. Image Encoder用来提取图像的特征,可以采用常用CNN模型或者vision transformer。

上面这段文字来源于https://zhuanlan.zhihu.com/p/493489688

  1. 从数据上看:之前相似度计算,都是两个文本对:text - text。只不过现在都是text - image了。
  2. clip是两个模型(具体长什么样子,后面再说)
  • 2.1 text-model:负责把text转换成向量。
  • 2.2 image-model:负责把image转换成向量。
  • 2.3 然后把上面两个向量,做交叉计算loss,然后loss反向传播,这样两个模型的参数都会更新。
  1. 其实你想啊,这个image-model处理图像的,其实也可以改为处理视频、处理3d模型等。那简直是格局打开🫴了。我现在没有数据,后面也打算做一个。
  2. 你再想想,text-image => text-image-video-3d这样联合起来,是不是更好。没数据,没机器,做不了。
  3. 有些人可能感觉,你这人,就知道TMD吹牛,来来来,我带你研究研究clip模型的源码。
  • 数据
  1. 直接点击链接https://pan.baidu.com/s/1wGmXUNP021OWnW7Kik7q1A?pwd=gd3c
    来获得。
  2. 把下载好的文件,也就是test-2.6w.csvtrain-137w.csv放在文件夹📁bigdata/raw_data里面。
  3. 以此运行processdta_01.ipynbprocessdta_02.ipynbprocessdta_02.ipynb用来处理数据。
  • 3.1 processdta_01.ipynb:用来下载数据,大概下载了10多个小时。
  • 3.2 processdta_02.ipynb:用来筛选数据,不是所有的图片数据都是可以用的,这一步非常坑。需要留意。如果图片没有筛选好,在你训练到中间的时候,突然一下因为图片无法加载导致错误,从而训练中断了。
  • 3.3 processdta_03.ipynb:用来把数据干净的数据处理好,合并好,生成新的,漂亮的训练数据。
  1. 其实完整下来看,数据清洗,就是把符合格式的照片筛选出来,然后进行训练。
  • 数据总结

说到底,你的数据只要整理成这样的一个样式即可

textimage_path
河南一村民继承祖上的一金碗,专家鉴定:此碗是溥仪皇帝用过的bigdata/image_data/test-9282.jpg
著名钢琴家郎朗:我永远不会放弃演奏bigdata/image_data/test-2644.jpg
科幻动作电影《超体》10月24日来袭bigdata/image_data/test-13199.jpg
  1. text:这一列对应图片的标注,或者和图片相关的文本。
  2. image_path:这一列对应图片所在你电脑本地上的路径。
  3. 是的,搞了半天,数据就是这么简单。
  • 数据预处理

这里的数据预处理,是我随便起的名字。说白了,就是这么会是:

  1. 使用tokenizertext转换成input_idsattention_mask.

  2. 使用processorimage转换成pixel_values.

  3. 处理text,那还是很快的。百万级别的数据,可能2~3分钟就行了。

  4. 因为image太大了,只能在训练的时候,每一batch,才能去加载image
    ,这就导致训练的时候特别慢。倒不是因为我的3090算力不行,全都TMD卡在计算机IO上了,非常让人难受。

  • 模型部分

终于讲解到clip的模型部分了。这个clip模型实在是太灵活了,你可以做很多个版本,这里我们挑几个比较常见的结构,来分享一下。

  • 常见的clip模型

这里值得是常见的clip模型,特指的是transformers包的clip模型。

  1. clip主要就是分为两个部分,一个是CLIPTextTransformer,一个是CLIPVisionTransformer,说白了就是一个处理text,一个处理image。
  2. CLIPTextTransformerCLIPVisionTransformer的核心,都共用了一个模型结构CLIPEncoder
    。也就是CLIP编码部分。(这里说的共用,值得是模型框架相同,而不是模型训练的时候,参数也相同。)

Q:有些人就问了,text和image两个生成的数据都不一样,比如text转换成input_idsattention_maskimage
转换成pixel_values;他们怎么可以使用一个模型结构CLIPEncoder

A:这个也是非常好回答的,因他俩又不是直接使用CLIPEncoder
,前后都加了一些万金油的模型组件(比如embeddinglinear
等),模型输出的时候,也是这么做的。还是应了那句话,就看你怎么吧数据转换成hidden_states,以及怎么把hidden_states输出出去。

Q:CLIPTextTransformerCLIPVisionTransformer输出的维度也不一定一样吧,怎么计算交叉损失?

A: 也很简单啦,加个linear对齐一下就行了。

看看CLIPTextTransformerCLIPVisionTransformer的内心:

  • 中文版本的clip模型

上面的常见的clip模型,确实是好,其实你只要换一个支持中文的新tokenizer,然后从0️⃣开始训练即可。
但是这么搞,没什么创意呀。其实我第一次就是这么干的,直接支持中文的新tokenizer。但是训练了一天,loss基本上没变化。我内心其实是崩溃的。

后来,我研究了一下transformers包里面的chinese-clip模型代码。我发现,chinese-clip相对于clip
。就是把常规的CLIPTextTransformer换成了bert版本的。啊对,这就破案了。这个奉上代码截图。

  • 后续改进
  1. 因为训练image这类型的任务,非常吃资源,不管是我的显存还是我的磁盘。目前数据占用我硬盘100GB
  2. 针对loss不下降,下次如果再让我做,我打算先把clip模型的vit部分先固定住,然后训练bert来拟合vit-output
  3. 也可也固定bert模型,训练vit模型;
  4. 也可以拆开做,反正本质上都是Encoder,然后计算相似度。

5. 图生文image-encoder-decoder

之前在huggingfacehttps://huggingface.co/nlpconnect/vit-gpt2-image-captioning上看到这个模型.

  1. 感觉这个模型很有趣,想法很好。
  2. 发现这个模型关于中文的不多。
  3. 之前的clip训练其实挺失败的,loss没有下降.

主要也就是抱着学习的态度,把源码看懂,把流程跑通。分享中间的细节和踩坑经历。

  1. 使用vit来作为encoder部分,输出encoder_hidden_states绿色部分1
  2. 使用gpt2来作为decoder部分,接受encoder_hidden_states,绿色部分3
  3. 如果encoder输出的encoder_hidden_statesdecoder接受的encoder_hidden_states维度不一样,就加个linear,绿色部分2
  • 模型训练需要的数据样式
    训练的时候,模型需要的数据主要有两个维度:
  1. pixel_valueimage通过processor生成
  2. labeltext通过tokenizer生成的input_ids
  3. 计算loss的时候,其实和gpt2一模一样的(自回归,本质上就是向后错位一下)。

目前已经把训练好的模型,发布在huggingface上了。https://huggingface.co/yuanzhoulvpi/vit-gpt2-image-chinese-captioning

本模块处理数据的方式和clip模型差不多,可以看隔壁文件夹,训练clip的数据处理思路。

  1. 只要把processdta_02.ipynb文件替换即可。
  2. 执行顺序依然按照着processdta_01.ipynbprocessdta_02.ipynbprocessdta_03.ipynb
  • 训练部分train_encoder_decoder.ipynb

    1. 处理图像,使用的是"google/vit-base-patch16-224"模型。
    2. 处理文本,使用的是"yuanzhoulvpi/gpt2_chinese"模型。
    3. 最后就是把两个模型通过VisionEncoderDecoderModel粘起来。
  • 训练的loss

  • 训练的信息
    gpu使用的是3090,模型大概是2.16亿个参数。花了超过20个小时。但是大部分时间都是卡在IO上(加载图片上)

  • 推理用你自己训练
    参考infer_encoder_decoder.ipynb

  • 直接用

from transformers import (VisionEncoderDecoderModel, 
                          AutoTokenizer,ViTImageProcessor)
import torch
from PIL import Image
vision_encoder_decoder_model_name_or_path = "yuanzhoulvpi/vit-gpt2-image-chinese-captioning"#"vit-gpt2-image-chinese-captioning/checkpoint-3200"

processor = ViTImageProcessor.from_pretrained(vision_encoder_decoder_model_name_or_path)
tokenizer = AutoTokenizer.from_pretrained(vision_encoder_decoder_model_name_or_path)
model = VisionEncoderDecoderModel.from_pretrained(vision_encoder_decoder_model_name_or_path)
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model.to(device)

max_length = 16
num_beams = 4
gen_kwargs = {"max_length": max_length, "num_beams": num_beams}


def predict_step(image_paths):
    images = []
    for image_path in image_paths:
        i_image = Image.open(image_path)
        if i_image.mode != "RGB":
            i_image = i_image.convert(mode="RGB")

        images.append(i_image)

    pixel_values = processor(images=images, return_tensors="pt").pixel_values
    pixel_values = pixel_values.to(device)

    output_ids = model.generate(pixel_values, **gen_kwargs)

    preds = tokenizer.batch_decode(output_ids, skip_special_tokens=True)
    preds = [pred.strip() for pred in preds]
    return preds


predict_step(['bigdata/image_data/train-1000200.jpg'])

6.vit 源码

  1. 之前都搞过clipimage-encoder-decoder。现在哪里还怕搞不懂vit.
  2. 这里主要分享一下vit的最核心的部分。
  • vit 核心的数据内容

vit想法非常牛,但是数据处理的思想更牛,之前都没提出来过。

载对于一个图片,将一个图片分割成N块。巧妙的使用nn.Conv2d

  • 初始化
import torch
from torch import nn 

#base parameter

image_size=224 # 图片的width和height
patch_size=16  # 将图片的分为块,每一块的大小为16x16,这样就有(224//16)^2 = 14 ^2 = 196个
num_channels=3 #  R,G, B
hidden_size=768 # 输出的hidden_size
batch_size = 16 # 一批数据有多少
  • 创建一个分块器和一个样本数据(一个batch)
#分块器
project = nn.Conv2d(num_channels, hidden_size, kernel_size=patch_size, stride=patch_size)

#样本数据(一个`batch`) 
#batch_size, num_channels, height, width = pixel_values.shape
pixel_values = torch.randn(batch_size, num_channels, image_size, image_size)

pixel_values.shape 
  • 输出分块的大小
project(pixel_values).shape 

#> torch.Size([16, 768, 14, 14])
  • 数据再转换一下,image的embedding就完成了。
image_embedding = project(pixel_values).flatten(2).transpose(1, 2)
image_embedding.shape 
#> torch.Size([16, 196, 768]) # batch_size, seq_length, embedding_dim

这个时候,就已经和文本的数据一样了。维度都是(batch_size, seq_length, embedding_dim),再向下推导,就是transformers了。没什么可介绍的了。

项目链接:https://github.com/yuanzhoulvpi2017/zero_nlp

更多优质内容请关注公号:汀丶人工智能;会提供一些相关的资源和优质文章,免费获取阅读。

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

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

相关文章

如何满足影视飓风对空间智能化的“挑剔”?智哪儿专访Aqara杭州上城区服务商

最近,商务部、住房城乡建设部等13部门联合印发了关于促进家居消费若干措施的通知,明确提出要促进智能家居设备互联互通,推动单品智能向全屋智能发展。在国家相关政策的支持下,全屋智能引领下的空间智能化面临前所未有的发展机会&a…

“传递信任 服务发展”金融科技标准认证生态大会成功举办 同创永益为支持单位

8月16日下午,北京国家金融科技认证中心(以下简称“国金认证”)在第十三届农村金融机构信息化发展创新座谈会期间,成功举办“传递信任 服务发展”金融科技标准认证生态大会,邀请管理部门、行业机构、产业机构&#xff0…

亚马逊云科技CEO谈及企业领导力原则的核心:坚持顾客至上

亚马逊云科技首席执行官Adam Selipsky几乎从一开始就在那里:他于2005年加入,在效力亚马逊11年后于2016年离开,转而经营Tableau,并于2021年成为亚马逊云科技首席执行官。当时亚马逊云科技前首席执行官安迪贾西(Andy Jassy)接替杰夫…

基于NXP i.MX 6ULL核心板的物联网模块开发案例(3)

前言 本文主要介绍基于创龙科技TLIMX6U-EVM评估板的物联网模块开发案例,适用开发环境: Windows开发环境:Windows 7 64bit、Windows 10 64bit 虚拟机:VMware15.1.0 Linux开发环境:Ubuntu18.04.4 64bit U-Boot&…

大型企业是否有必要进行数字化转型?

在数字化、信息化、智能化蓬勃发展的今天,初创公司可以很轻易的布局规划数字化发展的路径。而对于大型企业而言,其已经形成了较为成熟稳固的业务及组织架构,是否还有必要根据自身行业发展特点寻求数字化转型?(比如制造…

喜讯|思迈特软件入选2023爱分析·数据智能优秀厂商

近期,“2023爱分析数据智能优秀厂商”评选结果于第五届数据智能高峰论坛现场正式公布,思迈特软件凭借在数据智能领域的技术及服务水平,从150家数据智能厂商中脱颖而出,成功入选为“2023爱分析数据智能优秀厂商”。 本次评选是基于…

Python“牵手”1688商品列表数据,关键词搜索1688API接口数据,1688API接口申请指南

1688平台API接口是为开发电商类应用程序而设计的一套完整的、跨浏览器、跨平台的接口规范, 1688API接口是指通过编程的方式,让开发者能够通过HTTP协议直接访问1688平台的数据,包括商品信息、店铺信息、物流信息等,从而实现1688平…

Wi-Fi网络泄露你位置的新恶意软件,如何保护自己?

通常,当黑客用恶意软件感染最好的Windows笔记本电脑时,经济利益是他们的动机。然而,他们也喜欢部署信息窃取恶意软件来获取你的个人数据。 Secureworks反威胁部门的安全研究人员发现了一种神秘的新恶意软件,它完全是在寻找其他东…

【Unity小技巧】在Unity中实现类似书的功能(附git源码)

文章目录 前言本文实现的最终效果素材1. 页面素材2. 卡片内容素材地址 翻页实现1. 配置我们的canvas参数2. 添加封面和页码3. 翻页效果4. 添加按钮5. 脚本控制6. 运行效果 页面内容1. 添加卡片内容2. shader控制卡片背面3. 页面背面显示不同卡片 源码参考完结 前言 欢迎来到游…

【两区域系统的自动发电控制】任何区域突然负荷变化的情况下,如何测量两个区域共享的功率研究(Simulink)

💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…

No message found under code ‘-1‘ for locale ‘zh_CN‘.

导出中的报错:No message found under code -1 for locale zh_CN. 报错原因:页面中展示的数据和后端excel中的数据不一致导致 具体原因:

ray-分布式计算框架-集群与异步Job管理

0. ray 简介 ray是开源分布式计算框架,为并行处理提供计算层,用于扩展AI与Python应用程序,是ML工作负载统一工具包 Ray AI Runtime ML应用程序库集 Ray Core 通用分布式计算库 Task -- Ray允许任意Python函数在单独的Python worker上运行&…

矢量调制分析基础

前言 本文介绍VSA 的矢量调制分析和数字调制分析测量能力。某些扫频调谐频谱分析仪也能通过使用另外的数字无线专用软件来提供数字调制分析。然而,VSA 通常在调制格式和解调算法配置等方面提供更大的测量灵活性,并提供更多的数据结果和轨迹轨迹显示。本…

Codeforces Round #894 (Div.3)

文章目录 前言A. Gift Carpet题目:输入:输出:思路:代码: B. Sequence Game题目:输入:输出:思路:代码: C. Flower City Fence题目:输入&#xff1a…

keepalived双机热备 (四十五)

一、概述 Keepalived 是一个基于 VRRP 协议来实现的 LVS 服务高可用方案,可以解决静态路由出现的单点故障问题。 原理 在一个 LVS 服务集群中通常有主服务器(MASTER)和备份服务器(BACKUP)两种角色的服务器…

nuxt2-storybook-vite:环境搭建、基础使用 / nuxt项目组件库

一、创建 nuxt2 项目 安装 - NuxtJS | Nuxt.js 中文网 yarn create nuxt-app <项目名> 二、安装 storybook 2.1、初始化 Storybook pnpm add -g storybook/cli npx -p storybook/cli sb init 命令解释 序号命令命令解释1npx -p storybook/cli sb init是一个命令行…

基于JSP+Servlet+mysql员工权限管理系统

基于JSPServletmysql员工权限管理系统 一、系统介绍二、功能展示四、其他系统实现五、获取源码 一、系统介绍 项目类型&#xff1a;Java web项目 项目名称&#xff1a;基于JSPServlet的员工权限管理系统[qxxt] 项目架构&#xff1a;B/S架构 开发语言&#xff1a;Java语言 …

【ag-grid-vue】column

网格中的每一列都使用列定义(ColDef)来定义。列根据在网格选项中指定的列定义的顺序在网格中定位。 列定义 下面的例子展示了一个定义了3列的简单网格: <template><ag-grid-vuestyle"height: 300px; width: 1000px"class"ag-theme-balham":colum…

最新外卖点餐微信小程序源码系统 完整前后端+安装部署教程

分享一个完整的外卖点餐微信小程序源码系统&#xff0c;含完整代码程序包和详细的安装搭建教程。 系统为多用户&#xff0c;可以无限多开&#xff0c;轻松帮助商家开发各种外卖点餐小程序。系统功能特别强大。 小程序源码下载地址&#xff1a;春哥技术博客获取

python SystemRDL 包介绍

对于芯片验证&#xff0c;在验证寄存器环节&#xff0c;如果我们需要根据大量的寄存器来构建我们的sequence或者激励&#xff0c;比如irq测试&#xff0c;我们需要测试irq信号源到寄存器门口的连接是否正常&#xff0c;irq 寄存器各个field的接线排序是否有弄错&#xff0c;以及…