【GPT】文本生成任务(生成摘要、文本纠错、机器翻译等的模型微调)

news2024/10/6 7:36:51

note

文章目录

  • note
  • 一、NLG任务
  • 二、NLG之文本摘要
    • 2.1 基于mT5的文本摘要
    • 2.2 基于openai接口测试
    • 2.3 基于chatGPT接口
  • 三、根据自己的数据集进行模型微调
  • 四、文本纠错任务
  • 五、机器翻译任务
  • Reference

一、NLG任务

NLG:自然语言生成任务,很多NLP任务可以被描述为NLG任务,如经典的T5模型(text to text transfer transformer模型)就是NLG模型,如文本纠错任务,输出正确的文本描述、智能问答根据一定背景进行推理,然后回答。

# 安装一些必要的包
!pip install openai
# torch install 命令 https://pytorch.org/get-started/locally/
!pip install torch==2.0.0+cpu torchvision==0.15.1+cpu --extra-index-url https://download.pytorch.org/whl/cpu
!pip install tokenizers==0.13.2
!pip install transformers==4.27.4
!pip install --no-binary=protobuf protobuf==3.20.1
!pip install sentencepiece==0.1.97
!pip install shap==2.8.2
# 配置openai api key
import openai
OPENAI_API_KEY = "填入专属的API key"  # TODO
openai.api_key = OPENAI_API_KEY

models = openai.Model.list()
# 有60+个模型,fine-tune模型是以ft-personal开头
print([x.id for x in models.data])

二、NLG之文本摘要

主要分为三种:

  • 抽取式摘要:从原文档中提取现成的句子作为摘要句。
  • 压缩式摘要:对原文档的冗余信息进行过滤,压缩文本作为摘要。
  • 生成式摘要:基于NLG技术,根据源文档内容,由算法模型自己生成自然语言描述。

2.1 基于mT5的文本摘要

这里先使用huggingface进行测试:

''''''
import re
import torch
from transformers import AutoTokenizer, AutoModelForSeq2SeqLM

# 载入模型
tokenizer = AutoTokenizer.from_pretrained("csebuetnlp/mT5_multilingual_XLSum")
model = AutoModelForSeq2SeqLM.from_pretrained("csebuetnlp/mT5_multilingual_XLSum")

WHITESPACE_HANDLER = lambda k: re.sub('\s+', ' ', re.sub('\n+', ' ', k.strip()))

text = """全球游戏用户已经达到37亿,占到全球人口的一半,这是一个非常庞大的市场,这个市场完全值得我们去关注和应用,其中休闲游戏用户又占了很大的比例。为什么休闲游戏用户能够占那么大的比例,且还在不断增长呢?我们拿短视频迅猛的发展来举例。现在大家生活节奏很快,压力也很大,用户需要一些轻松快乐的体验来缓解压力、调整情绪。短视频的体验就非常轻松,想看就看,想停就停,看的时候可以给人带来快乐,还可以让你学到一些东西。在大数据的加持下,不断推给用户想看的东西,甚至让用户停不下来。休闲游戏也是类似的,休闲游戏本质上也是轻松,可以带来快乐并帮助用户减压的,而且休闲游戏比短视频有一个优势是其提供的各种各样的核心玩法,具备更多交互元素和不同的体验。"""
text = WHITESPACE_HANDLER(text)
input_ids = tokenizer([text], return_tensors="pt", padding="max_length", truncation=True, max_length=512)["input_ids"]

# 生成结果文本
output_ids = model.generate(input_ids=input_ids, max_length=84, no_repeat_ngram_size=2, num_beams=4)[0]
output_text = tokenizer.decode(output_ids, skip_special_tokens=True, clean_up_tokenization_spaces=False)

print("原始文本: ", text)
print("摘要文本: ", output_text)
# 摘要文本:  休闲游戏已经成为人们生活中不可或缺的一部分。

2.2 基于openai接口测试

def summarize_text(text):
    response = openai.Completion.create(
        engine="text-davinci-003",
        prompt=f"请对以下文本进行总结,注意总结的凝炼性,将总结字数控制在20个字以内:\n{text}",
        temperature=0.7,
        max_tokens=500,
    )

    summarized_text = response.choices[0].text.strip()
    return summarized_text

text = "全球游戏用户已经达到37亿,占到全球人口的一半,这是一个非常庞大的市场,这个市场完全值得我们去关注和应用,其中休闲游戏用户又占了很大的比例。为什么休闲游戏用户能够占那么大的比例,且还在不断增长呢?我们拿短视频迅猛的发展来举例。现在大家生活节奏很快,压力也很大,用户需要一些轻松快乐的体验来缓解压力、调整情绪。短视频的体验就非常轻松,想看就看,想停就停,看的时候可以给人带来快乐,还可以让你学到一些东西。在大数据的加持下,不断推给用户想看的东西,甚至让用户停不下来。休闲游戏也是类似的,休闲游戏本质上也是轻松,可以带来快乐并帮助用户减压的,而且休闲游戏比短视频有一个优势是其提供的各种各样的核心玩法,具备更多交互元素和不同的体验。"""
output_text = summarize_text(text)
print("原始文本: ", text)
print("摘要文本: ", output_text)
print("摘要文本长度: ", len(output_text))
# 摘要文本:  全球游戏用户已达37亿,休闲游戏占比很大且不断增长,因其轻松快乐的体验及大数据推送,可缓解生活压力并学习新知识。
# 摘要文本长度:  56

2.3 基于chatGPT接口

def summarize_text(text):
    content = f"请对以下文本进行总结,注意总结的凝炼性,将总结字数控制在20个字以内:\n{text}"
    response = openai.ChatCompletion.create(
        model="gpt-3.5-turbo",
        messages=[{"role": "user", "content": content}]
    )
    summarized_text = response.get("choices")[0].get("message").get("content")
    return summarized_text

text = """全球游戏用户已经达到37亿,占到全球人口的一半,这是一个非常庞大的市场,这个市场完全值得我们去关注和应用,其中休闲游戏用户又占了很大的比例。为什么休闲游戏用户能够占那么大的比例,且还在不断增长呢?我们拿短视频迅猛的发展来举例。现在大家生活节奏很快,压力也很大,用户需要一些轻松快乐的体验来缓解压力、调整情绪。短视频的体验就非常轻松,想看就看,想停就停,看的时候可以给人带来快乐,还可以让你学到一些东西。在大数据的加持下,不断推给用户想看的东西,甚至让用户停不下来。休闲游戏也是类似的,休闲游戏本质上也是轻松,可以带来快乐并帮助用户减压的,而且休闲游戏比短视频有一个优势是其提供的各种各样的核心玩法,具备更多交互元素和不同的体验。"""
output_text = summarize_text(text)

print("原始文本: ", text)
print("摘要文本: ", output_text)
print("摘要文本长度: ", len(output_text))
# 注意,chatgpt并不能完美限制摘要输出的字数
# 摘要文本:  全球游戏用户超37亿,休闲游戏用户增长迅速,因为轻松解压,且提供多样化体验。
# 摘要文本长度:  38

从上面的三种方法结果对比,可以发现huggingface的预训练模型mT5结果其实还不太好,后面两种结果挺好,还概括出游戏受欢迎的原因。

三、根据自己的数据集进行模型微调

数据集来源:CSL摘要数据集,是计算机领域的论文摘要和标题数据,包含3500条数据,

  • 标题:平均字数 18,字数标准差 4,最大字数41,最小数字 6;
  • 正文:平均字数 200,字数标准差 63,最大字数 631,最小数字 41;

这里我们根据自己的数据集进行模型微调,3500条数据,每个数据都包括titlecontent两个内容。data列表中每个元素是一个含有这两坨的字典。
数据源地址:https://github.com/liucongg/GPT2-NewsTitle 项目中的CSL摘要数据集

import json
with open('/home/andy/torch_rechub_n/hug_llm/content/dataset/csl_data.json', 'r', encoding='utf-8') as f:
    data = json.load(f)
len(data) # 3500

data[0]
{'title': '保细节的网格刚性变形算法',
 'content': '提出了一种新的保细节的变形算法,可以使网格模型进行尽量刚性的变形,以减少变形中几何细节的扭曲.首先根据网格曲面局部细节的丰富程度,对原始网格进行聚类生成其简化网格;然后对简化网格进行变形,根据其相邻面片变形的相似性,对简化网格作进一步的合并,生成新的变形结果,将该变形传递给原始网格作为初始变形结果.由于对属于同一个类的网格顶点进行相同的刚性变形,可在变形中较好地保持该区域的表面细节,但分属不同类的顶点之间会出现变形的不连续.为此,通过迭代优化一个二次能量函数,对每个网格顶点的变形进行调整来得到最终变形结果.实验结果显示,该算法简单高效,结果令人满意.'}

import pandas as pd
df = pd.DataFrame(data)
df = df[['content', 'title']]
df.columns = ["prompt", "completion"]
df_train = df.iloc[:500]
df_train.head(5)

在这里插入图片描述

file_path = "/home/andy/torch_rechub_n/hug_llm/content/dataset"
df_train.to_json(file_path + "/csl_summarize_finetune.jsonl", \
                 orient='records', lines=True, force_ascii=False)

!openai tools fine_tunes.prepare_data -f /home/andy/torch_rechub_n/hug_llm/content/dataset/csl_summarize_finetune.jsonl -q
file_path = "/home/andy/torch_rechub_n/hug_llm/content/dataset"
!openai api fine_tunes.create \
    -t "/home/andy/torch_rechub_n/hug_llm/content/dataset/csl_summarize_finetune_prepared.jsonl" \
    -m ada\
    --no_check_if_files_exist

huggingface/tokenizers: The current process just got forked, after parallelism has already been used. Disabling parallelism to avoid deadlocks...
To disable this warning, you can either:
	- Avoid using `tokenizers` before the fork if possible
	- Explicitly set the environment variable TOKENIZERS_PARALLELISM=(true | false)
Upload progress: 100%|███████████████████████| 380k/380k [00:00<00:00, 841Mit/s]
Uploaded file from /home/andy/torch_rechub_n/hug_llm/content/dataset/csl_summarize_finetune_prepared.jsonl: file-cNMh8V9gYipAoLlqgoL0upll
Created fine-tune: ft-6IqMLGVl0FXEWifOvBsY0Aoc
Streaming events until fine-tuning is complete...

(Ctrl-C will interrupt the stream, but not cancel the fine-tune)
[2023-04-25 02:48:37] Created fine-tune: ft-6IqMLGVl0FXEWifOvBsY0Aoc
[2023-04-25 02:48:49] Fine-tune costs $0.43
[2023-04-25 02:48:50] Fine-tune enqueued. Queue number: 2

从上面得到fine tune运行所需的key:

!openai api fine_tunes.get -i ft-6IqMLGVl0FXEWifOvBsY0Aoc
# 保存openai fine tune过程的记录
!openai api fine_tunes.results -i ft-6IqMLGVl0FXEWifOvBsY0Aoc > /home/andy/torch_rechub_n/hug_llm/content/dataset/metric.csv

# 后面的执行步骤是和之前一致的
# game text
def summarize_text(text, model_name):
    response = openai.Completion.create(
        engine=model_name,
        prompt=f"请对以下文本进行总结,注意总结的凝炼性,将总结字数控制在20个字以内:\n{text}",
        temperature=0.7,
        max_tokens=100,
    )

    summarized_text = response.choices[0].text.strip()
    return summarized_text

text = "全球游戏用户已经达到37亿,占到全球人口的一半,这是一个非常庞大的市场,这个市场完全值得我们去关注和应用,其中休闲游戏用户又占了很大的比例。为什么休闲游戏用户能够占那么大的比例,且还在不断增长呢?我们拿短视频迅猛的发展来举例。现在大家生活节奏很快,压力也很大,用户需要一些轻松快乐的体验来缓解压力、调整情绪。短视频的体验就非常轻松,想看就看,想停就停,看的时候可以给人带来快乐,还可以让你学到一些东西。在大数据的加持下,不断推给用户想看的东西,甚至让用户停不下来。休闲游戏也是类似的,休闲游戏本质上也是轻松,可以带来快乐并帮助用户减压的,而且休闲游戏比短视频有一个优势是其提供的各种各样的核心玩法,具备更多交互元素和不同的体验。"""
print("一、原始文本: ", text, "\n")
print("二、ada摘要文本: ", summarize_text(text, model_name='ada'), "\n")
# print("ada fine-tune摘要文本: ", summarize_text(text, model_name='ada:ft-personal-2023-04-15-13-29-50'))
# # ft model: ada:ft-personal-2023-04-25-02-56-14
print("三、ada fine-tune摘要文本: ", summarize_text(text, model_name='ada:ft-personal-2023-04-25-02-56-14'))

二、ada摘要文本:  因此,多达到休闲游戏的最佳解决方式是在推给用户带来快乐的时候,提醒一个人做好改进活动。

三、ada fine-tune摘要文本:  休闲游戏产品的结构和价值出现在游戏的结构上的字数较偏高的地位。有类似的游戏主题非演讲系

四、文本纠错任务

如飞机写错为灰机。常见的文本纠错技术主要有以下几种:

  • 基于规则的文本纠错技术:在数据库中加入常见错误的映射,如金字塔和金子塔,但耗时耗力;
  • 基于语言模型的文本纠错技术:如Kenlm模型
    • 错误检测:使用jieba中文分词器对句子进行切词,然后结合字粒度和词粒度两方面的疑似错误结果,形成疑似错误位置候选集。
    • 错误纠正:遍历所有的候选集并使用音似、形似词典替换错误位置的词,然后通过语言模型计算句子困惑度,最后比较并排序所有候选集结果,得到最优纠正词。
  • 基于MLM的文本纠错技术:bert就使用了Masked Language Model掩码语言模型(MLM)及Next Sentence Prediction下一句预测(NSP)两个任务,其中MLM任务中有15%*10%的Token会被替换为随机的其他词汇,迫使模型更多地依赖于上下文信息去预测Mask词汇,在一定程度上赋予了模型纠错能力。
    • 可以针对MLM, 将输入设计为错误词汇,输出为正确词汇,进fine tune,参考ACL2020的Soft-Masked BERT模型
  • 于NLG的文本纠错技术:mask方法只能用于输入和输出等长的情况,可以在bert后嵌入一层transformer decoder,将文本纠错,转为将错误的文本翻译为正确文本

pycorrector是一个文本纠错工具集,内置了KenLM、MacBERT、Transformer等多种文本纠错模型。

  • pycorrector的项目地址:https://github.com/shibing624/pycorrector
  • 一个基于MacBERT的线上Demo:https://huggingface.co/spaces/shibing624/pycorrector

  pycorrector不仅可以通过“import pycorrector”调用,也提供了Huggingface的预训练模型调用方式,以下是一个基于Huggingface的MacBERT4CSC调用样例。

# 1. 预训练模型
from transformers import BertTokenizer, BertForMaskedLM

# 载入模型
tokenizer = BertTokenizer.from_pretrained("shibing624/macbert4csc-base-chinese")
model = BertForMaskedLM.from_pretrained("shibing624/macbert4csc-base-chinese")

# text = "作为学生,一定要学习好学校的课乘!"
text = "重庆是一个好地方,今天天气好,适合除去玩"
input_ids = tokenizer([text], padding=True, return_tensors='pt')

# 生成结果文本
with torch.no_grad():
    outputs = model(**input_ids)
output_ids = torch.argmax(outputs.logits, dim=-1)
output_text = tokenizer.decode(output_ids[0], skip_special_tokens=True).replace(' ', '')

print("原始文本: ", text)
print("纠错文本: ", output_text)
# 原始文本:  重庆是一个好地方,今天天气好,适合除去玩
# 纠错文本:  重庆是一个好地方,今天天气好,适合出去玩

# 查看修改点
import operator
def get_errors(corrected_text, origin_text):
    sub_details = []
    for i, ori_char in enumerate(origin_text):
        if ori_char in [' ', '“', '”', '‘', '’', '琊', '\n', '…', '—', '擤']:
            # add unk word
            corrected_text = corrected_text[:i] + ori_char + corrected_text[i:]
            continue
        if i >= len(corrected_text):
            continue
        if ori_char != corrected_text[i]:
            if ori_char.lower() == corrected_text[i]:
                # pass english upper char
                corrected_text = corrected_text[:i] + ori_char + corrected_text[i + 1:]
                continue
            sub_details.append((ori_char, corrected_text[i], i, i + 1))
    sub_details = sorted(sub_details, key=operator.itemgetter(2))
    return corrected_text, sub_details

correct_text, details = get_errors(output_text[:len(text)], text)
print(details)

# 2. 基于OpenAI接口的文本纠错实验
def correct_text(text):
    content = f"请对以下文本进行文本纠错:\n{text}"
    response = openai.ChatCompletion.create(
        model="gpt-3.5-turbo", 
        messages=[{"role": "user", "content": content}]
    )
    corrected_text = response.get("choices")[0].get("message").get("content")
    return corrected_text

# text = "作为学生,一定要学习好学校的课乘!"
text = "重庆是一个好地方,今天天气好,适合除去玩"
output_text = correct_text(text)
print("原始文本: ", text)
print("纠错文本: ", output_text)

五、机器翻译任务

  • 基于规则的方法
  • 基于统计的方法
  • 基于神经网络的方法
# 1. huggingface的pre-trained model
from transformers import AutoTokenizer, AutoModelForSeq2SeqLM

tokenizer = AutoTokenizer.from_pretrained("Helsinki-NLP/opus-mt-zh-en")
model = AutoModelForSeq2SeqLM.from_pretrained("Helsinki-NLP/opus-mt-zh-en")

# text = "作为学生,一定要学习好学校的课乘!"
text = "重庆是一个好地方, 今天适合出去玩"

inputs = tokenizer(text, return_tensors="pt", )
outputs = model.generate(inputs["input_ids"], max_length=40, num_beams=4, early_stopping=True)
translated_sentence = tokenizer.decode(outputs[0], skip_special_tokens=True)
print('原始文本: ', text)
print('翻译文本: ', translated_sentence)
#原始文本:  重庆是一个好地方, 今天适合出去玩
#翻译文本:  Chongqing is a good place to go. It's a good day.

# 2. 基于OpenAI接口的机器翻译实验
def translate_text(text):
    content = f"请将以下中文文本翻译成英文:\n{text}"
    response = openai.ChatCompletion.create(
        model="gpt-3.5-turbo", 
        messages=[{"role": "user", "content": content}]
    )
    translated_text = response.get("choices")[0].get("message").get("content")
    return translated_text

text_to_translate = "重庆是一个好地方,今天天气好,适合出去玩"
translated_text = translate_text(text_to_translate)
print("原始文本: ", text_to_translate)
print("输出文本: ", translated_text)
# 原始文本:  重庆是一个好地方,今天天气好,适合出去玩
# 输出文本:  Chongqing is a great place. Today, the weather is good and it's suitable for going out and having fun.

上面的翻译结果对比:ChatGPT明显比Helsinki-NLP在中翻英上的效果更好,而不是简单的”直译“,用词相对更为丰富。

翻译数据:数据来源 https://github.com/LouisScorpio/datamining/tree/master/tensorflow-program/nlp/word2vec/dataset
下面翻译《哈利波特》并保存结果,第一册共有token数: 119873。GPT3的token限制数是4k,而GPT4是3万+,所以可以将每个段落当成一个文本块,每次翻译一段。

with open(file_path + "/哈利波特1-7英文原版.txt", "r", encoding='gbk') as f:
    text = f.read()
from transformers import GPT2Tokenizer

tokenizer = GPT2Tokenizer.from_pretrained("gpt2")  # GPT-2的tokenizer和GPT-3是一样的
token_counts = len(tokenizer.encode(text))
print('全书token数: ', token_counts)

# chatgpt的api调用价格是 1000 token 0.01美元,因此可以大致计算翻译一本书的价格
translate_cost = 0.01 / 1000 * token_counts
print(f'翻译全书约需{translate_cost}美元')

# 翻译全书约需115.14 rmb成本,有点贵了,我们试着只翻译第一本
end_idx = text.find('2.Harry Potter and The Chamber Of Secrets.txt')  # 第一册的结束位置
text = text[:end_idx]
print('第一册字符数: ', len(text))

tokenizer = GPT2Tokenizer.from_pretrained("gpt2") 
token_counts = len(tokenizer.encode(text))
print('第一册token数: ', token_counts)

translate_cost = 0.01 / 1000 * token_counts
print(f'翻译第一册约需{translate_cost}美元')

paragraphs = text.split('\n')
print('段落数: ', len(paragraphs))

ntokens = []
for paragraph in paragraphs:
    ntokens.append(len(tokenizer.encode(paragraph)))
print('最长段落的token数: ', max(ntokens))
# 段落数:  3038
# 最长段落的token数:  275

但是切分文本块太小会导致语境缺失,可以设置阈值为1000,即文本段落达到1k则新开一个,最后将翻译结果拼接:

def group_paragraphs(paragraphs, ntokens, max_len=1000):
    """
    合并短段落为文本块,用于丰富上下文语境,提升文本连贯性,并提升运算效率。
    :param paragraphs: 段落集合
    :param ntokens: token数集合
    :param max_len: 最大文本块token数
    :return: 组合好的文本块
    """
    batches = []
    cur_batch = ""
    cur_tokens = 0

    # 对于每个文本段落做处理
    for paragraph, ntoken in zip(paragraphs, ntokens):
        if ntoken + cur_tokens + 1 > max_len:  # '1' 指的是'\n'
            # 如果加入这段文本,总token数超过阈值,则开启新的文本块
            batches.append(cur_batch)
            cur_batch = paragraph
            cur_tokens = ntoken
        else:
            # 否则将段落插入文本块中
            cur_batch += "\n" + paragraph
            cur_tokens += (1 + ntoken)
    batches.append(cur_batch)  # 记录最后一个文本块
    return batches

batchs = group_paragraphs(paragraphs, ntokens)
print('文本块数: ', len(batchs))

new_tokens = []
for batch in batchs:
    new_tokens.append(len(tokenizer.encode(batch)))
print('最长文本块的token数: ', max(new_tokens))
# 文本块数:  125
# 最长文本块的token数:  1000

def translate_text(text):
    content = f"请将以下英文文本翻译成中文:\n{text}"
    response = openai.ChatCompletion.create(
        model="gpt-3.5-turbo", 
        messages=[{"role": "user", "content": content}]
    )
    translated_text = response.get("choices")[0].get("message").get("content")
    return translated_text

print(translate_text(batchs[0]))
translated_batchs = []
for i in range(len(batchs)):
    batch_context = batchs[i]
    translated_batchs.append(translate_text(batch_context))

在这里插入图片描述

Reference

[1] fine tune tutorial
[2] 中文文本纠错算法整体介绍
[3] 中文文本纠错任务简介
[4] pycorrector介绍
[5] 长文本英翻中tutorial
[6] https://learnprompting.org/docs/intermediate/least_to_most
[7] https://github.com/datawhalechina/hugging-llm

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

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

相关文章

Redis入门到入土(day02)

五大数据类型 官方文档 全段翻译&#xff1a; Redis是一个开放源代码&#xff08;BSD许可&#xff09;的内存中数据结构存储&#xff0c;用作数据库&#xff0c;缓存和消息代理。它支持数据结构&#xff0c;例如字符串&#xff0c;哈希&#xff0c;列表&#xff0c;集合&#…

vue项目 解决el-table自适应高度,vue页面不显示多条滚动条,超出的部分让el-table内部出现滚动条(推荐使用第二种解决方案)

一、需求 后台管理系统&#xff1a;最常见的页面都是由—>左侧菜单、头部tabView页签、主体数据渲染页面&#xff08;AppMain&#xff09;&#xff1b;而一般AppMain页面又分为&#xff1a; 搜索区域、table数据&#xff08;分页&#xff09;&#xff0c;可能也会存在底部&a…

Reid训练代码之数据集处理

本篇文章是对yolov5_reid这篇文章训练部分的详解。 该项目目录为&#xff1a; . |-- config # reid输入大小&#xff0c;数据集名称&#xff0c;损失函数等配置 |-- configs # 训练时期超参数定义 |-- data # 存储数据集和数据处理等代码&#xff0c;以及yolov5类别名称等 |--…

【高分论文密码】大尺度空间模拟预测与数字制图技术

大尺度空间模拟预测和数字制图技术和不确定性分析广泛应用于高分SCI论文之中&#xff0c;号称高分论文密码。 大尺度模拟技术可以从不同时空尺度阐明农业生态环境领域的内在机理和时空变化规律&#xff0c;又可以为复杂的机理过程模型大尺度模拟提供技术基础。 在本次&#x…

cocosLua 之 RichText(1)

结构 富文本主要通过RichText来实现, 其继承结构&#xff1a; #mermaid-svg-AHbMrHe3zp3q1wTZ {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-AHbMrHe3zp3q1wTZ .error-icon{fill:#552222;}#mermaid-svg-AHbMrHe3z…

Linux下ds18b20驱动开发获取温度

文章目录 一、修改并且编译设备树&#xff08;1&#xff09;修改设备树&#xff08;2&#xff09;修改开发板设备树进行reboot 二、硬件连接三、驱动开发与测试&#xff08;1&#xff09;编写设备驱动&#xff08;2&#xff09;编写测试代码&#xff08;3&#xff09;Makefile&…

第四章——数学知识1

质数 质数&#xff1a;在大于1的整数中&#xff0c;如果只包含1和本身这俩个约束&#xff0c;就被叫质数或素数。 质数判定试除法 质数的判定——试除法&#xff1a;如果d能整除n&#xff0c;则n/d再除n&#xff0c;结果是一个整数。 d≤n/d。 bool is_prime(int x) {if (x <…

【大数据之Hadoop】二十、Yarn基础框架及工作机制

1、Yarn基础框架 Yarn是一个资源调度平台&#xff0c;负责为运算程序提供服务器运算资源&#xff0c;相当于一个分布式的操作系统平台&#xff0c;而MapReduce等运算程序则相当于运行于操作系统之上的应用程序。 YARN主要由ResourceManager、NodeManager、ApplicationMaster和…

202303-1 田地丈量

代码 #include<iostream> #include<vector> #include<string> #include<cmath> #include<algorithm> #include<stack> using namespace std; int n, a, b;int main() {cin >> n >> a >> b;int x1, y1, x2, y2;int x, y;…

科学计算NumPy之Ndarray数组对象的创建、切片、索引、修改等操作汇总

NumPy的操作汇总 NumPy概述Ndarray对象基本使用Ndarray的属性Ndarray的类型Ndarray的形状 创建数组创建数组创建全1数组创建全1数组从已有数组创建新数组从现有数组生成创建等差数列数组创建等比数列数组创建等间隔数列数组创建随机数数组创建正态分布创建创建均匀分布 数组切片…

【JUC高并发编程】—— 再见JUC

一、读写锁 读写锁概述 1️⃣ 什么是读写锁&#xff1f; 读写锁是一种多线程同步机制&#xff0c;用于在多线程环境中保护共享资源的访问 与互斥锁不同的是&#xff0c;读写锁允许多个线程同时读取共享资源&#xff0c;但在有线程请求写操作时&#xff0c;必须将其他读写锁…

windows10 ubuntu子系统安装perf工具

文章目录 1&#xff0c;ubuntu子系统中perf工具安装不了1.1&#xff0c;查看perf版本如下所示1.2&#xff0c;网上找不到对应的版本的内核源码&#xff0c;下载别的版本后&#xff0c;编译各种报错 2&#xff0c;百度查到说是WSL1不支持perf2.1&#xff0c;查看WSL版本 2.2&…

MySQ基础知识整合

目录 模糊查询 排序 单行函数 多行函数 分组函数 having 单表查询执行顺序总结 distinct 连接查询 子查询 union limit DQL语句执行顺序 DDL语句 日期化 date和date_format区别 update table 的快速创建以及删除&#xff08;及回滚&#xff09; 约束 事务 …

HTTP基础知识汇总

伴随着云原生(Cloud Native)的兴起&#xff0c;面向服务架构(Service-Oriented Architecture&#xff0c;SOA)、微服务(Microservice)、容器(Container)等相关概念与技术正在逐渐影响CAx(CAD/CAE/CAM)软件的架构设计与开发。 在云原生CAx软件中&#xff0c;首先需要把系统按照…

MySQL锁详解及案例分析

MySQL锁详解及案例分析 一、一条update语句二、MySQL锁介绍三、全局锁全局锁演示1.环境准备2.全局锁演示 四、MySQL表级锁&#xff08;都是Server层实现&#xff09;1、表级锁介绍2、表读S、写锁X1&#xff09;表锁相关命令2&#xff09;表锁演示1、表级的共享锁(读锁)2、表级的…

VLAN实验

SW1 [sw1]int g0/0/2 [sw1-GigabitEthernet0/0/2]dis this interface GigabitEthernet0/0/2 port link-type access port default vlan 2 pc1划分到vlan 2 [sw1-GigabitEthernet0/0/3]dis t…

【C++STL】set

前言 前面的CSTL的博客&#xff0c;我们介绍了string&#xff0c;vector&#xff0c;list&#xff0c;deque&#xff0c;priority_queue还有stack和queue。 这些容器统称为序列式容器&#xff0c;因为其底层为线性序列的数据结构&#xff0c;里面存储的是元素本身。 而从本节开…

【正点原子STM32精英V2开发板体验】体验LVGL的SD NAND文件系统

目的 验证基于SD NAND卡在正点原子STM32精英V2开发板上的兼容效果 实验材料 正点原子STM32精英V2开发板 TF 卡一片 SD NAND卡一片 实验步骤 1、打开例程【正点原子】精英STM32F103开发板 V2-资料盘(A盘)\4&#xff0c;程序源码\3&#xff0c;扩展例程\4&#xff0c;LVGL…

数据库系统概论(二)关系数据库,SQL概述和数据库安全性

作者的话 前言&#xff1a;总结下知识点&#xff0c;自己偶尔看一看。 目录 一、关系模型概述 1.1关系数据结构及形式化定义 1.1.1域&#xff08;Domain&#xff09; 1.1.2笛卡尔积&#xff08;Cartesian Product&#xff09; 1.1.3关系&#xff08;Relation&#xff09; …

Android之 WebView的使用

一 简介 1.1 WebView是用来展示网页的控件&#xff0c;底层是google的WebKit的引擎。 比起苹果的WebView&#xff0c;webkit一些不足地方&#xff1a; 不能支持word等文件的预览 纯标签加载&#xff0c;并不支持所有标签的加载 不支持文件的下载&#xff0c;图片的放大&#…