三万字带你一遍跑通uer
三万字带你一遍跑通uer
参考文档
今天给大家介绍个非常强大的项目uer,集成了许多可以做自然语言的东西,效果的话也非常好,很适合企业级的应用!
1. 先将项目uer从github拉取下来(zip或git都ok)
2. 用pycharm打开项目,按照requirements.txt配置环境,我这里有一个专门用与机器学习的conda环境,就直接在此基础上装所需的包了
3. 预处理
词典文件的格式是一行一个单词,我们使用谷歌提供的包含21128个中文字符的词典文件models/google_zh_vocab.txt。
我们首先对书评语料进行预处理。预处理阶段需要将语料处理成为指定预训练模型要求的数据格式(–data_processor):
python preprocess.py --corpus_path corpora/book_review_bert.txt --vocab_path models/google_zh_vocab.txt --dataset_path dataset.pt --processes_num 8 --data_processor bert
我的配置
运行图片
4. 生成预训练模型
注意我们需要安装 six>=1.12.0。
预处理非常耗时,使用多个进程可以大大加快预处理速度(–processes_num)。默认的分词器为 --tokenizer bert 。原始文本在预处理之后被转换为pretrain.py可以接收的输入,dataset.pt。然后下载Google中文预训练模型google_zh_model.bin(此文件为UER支持的格式,原始模型来自于这里),并将其放在 models 文件夹中。接着加载Google中文预训练模型,在书评语料上对其进行增量预训练。预训练模型通常由词向量层,编码层和目标任务层组成。因此要构建预训练模型,我们应该给出这些信息,比如编码层使用什么类型的Encoder模块。这里我们通过配置文件(–config_path)指定模型使用的模块类型和超参数等信息。google_zh_model.bin下载地址
具体可见models/bert/base_config.json。假设我们有一台带有8个GPU的机器(官方文档代码):
python3 pretrain.py --dataset_path dataset.pt --vocab_path models/google_zh_vocab.txt \--pretrained_model_path models/google_zh_model.bin \--config_path models/bert/base_config.json \--output_model_path models/book_review_model.bin \--world_size 8 --gpu_ranks 0 1 2 3 4 5 6 7 \--total_steps 5000 --save_checkpoint_steps 1000 --batch_size 32mv models/book_review_model.bin-5000 models/book_review_model.bin
当然以上代码要随个人做小小的改动。比如我是只有一个gpu,那么我的代码应该是
python pretrain.py --dataset_path dataset.pt --vocab_path models/google_zh_vocab.txt --pretrained_model_path models/google_zh_model.bin --config_path models/bert/base_config.json --output_model_path models/book_review_model.bin --world_size 1 --gpu_ranks 0 --total_steps 5000 --save_checkpoint_steps 1000 --batch_size 32
mv models/book_review_model.bin-5000 models/book_review_model.bin
5.微调模型
我们在下游分类数据集上微调预训练模型,我们使用 pretrain.py 的输出book_review_model.bin(加载词向量层和编码层参数):
python finetune/run_classifier.py --pretrained_model_path models/book_review_model.bin --vocab_path models/google_zh_vocab.txt --config_path models/bert/base_config.json --train_path datasets/book_review/train.tsv --dev_path datasets/book_review/dev.tsv --test_path datasets/book_review/test.tsv --epochs_num 3 --batch_size 32
微调后的模型的默认路径是models/finetuned_model.bin。注意到预训练的实际batch size大小是 --batch_size 乘以 --world_size;分类等下游任务微调的实际的batch size大小是 --batch_size 。然后我们利用微调后的分类器模型进行预测:
python inference/run_classifier_infer.py --load_model_path models/finetuned_model.bin --vocab_path models/google_zh_vocab.txt --config_path models/bert/base_config.json --test_path datasets/book_review/test_nolabel.tsv --prediction_path datasets/book_review/prediction.tsv --labels_num 2
–test_path 指定需要预测的文件,文件需要包括text_a列; --prediction_path 指定预测结果的文件; 注意到我们需要指定分类任务标签的个数 --labels_num ,这里是二分类任务。
然后我们得到8000条预测结果
让我们来大致看一下预测效果(test_nolabel.tsv为预测样本,prediction.tsv为预测结果,标0是消极评论,标1为积极评论)
粗略一看差不多也有90多的正确率,我感觉还是ok的。
当然我们还可以使用 google_zh_model.bin 在下游分类数据集上微调:
python finetune/run_classifier.py --pretrained_model_path models/google_zh_model.bin --vocab_path models/google_zh_vocab.txt --config_path models/bert/base_config.json --train_path datasets/book_review/train.tsv --dev_path datasets/book_review/dev.tsv --test_path datasets/book_review/test.tsv --epochs_num 3 --batch_size 32
可以看到,直接用 google_zh_model.bin的精度只比预训练生成的模型少一点点
一般来说,模型相关的关键信息一般放在配置文件中。这里我们进一步介绍前面使用的BERT-base模型的配置文件 models/bert/base_config.json :
{"emb_size": 768,"feedforward_size": 3072,"hidden_size": 768,"hidden_act": "gelu","heads_num": 12,"layers_num": 12,"max_seq_length": 512,"dropout": 0.1,"data_processor": "bert""embedding": ["word", "pos", "seg"],"encoder": "transformer","mask": "fully_visible","target": ["mlm", "sp"],"tie_weights": true
}
BERT模型的词向量层是word(token)、position、segment向量的求和,因此使用 “embedding”: [“word”, “pos”, “seg”] ;BERT使用Transformer编码器(“encoder”: “transformer”),并且句子中的任意一个词可以看到所有词的信息,因此我们使用 fully_visible 遮罩类型(“mask”: “fully_visible”);在预训练目标任务方面,BERT同时使用遮罩语言模型和句子预测,因此使用 “target”: [“mlm”, “sp”] 。“tie_weights”: true 指定embedding层和softmax前一层共享参数。预训练阶段还需要指定 dataset.pt 的格式(“data_processor”: “bert”)。这里和预处理阶段 --data_processor bert 保持一致。
我们通过对某些参数的微调同样也可以提高预测的精度
6.使用MLM目标任务预训练
预测是否是下一个句子(NSP)是BERT的目标任务之一,但是,NSP任务与句子级别的评论匹配度程度不是很高,因为我们需要将句子切分为多个部分去构造文档。 UER-py可以让用户自由选择不同的目标任务。这里我们选择使用遮罩语言模型(MLM)作为目标任务。去掉NSP目标任务,只使用MLM目标任务对书评语料可能是更合适的选择:
python preprocess.py --corpus_path corpora/book_review.txt --vocab_path models/google_zh_vocab.txt --dataset_path dataset.pt --processes_num 8 --dynamic_masking --data_processor mlm
python pretrain.py --dataset_path dataset.pt --vocab_path models/google_zh_vocab.txt --pretrained_model_path models/google_zh_model.bin --config_path models/bert/base_config.json --output_model_path models/book_review_mlm_model.bin --world_size 1 --gpu_ranks 0 --total_steps 5000 --save_checkpoint_steps 1000 --batch_size 32 --data_processor mlm --target mlm
mv models/book_review_mlm_model.bin-5000 models/book_review_mlm_model.bin
python finetune/run_classifier.py --pretrained_model_path models/book_review_mlm_model.bin --vocab_path models/google_zh_vocab.txt --config_path models/bert/base_config.json --train_path datasets/book_review/train.tsv --dev_path datasets/book_review/dev.tsv --test_path datasets/book_review/test.tsv --epochs_num 3 --batch_size 32
在预训练阶段,我们仍然使用BERT-base配置文件 models/bert/base_config.json ,但是由于只保留MLM目标任务,因此在命令行中进行指定 --data_processor mlm --target mlm 。我们可以通过多种方式去控制模型的类型,超参数等信息,它们的优先级如下:命令行、配置文件、默认设置。也就是说,我们在命令行中指定的信息会覆盖配置文件中的信息以及默认设置的信息。 这里使用了动态遮罩策略(–dynamic_masking)。动态遮罩策略能减小 dataset.pt 的大小,并且相对于静态遮罩通常会有更好的效果。因此推荐使用动态遮罩。 不同的预训练目标需要不同格式的语料。MLM目标对应的语料格式为一行一个文档:
doc1
doc2
doc3
注意到当预训练目标被改为MLM后,我们使用的预训练语料为 corpora/book_review.txt 而不是 corpora/book_review_bert.txt。
从以下这张图我们能很明显的看出文本样式的区别:
从训练精度来说使用动态遮罩后,效果确实得到了一定提升
7.使用BERT模型微调下游任务
除了分类外,UER-py还可以用于其他多种下游任务的微调。在下游任务数据集中,我们可以下载各种数据集。这里我们下载LCQMC、MSRA-NER、CMRC2018数据集,并将它们放到 datasets 文件夹中,如下
先来看看test.tsv(了解下这些数据集的大概样式)
其中0代表两句话句义不相似,1代表两句话句义相似
我们可以使用 run_classifier.py 进行文本对分类:
python finetune/run_classifier.py --pretrained_model_path models/google_zh_model.bin --vocab_path models/google_zh_vocab.txt --config_path models/bert/base_config.json --train_path datasets/lcqmc/train.tsv --dev_path datasets/lcqmc/dev.tsv --test_path datasets/lcqmc/test.tsv --output_model_path models/classifier_model.bin --batch_size 32 --epochs_num 3 --seq_length 128
对于文本对分类,数据集需要包括text_a、text_b、label列。 然后我们使用微调后的文本对分类模型进行推理:
python inference/run_classifier_infer.py --load_model_path models/classifier_model.bin --vocab_path models/google_zh_vocab.txt --config_path models/bert/base_config.json --test_path datasets/lcqmc/test.tsv --prediction_path datasets/lcqmc/prediction.tsv --seq_length 128 --labels_num 2
被预测的文件(–test_path)需要包括text_a和text_b列。
从前21条预测结果来看,有4条打标有误,不过也不能以偏概全,只能说还需要再微调一下。
我们还可以使用 run_ner.py 进行命名实体识别:
python finetune/run_ner.py --pretrained_model_path models/google_zh_model.bin --vocab_path models/google_zh_vocab.txt --config_path models/bert/base_config.json --train_path datasets/msra_ner/train.tsv --dev_path datasets/msra_ner/dev.tsv --test_path datasets/msra_ner/test.tsv --output_model_path models/ner_model.bin --label2id_path datasets/msra_ner/label2id.json --epochs_num 5 --batch_size 16
这张图里给出了精度、召回率和 F1 分数:
这些指标都在 0.94 以上,表明模型在处理该任务时性能非常好。
验证集上的分数(0.956, 0.955, 0.955)略高于测试集上的分数(0.943, 0.947, 0.945),这通常是正常的,因为模型在验证集上可能会更熟悉这些数据的模式。
–label2id_path 指定用于命名实体识别的label2id文件的路径。 然后我们使用微调后的命名实体模型模型进行推理:
python inference/run_ner_infer.py --load_model_path models/ner_model.bin --vocab_path models/google_zh_vocab.txt --config_path models/bert/base_config.json --test_path datasets/msra_ner/test_nolabel.tsv --prediction_path datasets/msra_ner/prediction.tsv --label2id_path datasets/msra_ner/label2id.json
在对比预测结果前,我们先来学点基础知识
这些标签是用于命名实体识别(NER,Named Entity Recognition)任务中的标记,表示不同类型的实体和它们在文本中的位置。以下是对这些标签的详细解释:
标签解释
-
O
(Outside):- 含义:该标记表示当前词不属于任何命名实体。
- 用途:适用于那些不需要特别标记的普通词语。
-
B-LOC
(Beginning of Location):- 含义:表示一个地理位置(如城市、国家等)实体的开始。
- 示例:在 “Paris is beautiful” 中,“Paris” 应该标记为
B-LOC
,因为它是地理位置的开始。
-
I-LOC
(Inside of Location):- 含义:表示地理位置实体的内部位置,通常用于多词组成的地理名称。
- 示例:在 “New York City” 中,“New” 应该标记为
B-LOC
,而 “York” 和 “City” 应该标记为I-LOC
,表示它们是一个连续的地理位置名称的一部分。
-
B-PER
(Beginning of Person):- 含义:表示一个人名实体的开始。
- 示例:在 “John Smith” 中,“John” 应该标记为
B-PER
,表示它是一个人名的开头。
-
I-PER
(Inside of Person):- 含义:表示人名实体的内部位置,通常用于多词组成的人名。
- 示例:在 “John Smith” 中,“Smith” 应该标记为
I-PER
,表示它是一个人名的后续部分。
-
B-ORG
(Beginning of Organization):- 含义:表示一个组织名称实体的开始,例如公司、机构或团体。
- 示例:在 “Google Inc.” 中,“Google” 应该标记为
B-ORG
,表示它是一个组织名称的开头。
-
I-ORG
(Inside of Organization):- 含义:表示组织名称实体的内部位置,通常用于多词组成的组织名称。
- 示例:在 “Google Inc.” 中,“Inc.” 应该标记为
I-ORG
,表示它是一个组织名称的后续部分。
标签格式
这些标签使用了 BIO 格式(有时也称为 IOB 格式),它是一种常用的序列标记方法,用于标记序列中的命名实体。BIO 是 Beginning
(开始), Inside
(内部) 和 Outside
(外部) 的缩写。
B-X
:表示某类型实体(X)的开头。I-X
:表示某类型实体(X)的后续部分。O
:表示不属于任何实体的词。
实际应用
在实体提取任务中,这些标签帮助模型识别并分类文本中的不同类型的实体。例如,模型可以从句子中提取并标记地名、人名和组织名称。下面是一个使用这些标签标记的句子的示例:
示例句子和标记
示例句子:
“张三在北京大学学习。”
我们需要标记以下几类实体:
- 人名 (
B-PER
,I-PER
) - 地名 (
B-LOC
,I-LOC
) - 组织名 (
B-ORG
,I-ORG
)
标记结果:
词 | 标签 |
---|---|
张 | B-PER |
三 | I-PER |
在 | O |
北京 | B-LOC |
大学 | I-LOC |
学习 | O |
BIO 标签解释
B-PER
: “张” 是人名的开始。I-PER
: “三” 是人名的后续部分。O
: “在” 和 “学习” 是普通词,不属于任何实体。B-LOC
: “北京” 是地名的开始。I-LOC
: “大学” 是地名的后续部分。
更复杂的中文例子
我们来看一个更复杂的例子,其中包含多种实体类型:
示例句子:
“李四在中国科学院工作,他的朋友王五在北京市政府工作。”
标记结果:
词 | 标签 |
---|---|
李 | B-PER |
四 | I-PER |
在 | O |
中国 | B-ORG |
科学院 | I-ORG |
工作 | O |
, | O |
他 | O |
的 | O |
朋友 | O |
王 | B-PER |
五 | I-PER |
在 | O |
北京 | B-LOC |
市政府 | I-LOC |
工作 | O |
。 | O |
BIO 标签解释
B-PER
: “李” 和 “王” 是人名的开始。I-PER
: “四” 和 “五” 是人名的后续部分。B-ORG
: “中国” 是组织名的开始。I-ORG
: “科学院” 是组织名的后续部分。B-LOC
: “北京” 是地名的开始。I-LOC
: “市政府” 是地名的后续部分。O
: 其他词都标记为O
,表示它们不属于任何命名实体。
可以说现在训练出来的对实体提取已经有不错的效果了
我们现在来看看使用 run_cmrc.py 进行机器阅读理解:
(这个其实就是训练本地知识库问答的一个东东)
python finetune/run_cmrc.py --pretrained_model_path models/google_zh_model.bin --vocab_path models/google_zh_vocab.txt --config_path models/bert/base_config.json --train_path datasets/cmrc2018/train.json --dev_path datasets/cmrc2018/dev.json --output_model_path models/cmrc_model.bin --epochs_num 2 --batch_size 8 --seq_length 512
我们不指定 --test_path ,因为CMRC2018数据集不提供测试集的标签。 然后,我们使用微调后的机器阅读理解模型进行推理:
python inference/run_cmrc_infer.py --load_model_path models/cmrc_model.bin --vocab_path models/google_zh_vocab.txt --config_path models/bert/base_config.json --test_path datasets/cmrc2018/test.json --prediction_path datasets/cmrc2018/prediction.json --seq_length 512
我大概浏览了一下可以发现,这一遍跑出来的问答效果非常的好,赞
7.分类任务交叉验证
UER-py支持分类任务的交叉验证,在竞赛数据集SMP2020-EWECT上使用交叉验证的示例:
python finetune/run_classifier_cv.py --pretrained_model_path models/google_zh_model.bin --vocab_path models/google_zh_vocab.txt --config_path models/bert/base_config.json --train_path datasets/smp2020-ewect/virus/train.tsv --train_features_path datasets/smp2020-ewect/virus/train_features.npy --output_model_path models/classifier_model.bin --epochs_num 3 --batch_size 32 --folds_num 5
由上图可知,google_zh_model.bin 的结果为79.9/65.46(准确率/F1值); --folds_num 指定交叉验证的轮数; --output_path 指定微调模型的路径,共保存 --folds_num 个微调后的模型,并将 fold ID 后缀添加到模型名称中; --train_features_path 指定out-of-fold预测文件的路径;训练集被分成了 --folds_num 折。一折样本的预测概率是由其他折上的数据训练的模型预测得到的。train_features.npy 可用于stacking集成。竞赛解决方案章节给出了更多详细信息。
我们可以进一步尝试不同的预训练模型。例如,可以下载RoBERTa-wwm-ext-large from HIT并将其转换为UER格式(这里的话我建议打开这个网址,直接去下载pytorch_model.bin,然后放在models下):
python scripts/convert_bert_from_huggingface_to_uer.py --input_model_path models/pytorch_model.bin --output_model_path models/pytorch_uer_model.bin --layers_num 24
python finetune/run_classifier_cv.py --pretrained_model_path models/pytorch_uer_model.bin --vocab_path models/google_zh_vocab.txt --config_path models/bert/large_config.json --train_path datasets/smp2020-ewect/virus/train.tsv --train_features_path datasets/smp2020-ewect/virus/train_features.npy --output_model_path models/classifier_model.bin --folds_num 5 --epochs_num 3 --batch_size 32
RoBERTa-wwm-ext-large 的结果为80.3/66.8(准确率/F1值)。注意到这里使用BERT-large的配置文件(–config_path models/bert/large_config.json)。
使用下载好的预训练模型评论语料RoBERTa-large的示例如下:
python finetune/run_classifier_cv.py --pretrained_model_path models/review_roberta_large_model.bin --vocab_path models/google_zh_vocab.txt --config_path models/bert/large_config.json --train_path datasets/smp2020-ewect/virus/train.tsv --train_features_path datasets/smp2020-ewect/virus/train_features.npy --output_model_path models/classifier_model.bin --folds_num 5 --learning_rate 1e-5 --epochs_num 3 --batch_size 32 --seed 11
结果为81.3/68.4(准确率/F1值),与其他开源预训练模型相比,这一结果很具有竞争力。这个预训练模型使用的语料和SMP2020-EWECT(微博评论数据集)高度相似。 有时大模型无法收敛,我们需要通过指定 --seed 尝试不同的随机种子
8.使用Transformer之外的编码器
UER-py支持Transformer之外的编码器。这里我们选择2层LSTM编码器来替代12层Transformer编码器。我们首先下载2层LSTM编码器的预训练模型cluecorpussmall_lstm_lm_model.bin。这个预训练模型在CLUECorpusSmall语料上训练了50万步(大家这里要去找开源人员申请,可以发邮箱过去,然后加联系方式),我这里还没申请到哈哈哈,大家就先看看代码吧:
python preprocess.py --corpus_path corpora/cluecorpussmall.txt --vocab_path models/google_zh_vocab.txt --dataset_path dataset.pt --processes_num 8 --seq_length 256 --data_processor lm
python pretrain.py --dataset_path dataset.pt --vocab_path models/google_zh_vocab.txt --config_path models/rnn/lstm_config.json --output_model_path models/cluecorpussmall_lstm_lm_model.bin --world_size 8 --gpu_ranks 0 1 2 3 4 5 6 7 --total_steps 500000 --save_checkpoint_steps 100000 --learning_rate 1e-3 --batch_size 64
把预训练模型记录训练步数的后缀去掉,然后在下游分类数据集上对其进行微调:
python finetune/run_classifier.py --pretrained_model_path models/cluecorpussmall_lstm_lm_model.bin --vocab_path models/google_zh_vocab.txt --config_path models/rnn/lstm_config.json --train_path datasets/book_review/train.tsv --dev_path datasets/book_review/dev.tsv --test_path datasets/book_review/test.tsv --learning_rate 1e-3 --epochs_num 5 --batch_size 64 --pooling mean
python inference/run_classifier_infer.py --load_model_path models/finetuned_model.bin --vocab_path models/google_zh_vocab.txt --config_path models/rnn/lstm_config.json --test_path datasets/book_review/test_nolabel.tsv --prediction_path datasets/book_review/prediction.tsv --pooling mean --labels_num 2
UER-py还支持更多的预训练模型。 我们下载ELMo预训练模型cluecorpussmall_elmo_model.bin。这个预训练模型在CLUECorpusSmall语料上训练了50万步:
python preprocess.py --corpus_path corpora/cluecorpussmall.txt --vocab_path models/google_zh_vocab.txt --dataset_path dataset.pt --processes_num 8 --seq_length 256 --data_processor bilm
python pretrain.py --dataset_path dataset.pt --vocab_path models/google_zh_vocab.txt --config_path models/rnn/bilstm_config.json --output_model_path models/cluecorpussmall_elmo_model.bin --world_size 1 --gpu_ranks 0 --total_steps 500000 --save_checkpoint_steps 100000 --learning_rate 5e-4 --batch_size 64
把预训练模型记录训练步数的后缀去掉,然后在书评情感分类数据集上对其进行增量预训练和微调:
python preprocess.py --corpus_path corpora/book_review.txt --vocab_path models/google_zh_vocab.txt --dataset_path dataset.pt --processes_num 8 --seq_length 192 --data_processor bilm
python pretrain.py --dataset_path dataset.pt --vocab_path models/google_zh_vocab.txt --pretrained_model_path models/cluecorpussmall_elmo_model.bin --config_path models/rnn/bilstm_config.json --output_model_path models/book_review_elmo_model.bin --world_size 1 --gpu_ranks 0 --total_steps 5000 --save_checkpoint_steps 2500 --learning_rate 5e-4 --batch_size 64
mv models/book_review_elmo_model.bin-5000 models/book_review_elmo_model.bin
python finetune/run_classifier.py --pretrained_model_path models/book_review_elmo_model.bin --vocab_path models/google_zh_vocab.txt --config_path models/rnn/bilstm_config.json --train_path datasets/book_review/train.tsv --dev_path datasets/book_review/dev.tsv --test_path datasets/book_review/test.tsv --learning_rate 5e-4 --epochs_num 5 --batch_size 64 --seq_length 192 --pooling max
python inference/run_classifier_infer.py --load_model_path models/finetuned_model.bin --vocab_path models/google_zh_vocab.txt --config_path models/rnn/bilstm_config.json --test_path datasets/book_review/test_nolabel.tsv --prediction_path datasets/book_review/prediction.tsv --seq_length 192 --pooling max --labels_num 2
corpora/book_review.txt 是由书评情感分类数据集去掉标签得到的。
在分类数据集上微调GatedCNN模型的示例:
python finetune/run_classifier.py --pretrained_model_path models/cluecorpussmall_gatedcnn_lm_model.bin --vocab_path models/google_zh_vocab.txt --config_path models/cnn/gatedcnn_9_config.json --train_path datasets/book_review/train.tsv --dev_path datasets/book_review/dev.tsv --test_path datasets/book_review/test.tsv --learning_rate 5e-5 --epochs_num 5 --batch_size 64 --pooling mean
python inference/run_classifier_infer.py --load_model_path models/finetuned_model.bin --vocab_path models/google_zh_vocab.txt --config_path models/cnn/gatedcnn_9_config.json --test_path datasets/book_review/test_nolabel.tsv --prediction_path datasets/book_review/prediction.tsv --pooling mean --labels_num 2
大家可以下载wikizh_gatedcnn_lm_model.bin,这个预训练模型在CLUECorpusSmall语料上训练了50万步:
python preprocess.py --corpus_path corpora/cluecorpussmall.txt --vocab_path models/google_zh_vocab.txt --dataset_path dataset.pt --processes_num 8 --seq_length 256 --data_processor lm
python pretrain.py --dataset_path dataset.pt --vocab_path models/google_zh_vocab.txt --config_path models/cnn/gatedcnn_9_config.json --output_model_path models/cluecorpussmall_gatedcnn_lm_model.bin --world_size 1 --gpu_ranks 0 --total_steps 500000 --save_checkpoint_steps 100000 --report_steps 100 --learning_rate 1e-4 --batch_size 64
9.使用GPT2模型微调
使用GPT-2模型微调下游任务示例:
用户可以从这里下载 cluecorpussmall_gpt2_seq1024_model.bin
python finetune/run_classifier.py --pretrained_model_path models/cluecorpussmall_gpt2_seq1024_model.bin-250000 --vocab_path models/google_zh_vocab.txt --config_path models/gpt2/config.json --train_path datasets/book_review/train.tsv --dev_path datasets/book_review/dev.tsv --test_path datasets/book_review/test.tsv --epochs_num 3 --batch_size 32 --pooling mean
10.使用不同的分词器和词典
在大多数情况下,我们使用 --vocab_path models/google_zh_vocab.txt 和 --tokenizer bert 组合进行分词。在项目的大多数脚本中, --tokenizer bert 作为默认的分词器被使用。因此我们通常不会显式的指定 --tokenizer 。这里我们展示更多的分词器和词典的使用方法。
–tokenizer bert 在处理中文的时候是基于字的。如果我们想得到基于词的预训练模型并基于其进行微调和推理,那么首先我们要对语料进行分词,词与词之间用空格分隔。然后,我们基于分词后的语料(corpora/book_review_seg.txt)构建词典:(这里的book_review_seg文件夹包括语料集我没找到,可能也是要申请才能拿的到,大家就先看看代码)
python scripts/build_vocab.py --corpus_path corpora/book_review_seg.txt --output_path models/book_review_word_vocab.txt --delimiter space --workers_num 8 --min_count 5
由于词与词之间用空格分隔,因此在预处理和预训练阶段需要使用 --tokenizer space 。基于词的模型预处理和预训练示例:
python preprocess.py --corpus_path corpora/book_review_seg.txt --vocab_path models/book_review_word_vocab.txt --tokenizer space --dataset_path book_review_word_dataset.pt --processes_num 8 --seq_length 128 --dynamic_masking --data_processor mlm
python pretrain.py --dataset_path book_review_word_dataset.pt --vocab_path models/book_review_word_vocab.txt --tokenizer space --config_path models/bert/base_config.json --output_model_path models/book_review_word_model.bin --world_size 1 --gpu_ranks 0 --total_steps 5000 --save_checkpoint_steps 2500 --report_steps 500 --learning_rate 1e-4 --batch_size 64 --data_processor mlm --target mlm --tie_weights
在下游任务微调和推理的过程中,我们同样需要显式的指定 --vocab_path models/book_review_word_vocab.txt 和 --tokenizer space ,并且数据集的训练/验证/测试集文本列(text_a和text_b)需要使用相同的分词工具进行分词。我们对 datasets/book_review/ 中的文件进行分词,放在 datasets/book_review_seg/ 文件夹中:
mv models/book_review_word_model.bin-5000 models/book_review_word_model.bin
python finetune/run_classifier.py --pretrained_model_path models/book_review_word_model.bin --vocab_path models/book_review_word_vocab.txt --tokenizer space --config_path models/bert/base_config.json --train_path datasets/book_review_seg/train.tsv --dev_path datasets/book_review_seg/dev.tsv --test_path datasets/book_review_seg/test.tsv --epochs_num 3 --batch_size 32
python inference/run_classifier_infer.py --load_model_path models/finetuned_model.bin --vocab_path models/book_review_word_vocab.txt --tokenizer space --config_path models/bert/base_config.json --test_path datasets/book_review_seg/test_nolabel.tsv --prediction_path datasets/book_review_seg/prediction.tsv --labels_num 2
使用SentencePiece分词示例:
python preprocess.py --corpus_path corpora/book_review.txt --spm_model_path models/cluecorpussmall_spm.model --dataset_path book_review_word_sentencepiece_dataset.pt --processes_num 8 --seq_length 128 --dynamic_masking --data_processor mlm
python pretrain.py --dataset_path book_review_word_sentencepiece_dataset.pt --spm_model_path models/cluecorpussmall_spm.model --output_model_path models/book_review_word_sentencepiece_model.bin --world_size 1 --gpu_ranks 0 --total_steps 5000 --save_checkpoint_steps 2500 --report_steps 500 --learning_rate 1e-4 --batch_size 64 -data_processor mlm --target mlm --tie_weights
mv models/book_review_word_sentencepiece_model.bin-5000 models/book_review_word_sentencepiece_model.bin
python finetune/run_classifier.py --pretrained_model_path models/book_review_word_sentencepiece_model.bin --spm_model_path models/cluecorpussmall_spm.model --config_path models/bert/base_config.json --train_path datasets/book_review/train.tsv --dev_path datasets/book_review/dev.tsv --test_path datasets/book_review/test.tsv --epochs_num 3 --batch_size 32
python inference/run_classifier_infer.py --load_model_path models/finetuned_model.bin --spm_model_path models/cluecorpussmall_spm.model --config_path models/bert/base_config.json --test_path datasets/book_review/test_nolabel.tsv --prediction_path datasets/book_review/prediction.tsv --labels_num 2
通过 --spm_model_path models/cluecorpussmall_spm.model 指定使用在CLUECorpusSmall语料上训练的SentencePiece分词模型。
如果使用基于字的分词方式,可以使用 --vocab_path models/google_zh_vocab.txt 和 --tokenizer char 的组合代替上面的 --spm_model_path models/cluecorpussmall_spm.model,其余的选项不变。 由于谷歌提供的词典 models/google_zh_vocab.txt 是基于字的,因此可以直接使用。
本项目支持多种分词(tokenization)方式。最常用的,也是项目默认使用的是BertTokenizer。BertTokenizer有两种使用方式:第一种是通过 --vocab_path 指定词典路径。然后使用BERT原始的tokenization策略,根据词典对句子进行切分;第二种是通过 --spm_model_path 指定sentencepiece模型路径,然后导入sentencepiece模块,加载sentencepiece模型,对句子进行切分。如果用户指定了 --spm_model_path ,那么使用sentencepiece进行tokeniztion。否则,用户必须指定 --vocab_path ,使用BERT原始的策略进行tokenization。
此外,本项目支持CharTokenizer和SpaceTokenizer。CharTokenizer将文本按照字符分开。如果文本全都是中文,则CharTokenizer和BertTokenizer等价。CharTokenizer逻辑简单,速度大于BertTokenizer。SpaceTokenizer将文本按照空格分开。可以事先对文本进行预处理(比如进行分词),将文本按照空格分开,然后使用SpaceTokenizer。对于CharTokenizer和SpaceTokenizer,如果用户指定了 --spm_model_path ,那么使用sentencepiece模型中的词典。否则,用户必须通过 --vocab_path 指定使用的词典。
为了支持加载英文RoBERTa和GPT-2等模型,本项目支持使用BPETokenizer对句子进行切分,通过 --vocab_path 指定使用的词典,通过 --merges_path 指定使用的合并词典。
本项目还支持XLMRobertaTokenizer(和原始实现一致)。XLMRobertaTokenizer使用sentencepiece模型对句子进行切分,通过 --spm_model_path 指定sentencepiece模型路径。此外,XLMRoBERTaTokenizer会对词典进行修改,加上特殊字符。由于XLMRobertaTokenizer使用了和默认情况不一致的特殊字符,需要按照下一段中提到的方法修改特殊字符。
预处理、预训练、下游任务微调、推理阶段均需要通过 --vocab_path 或者 --smp_model_path 提供词典信息以及通过 --tokenizer 提供分词方式信息。如果用户使用自己的词典,默认情况下,填充字符、起始字符、分隔字符、遮罩字符分别为“[PAD]”、“[CLS]”、“[SEP]”、“[MASK]”(项目从默认的特殊字符映射表 models/special_tokens_map.json 中读取特殊字符)。如果用户词典中的特殊字符和默认的不一致,需要相应的提供特殊字符映射表,比如 models/xlmroberta_special_tokens_map.json ,然后修改 uer/utils/constants.py 中的特殊字符映射表路径。
刚刚我们对实体标注进行了一定的拓展,现在我们来拓展一下分词器与字典的知识
分词(Tokenization)方式详解
分词是自然语言处理(NLP)中的一个关键步骤,它将文本数据拆分成更小的单位,称为“token”。这些token可以是单词、子词或字符,具体取决于所选的分词策略和目标任务。以下是该项目支持的几种分词方式的详细说明,并通过中文例子来帮助理解这些概念。
1. BertTokenizer
BertTokenizer 是专为 BERT 模型设计的分词器,能够处理复杂的语言结构和词语组合。BERT 的分词策略主要包括基于词典的切分和基于子词的切分。
使用方式一:通过 --vocab_path
指定词典路径
- 解释:这种方式使用预定义的词典来切分句子。词典包含了常见词语及其子词。
- 例子:
- 输入句子:
"我喜欢学习自然语言处理"
- 词典:
["我", "喜欢", "学习", "自然", "语言", "处理"]
- 分词结果:
["我", "喜欢", "学习", "自然", "语言", "处理"]
- 输入句子:
- 应用场景:这种方式适用于标准化语言处理任务,尤其是在处理结构良好的文本时效果较好。
使用方式二:通过 --spm_model_path
指定 SentencePiece 模型路径
- 解释:这使用了 SentencePiece 模型,可以将句子切分为子词单位,适合处理未登录词(词典中不存在的词)。
- 例子:
- 输入句子:
"我喜欢学习自然语言处理"
- 可能的分词结果:
["我", "喜", "欢", "学", "习", "自然", "语", "言", "处", "理"]
- 或:
["我", "喜", "欢", "学习", "自然", "语", "言", "处理"]
- 输入句子:
- 应用场景:这种方式对处理多语言和包含大量未登录词的文本非常有效。
2. CharTokenizer
CharTokenizer 将文本按照单个字符进行分割,特别适合处理字符级别的信息。
- 解释:对于中文文本,这种方式与 BertTokenizer 的效果相同,因为中文词汇本身是字符单位。对于其他语言,如英文,它将每个字符单独分割。
- 例子:
- 中文输入:
"我喜欢学习"
- 分词结果:
["我", "喜", "欢", "学", "习"]
- 英文输入:
"Hello"
- 分词结果:
["H", "e", "l", "l", "o"]
- 中文输入:
- 应用场景:CharTokenizer 适合处理文本的细粒度信息,特别是在需要逐字符分析的任务中,如语言生成或字符级模型。
3. SpaceTokenizer
SpaceTokenizer 按照空格将文本进行分割,这对于预处理过的文本特别有用。
- 解释:假设输入的文本已经经过分词处理(每个词之间有空格)。
- 例子:
- 输入句子:
"我 喜欢 学习 自然 语言 处理"
- 分词结果:
["我", "喜欢", "学习", "自然", "语言", "处理"]
- 输入句子:
- 应用场景:这种方式适用于已经进行了初步分词的文本,或者语言本身词与词之间有明显分隔符(如英文)。
4. BPETokenizer
BPETokenizer 使用 Byte Pair Encoding (BPE) 算法,将常见的词汇和短语进行合并,逐步生成词典。
- 解释:BPE 是一种子词级别的分词策略,可以处理新词和组合词。
- 例子:
- 输入句子:
"我喜欢自然语言处理"
- 词典:
{"我", "喜欢", "自然", "语言", "处理", "自", "然", "语", "言"}
- 分词结果:
["我", "喜欢", "自然", "语言", "处理"]
- 对于新词:
"机器学习"
可能会分成["机", "器", "学习"]
或["机器", "学习"]
,取决于词典。
- 输入句子:
- 应用场景:BPETokenizer 适合处理拼写变体和复合词,广泛用于支持多语言的模型,如 RoBERTa 和 GPT-2。
5. XLMRobertaTokenizer
XLMRobertaTokenizer 是为 XLM-RoBERTa 模型设计的,使用 SentencePiece 模型进行分词,并支持特殊字符的处理。
- 解释:它在分词的同时,会对词典进行修改,加入特殊字符(如句子的起始和结束标志)。
- 例子:
- 输入句子:
"我喜欢学习自然语言处理"
- 分词结果:
["[CLS]", "我", "喜欢", "学习", "自然", "语言", "处理", "[SEP]"]
- 输入句子:
- 应用场景:这种分词器适用于需要处理多语言和跨语言任务的场景,特别是在使用 XLM-RoBERTa 模型时。
特殊字符和映射
在分词和文本处理过程中,特殊字符起到标记和控制的作用:
- [PAD]:填充字符,用于对齐不同长度的句子。
- [CLS]:分类标志,一般放在句子的开头,表示句子的开始。
- [SEP]:分隔标志,用于分隔句子或句子片段。
- [MASK]:掩蔽标志,用于模型在训练时预测被掩盖的词。
特殊字符的应用
- 默认设置:项目中的特殊字符映射表通常存储在
models/special_tokens_map.json
中。 - 自定义词典:如果使用了自定义词典,且特殊字符与默认字符不一致,需要提供对应的特殊字符映射表,例如
models/xlmroberta_special_tokens_map.json
,并修改uer/utils/constants.py
中的路径以匹配新的词典。
拓展2:base_config参数详解
这个参数配置描述了一个用于自然语言处理(NLP)任务的Transformer模型。让我们详细解释这些参数:
模型架构参数
-
emb_size(嵌入层大小): 768
- 这是模型的词嵌入维度,也就是每个词被表示成一个768维的向量。这些向量是模型学习的,能够捕捉词的语义特征。
-
feedforward_size(前馈神经网络层大小): 3072
- Transformer中每层的前馈神经网络(FFN)的隐藏层大小。在这个例子中是3072,通常是嵌入层大小的4倍。FFN帮助模型在每一层提取复杂的特征。
-
hidden_size(隐藏层大小): 768
- 定义了Transformer模型中每层的隐藏状态的维度,也就是模型内部的表示维度,与emb_size相同。
-
hidden_act(隐藏层激活函数): gelu
- 这是模型中使用的激活函数。在这里是gelu(高斯误差线性单元),它是一种平滑的非线性函数,通常在Transformer模型中使用,因为它有更好的训练效果。
-
heads_num(注意力头的数量): 12
- 这是多头自注意力机制的头数。在这个模型中有12个头,这意味着模型会在每个位置计算12个不同的注意力分布,从而捕捉到更多的上下文信息。
-
layers_num(层数): 12
- 这是Transformer模型的层数,表示模型由12层堆叠的Transformer编码器层组成。每层都包含一个多头自注意力机制和一个前馈神经网络。
-
max_seq_length(最大序列长度): 512
- 这是模型可以处理的输入序列的最大长度。输入文本被截断或填充到这个长度。在这个例子中,最长的输入序列是512个标记(tokens)。
-
dropout(随机失活率): 0.1
- 用于正则化的技术,在训练时随机丢弃10%的神经元连接,以防止模型过拟合。
数据处理和输入参数
-
data_processor(数据处理器): bert
- 这里的bert表示使用类似BERT模型的数据处理方法,包括分词、输入格式化等。
-
embedding(嵌入方式): [“word”, “pos”, “seg”]
- 这定义了输入的嵌入表示,包括词嵌入(word)、位置嵌入(pos)和分段嵌入(seg)。这些嵌入帮助模型理解输入文本的结构和内容:
- word: 每个词的词嵌入。
- pos: 每个词在句子中的位置(位置信息)。
- seg: 句子分段嵌入,用于区分输入中的不同句子(例如,问句和回答句)。
- 这定义了输入的嵌入表示,包括词嵌入(word)、位置嵌入(pos)和分段嵌入(seg)。这些嵌入帮助模型理解输入文本的结构和内容:
-
encoder(编码器): transformer
- 使用Transformer架构作为模型的编码器。Transformer通过自注意力机制和前馈神经网络层来处理输入数据。
-
mask(掩码机制): fully_visible
- 表示所有输入的位置在自注意力中都是可见的。对于BERT的掩码语言模型任务,所有标记的位置都可以关注到其他标记的位置。
目标和训练参数
-
target(目标): [“mlm”, “sp”]
- 这些是模型的训练目标,包括:
- mlm(Masked Language Modeling): 掩码语言模型任务,模型通过预测被掩盖的词来学习上下文。
- sp(Sentence Prediction): 句子预测任务,通常是BERT的下一句预测任务(NSP),用来预测两个句子是否是连续的。
- 这些是模型的训练目标,包括:
-
tie_weights(权重共享): true
- 这表示词嵌入层和输出层之间共享权重。共享权重可以减少模型的参数数量,提高训练效率,并且通常有助于模型的泛化能力。
例子
为了更好地理解这些参数,我们可以对照BERT模型:
- BERT Base的常见配置:
emb_size
: 768feedforward_size
: 3072hidden_size
: 768hidden_act
: geluheads_num
: 12layers_num
: 12max_seq_length
: 512dropout
: 0.1data_processor
: bertembedding
: [“word”, “pos”, “seg”]encoder
: transformermask
: fully_visibletarget
: [“mlm”, “sp”]tie_weights
: true
遇到的问题
我在做文本预训练的过程中碰到了一个问题。用pycharm打开预处理好的.pt文件出现乱码,我调了utf-8格式也解决不了。不知道有没有大佬赐教?
我检查过文件的“魔数”,是没问题的
于是我尝试过用torch加载它,可是不行
import torch
import osfile_path = 'dataset.pt'# 检查文件是否存在
if not os.path.exists(file_path):print(f"File not found: {file_path}")
else:# 查看文件大小file_size = os.path.getsize(file_path)print(f"File size: {file_size} bytes")# 读取文件头部信息with open(file_path, 'rb') as f:header = f.read(4)print(f"File header: {header}")try:# 尝试加载文件data = torch.load(file_path, map_location=torch.device('cpu'))print(data)except Exception as e:print(f"Failed to load the file: {e}")
Traceback (most recent call last):File "D:\uer\UER-py-master\UER-py-master\check.py", line 4, in <module>model = torch.load('dataset.pt')^^^^^^^^^^^^^^^^^^^^^^^^File "D:\ancanda\envs\pytorch-gpu\Lib\site-packages\torch\serialization.py", line 1040, in loadreturn _legacy_load(opened_file, map_location, pickle_module, **pickle_load_args)^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^File "D:\ancanda\envs\pytorch-gpu\Lib\site-packages\torch\serialization.py", line 1264, in _legacy_loadraise RuntimeError("Invalid magic number; corrupt file?")
RuntimeError: Invalid magic number; corrupt file?
相关文章:

三万字带你一遍跑通uer
三万字带你一遍跑通uer 参考文档 今天给大家介绍个非常强大的项目uer,集成了许多可以做自然语言的东西,效果的话也非常好,很适合企业级的应用! 1. 先将项目uer从github拉取下来(zip或git都ok) 2. 用pycha…...

Ubuntu24.04LTS基础软件下载
librewolf: deb文件link 作用:访问github,无痕浏览,这个速度,不指望了 vscodium: 从deb安装,ubuntu sudo dpkg -i xxx.debpaste-image 插件替代 markdown wps: libreoffice: 替换USTC源 sudo nano /etc/apt/sourc…...
SQLAlchemy配置连接多个数据库
1.定义配置项 首先定义两个数据库的配置信息 # PostgreSQL database configuration DB_USERNAMEpostgres DB_PASSWORDpassord DB_HOST127.0.0.1 DB_PORT5432 DB_DATABASEtest# mysql database configuration DB_USERNAME_MYSQLroot DB_PASSWORD_MYSQLpassword DB_HOST_MYSQL127…...
NLP+LLM从入门到精通系列
NLPLLM从入门到精通系列 前言:笔者从事于NLPLLM的对话智能机器人的相关行业,现在的大模型的技术日新月异,传统的NLP业务显然是要被淘汰的,那么这也是我着笔写这一系列文章的初衷。本系列将由浅到深,结合实际代码案例&…...
用数组手搓一个小顶堆
堆默认从数组下标为1开始存储。 const int N201000; int heap[N]; int len; 插入操作: 将元素插入到堆的末尾位置向上调整。 void up(int k){while(k>1&&heap[k/2]>heap[k]){swap(heap[k],heap[k/2]);k/2;} } //len为当前存在元素长度 void Inser…...

【Linux开发】基于ALSA库实现音量调节
基于ALSA库实现音量调节 ALSA库实现音量调节1、使用alsamixer工具查看音频接口2、完整代码2.1、snd_mixer_open2.2、snd_mixer_attach、2.3、snd_mixer_selem_register2.4、snd_mixer_load2.5、snd_mixer_first_elem/snd_mixer_elem_next2.6、snd_mixer_selem_get_playback_vol…...
代理IP在未来将面临哪些挑战?
今天我们来聊聊代理IP在未来可能会面临的挑战。虽然代理IP技术目前应用广泛,但随着科技的发展和网络环境的变化,代理IP也将面临一些新的挑战。让我们一起来看看这些挑战是什么吧! 1. 更严格的网络封锁和检测 现代社会各行各业都在飞速发展&…...

FineBI在线学习资源-数据处理
FineBI在线学习资源汇总: 学习资源 视频课程 帮助文档 问答 数据处理学习文档: 相关资料: 故事背景概述-https://help.fanruan.com/finebi6.0/doc-view-1789.html 基础表处理-https://help.fanruan.com/finebi6.0/doc-view-1791.html …...
【代码随想录算法训练营第37期 第四十五天 | LeetCode198.打家劫舍、213.打家劫舍II、337.打家劫舍III】
代码随想录算法训练营第37期 第四十五天 | LeetCode198.打家劫舍、213.打家劫舍II、337.打家劫舍III 一、198.打家劫舍 解题代码C: class Solution { public:int rob(vector<int>& nums) {if (nums.size() 0) return 0;if (nums.size() 1) return num…...
Elasticsearch查询上下文和_source
查询上下文 {"took": 1,"timed_out": false,"_shards": {"total": 1,"successful": 1,"skipped": 0,"failed": 0},"hits": {"total": {"value": 1,"relation"…...
golang实现网卡流量监控
获取当前时刻一分钟前的网卡流量排序 package mainimport ("fmt""github.com/mackerelio/go-osstat/network""log""net/http""sort""strconv""time" )var arr []map[string]int var arr2 []map[string]…...

技术分享:直播平台如何开发并接入美颜SDK
本篇文章,笔者将分享直播平台如何开发并接入美颜SDK的技术细节与步骤。 一、选择合适的美颜SDK 首先,选择一款适合的美颜SDK非常重要。市面上有很多优秀的美颜SDK供应商,选择时应考虑以下因素: 功能丰富性:支持美白…...
左耳听风_114_113_Go编程模式修饰器
你好,我是陈浩,我名多尔多house.之前呢我写过一篇文章叫做python修饰器的函数式编程。 那这种模式呢可以很轻松的把一些函数啊装配到另外一些函数上。 让你的代码呢更加简单,也可以让一些小功能性的代码复用性更高。 让代码中的函数呢可以…...

Java实习手册(小白也看得懂)
秃狼说 距离俺发布的学习路线已经六个月了,那我给小伙伴的学习周期是四五个月左右,我相信大多的小伙伴已经学习的差不多了。正好赶上暑期实习的阶段,在暑期找到实习就成为暑期的头等大事。 实习经验在校招的起到决定性的作用,所…...
Elasticsearch 分析器(Analyzer)的作用和配置
在Elasticsearch中,分析器(Analyzer)是文本处理的核心组件,它负责将输入的文本转换为可用于搜索和索引的词项(tokens)。这一过程涉及多个步骤,包括字符过滤、分词和标记过滤,共同决定…...

SpringBoot(一)创建一个简单的SpringBoot工程
Spring框架常用注解简单介绍 SpringMVC常用注解简单介绍 SpringBoot(一)创建一个简单的SpringBoot工程 SpringBoot(二)SpringBoot多环境配置 SpringBoot(三)SpringBoot整合MyBatis SpringBoot(四…...
简述Vue中的数据双向绑定原理
Vue中的数据双向绑定原理是Vue框架的核心特性之一,它通过数据劫持结合发布者-订阅者模式来实现。下面将详细阐述Vue中数据双向绑定的原理,并尽量按照清晰的结构进行归纳: 一、数据劫持 使用Object.defineProperty(): Vue在组件…...
C++STL函数对象的应用
STL函数对象 文章目录 STL函数对象1.基本概念2.使用方法1. 简单函数对象示例2. 函数对象作为算法参数3. Lambda表达式作为函数对象 2.一元谓词和二元谓词1.一元谓词2.二元谓词3.总结 3.算术仿函数1.使用示例2.Lambda表达式的替代 4.关系仿函数5.逻辑仿函数 C中的函数对象&#…...

AJAX-day1:
注:文件布局: 一、AJAX的概念: AJAX是浏览器与服务器进行数据通信的技术 >把数据变活 二、AJAX的使用: 使用axios库,与服务器进行数据通信 基于XMLHttpRequest封装,代码简单 Vue,React项目使用 学习…...

昆虫学(书籍学习资料)
包括昆虫分类(上下册)、昆虫生态大图鉴等书籍资料。...
web vue 项目 Docker化部署
Web 项目 Docker 化部署详细教程 目录 Web 项目 Docker 化部署概述Dockerfile 详解 构建阶段生产阶段 构建和运行 Docker 镜像 1. Web 项目 Docker 化部署概述 Docker 化部署的主要步骤分为以下几个阶段: 构建阶段(Build Stage):…...
<6>-MySQL表的增删查改
目录 一,create(创建表) 二,retrieve(查询表) 1,select列 2,where条件 三,update(更新表) 四,delete(删除表…...

STM32F4基本定时器使用和原理详解
STM32F4基本定时器使用和原理详解 前言如何确定定时器挂载在哪条时钟线上配置及使用方法参数配置PrescalerCounter ModeCounter Periodauto-reload preloadTrigger Event Selection 中断配置生成的代码及使用方法初始化代码基本定时器触发DCA或者ADC的代码讲解中断代码定时启动…...
Spring AI 入门:Java 开发者的生成式 AI 实践之路
一、Spring AI 简介 在人工智能技术快速迭代的今天,Spring AI 作为 Spring 生态系统的新生力量,正在成为 Java 开发者拥抱生成式 AI 的最佳选择。该框架通过模块化设计实现了与主流 AI 服务(如 OpenAI、Anthropic)的无缝对接&…...
3403. 从盒子中找出字典序最大的字符串 I
3403. 从盒子中找出字典序最大的字符串 I 题目链接:3403. 从盒子中找出字典序最大的字符串 I 代码如下: class Solution { public:string answerString(string word, int numFriends) {if (numFriends 1) {return word;}string res;for (int i 0;i &…...
浅谈不同二分算法的查找情况
二分算法原理比较简单,但是实际的算法模板却有很多,这一切都源于二分查找问题中的复杂情况和二分算法的边界处理,以下是博主对一些二分算法查找的情况分析。 需要说明的是,以下二分算法都是基于有序序列为升序有序的情况…...

mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包
文章目录 现象:mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包遇到 rpm 命令找不到已经安装的 MySQL 包时,可能是因为以下几个原因:1.MySQL 不是通过 RPM 包安装的2.RPM 数据库损坏3.使用了不同的包名或路径4.使用其他包…...

GC1808高性能24位立体声音频ADC芯片解析
1. 芯片概述 GC1808是一款24位立体声音频模数转换器(ADC),支持8kHz~96kHz采样率,集成Δ-Σ调制器、数字抗混叠滤波器和高通滤波器,适用于高保真音频采集场景。 2. 核心特性 高精度:24位分辨率,…...

淘宝扭蛋机小程序系统开发:打造互动性强的购物平台
淘宝扭蛋机小程序系统的开发,旨在打造一个互动性强的购物平台,让用户在购物的同时,能够享受到更多的乐趣和惊喜。 淘宝扭蛋机小程序系统拥有丰富的互动功能。用户可以通过虚拟摇杆操作扭蛋机,实现旋转、抽拉等动作,增…...

Rust 开发环境搭建
环境搭建 1、开发工具RustRover 或者vs code 2、Cygwin64 安装 https://cygwin.com/install.html 在工具终端执行: rustup toolchain install stable-x86_64-pc-windows-gnu rustup default stable-x86_64-pc-windows-gnu 2、Hello World fn main() { println…...