Bert基础(二十一)--Bert实战:文本摘要

news2024/11/19 3:20:41

一、介绍

1.1 文本摘要简介

文本摘要(Text Summarization),作为自然语言处理(NLP)领域的一个分支,其核心目标是从长篇文档中提取关键信息,并生成简短的摘要,以提供对原始内容的高度概括。这一过程不仅有助于用户迅速把握信息的核心,而且对于有效组织和归纳大量的文本数据至关重要。

文本摘要的任务可以根据不同的输入和输出进行分类。首先,根据输入文档的数量,可以将摘要任务分为单文档摘要和多文档摘要。单文档摘要专注于处理单个文档,而多文档摘要则需要整合多个相关文档的信息。其次,根据输入和输出的语言,摘要任务可以分为单语言摘要、跨语言摘要和多语言摘要。在本课程中,我们将重点关注单文档单语言摘要,即处理单个文档并以同一种语言生成摘要。

在单文档单语言摘要中,系统需要理解文档的语义和结构,并从中提取最重要的信息,然后以简洁明了的方式呈现给用户。这个过程涉及对文本的理解、分析和重构,要求模型能够准确捕捉文档的主要观点,同时保持信息的完整性。

1.2 T5简介

T5(Text-to-Text Transfer Transformer)是一种基于Transformer架构的文本到文本的预训练语言模型领域的通用模型,由Google Research开发。T5模型的主要特点是将文本生成任务视为一种文本到文本的转换,这使得它可以被广泛应用于多种文本生成任务,如文本摘要、机器翻译、问答系统、文本生成等。

T5模型通过预训练来学习文本的通用表示,这使得它在下游任务中能够快速适应并表现出色。预训练的过程包括在大规模文本数据上进行自监督学习,模型通过预测文本中的缺失部分来学习文本的表示。

T5模型的一个重要特点是它采用了统一的编码器-解码器架构,这意味着它可以在多种文本生成任务中使用相同的模型,只需调整模型的输入和输出即可。这种统一的架构使得T5模型在各种文本生成任务中表现出了强大的通用性和灵活性。

T5模型的另一个特点是它采用了简单的任务提示(Task Prompt)技术,通过在输入文本中添加一些简单的提示词,如“摘要:”、“翻译:”等,来指导模型生成相应的文本。这种方法可以有效地提高模型的生成质量,并且可以很容易地应用于不同的文本生成任务。

总的来说,T5模型是一种强大的文本到文本的预训练模型,它在多种文本生成任务中都表现出了出色的性能。随着研究的不断深入,T5模型有望在未来的文本生成任务中发挥更大的作用。

1.3 Seq2Seq

序列到序列(Seq2Seq)模型是一种用于处理序列数据的神经网络模型,它由两个主要部分组成:编码器(Encoder)和解码器(Decoder)。这种模型通常用于机器翻译、语音识别、文本摘要等任务
在这里插入图片描述

  1. 数据处理:在序列到序列模型的数据预处理阶段,我们需要将输入数据(input)和标签数据(labels)分开处理。例如,我们可以有一个文本数据集,其中每一行代表一个样本,第一列是输入数据,后续列是该样本的标签。
  2. 标签处理:在实际应用中,标签不仅仅是分类的结果,它们还可以包含更多的信息,如情感分析中的正面、负面和中性
  3. 情绪,或者是机器翻译中的源语言和目标语言等。这些额外的信息对于模型的学习和泛化非常重要。
  4. 编码和解码器结构:在序列到序列模型的架构设计中,编码器和解码器通常采用相同的结构,但它们的用途不同。编码器负责将输入数据转换为一个表示,而解码器则使用这个表示来生成相应的输出。这种对称的结构有助于提高模型的效率和可扩展性。
  5. 注意力机制:在某些序列到序列模型中,如Transformer模型,注意力机制被用来关注输入数据的不同部分,从而捕捉长距离依赖关系。这有助于模型更好地理解上下文,尤其是在处理自然语言时。
  6. 优化算法:为了训练序列到序列模型,我们通常会使用梯度下降或其他优化算法来更新模型参数。在这个过程中,我们需要考虑如何有效地计算梯度和选择合适的 learning rate 等超参数。
  7. 评估指标:在评估序列到序列模型的性能时,常用的指标包括 BLEU(Bilingual Evaluation Understudy)、ROUGE(Recall-Oriented Understudy for Gisting Evaluation)和 CIDEr(Cascade Intersection over Union)。这些指标可以帮助我们了解模型生成文本的质量。

1.4 评价指标

评价指标包括Rouge,具体又分为Rouge-1、Rouge-2、Rouge-L,它们分别基于1-gram、2-gram、LCS。

ROUGE(Recall-Oriented Understudy for Gisting Evaluation)是一种用于自动评估文本摘要质量的指标,它主要关注召回率(Recall)和F1分数。ROUGE-1、ROUGE-2和ROUGE-L是ROUGE的不同变体,它们分别计算不同长度的匹配项。
以下是计算ROUGE-1、ROUGE-2和ROUGE-L的基本步骤:

  1. ROUGE-1:计算1-gram(单字词)的匹配项。
  2. ROUGE-2:计算2-gram(双字词)的匹配项。
  3. ROUGE-L:计算最长公共子序列(Longest Common Subsequence, LCS)的匹配项。
    计算公式如下:

ROUGE-1

  • Precision §: 匹配到的1-gram数量 / 生成的1-gram总数
  • Recall ®: 匹配到的1-gram数量 / 参考的1-gram总数
  • F1 Score: 2 * P * R / (P + R)

ROUGE-2

  • Precision §: 匹配到的2-gram数量 / 生成的2-gram总数
  • Recall ®: 匹配到的2-gram数量 / 参考的2-gram总数
  • F1 Score: 2 * P * R / (P + R)

ROUGE-L

  • Precision §: LCS匹配到的1-gram数量 / 生成的1-gram总数
  • Recall ®: LCS匹配到的1-gram数量 / 参考的1-gram总数
  • F1 Score: 2 * P * R / (P + R)
    其中,LCS匹配是指在生成文本和参考文本之间找到的最长公共子序列。

示例

假设我们有一个生成的摘要和一个参考摘要,我们想要计算ROUGE-1、ROUGE-2和ROUGE-L。
生成摘要:今天不错
参考摘要:今天天气不错

  1. ROUGE-1
    • 生成的1-gram:今天, 不, 错
    • 参考的1-gram:今天, 天气, 不, 错
    • P: 4/4
    • R: 4/6
    • F1: 2 * 4/4 * 4/6 / (4/4 + 4/6)
  2. ROUGE-2
    • 生成的2-gram:今天不错, 不错今天
    • 参考的2-gram:今天天气, 天气不错, 不错天气
    • P: 2/3
    • R: 2/5
    • F1: 2 * 2/3 * 2/5 / (2/3 + 2/5)
  3. ROUGE-L
    • 生成的1-gram:今天, 不, 错
    • 参考的1-gram:今天, 天气, 不, 错
    • P: 4/4
    • R: 4/6
    • F1: 2 * 4/4 * 4/6 / (4/4 + 4/6)
      请注意,这些计算是基于示例文本进行的,实际应用中可能需要更复杂的数据处理和计算。在实际使用ROUGE时,通常会使用专门的ROUGE工具来进行计算,而不是手动计算。

二、实战

2.1 下载数据集

常见的数据集
在这里插入图片描述
我们使用的是lcsts摘要数据:

lcsts摘要数据是哈尔滨工业大学整理,基于新闻媒体在微博上发布的新闻摘要创建了该数据集,每篇短文约100个字符,每篇摘要约20个字符。

整理后数据信息如下:

总数量:2108915个样本;

摘要:平均字数 18,字数标准差 5,最大字数 30,最小数字 4;

正文:平均字数 104,字数标准差 10,最大字数 152,最小数字 69;

在这里插入图片描述

sum_datasets = load_dataset("hugcyp/LCSTS")
sum_datasets
DatasetDict({
    train: Dataset({
        features: ['summary', 'text'],
        num_rows: 2400591
    })
    validation: Dataset({
        features: ['summary', 'text'],
        num_rows: 8685
    })
    test: Dataset({
        features: ['summary', 'text'],
        num_rows: 725
    })
})

数据集太大了,所以我们做一个简单的

sum_datasets = load_dataset("hugcyp/LCSTS",split="train[:10000]")
sum_datasets = sum_datasets.train_test_split(test_size=0.2)
sum_datasets
DatasetDict({
    train: Dataset({
        features: ['summary', 'text'],
        num_rows: 8000
    })
    test: Dataset({
        features: ['summary', 'text'],
        num_rows: 2000
    })
})

查看数据

sum_datasets["train"][0]
{'summary': '美国学生如何吐槽第一夫人的营养餐?',
 'text': '在米歇尔强力推动下,美国国会通过了法案,要求学生午餐必须包括一份水果或蔬菜,并设定了卡路里的上限。从此美国学校饭堂出现了各种奇葩的“达标”午餐(如下图),譬如用番茄酱来代替水果,引发学生吐槽。'}

2.2 数据预处理

在hugging face中找一个T5Chinese的模型试一下
在这里插入图片描述

tokenizer = AutoTokenizer.from_pretrained("uer/t5-base-chinese-cluecorpussmall")

def process_func(exmaples):
    contents = ["摘要生成: \n" + e for e in exmaples["text"]]
    inputs = tokenizer(contents, max_length=384, truncation=True)
    labels = tokenizer(text_target=exmaples["summary"], max_length=64, truncation=True)
    inputs["labels"] = labels["input_ids"]
    return inputs

这段代码是一个函数,名为process_func,它的目的是处理输入的数据,以便用于训练一个序列到序列(Seq2Seq)模型。在这个函数中,它接受一个字典exmaples作为输入,该字典包含原始文本"text"和对应的摘要"summary"
函数的步骤如下:

  1. 生成摘要生成提示:使用列表推导式,遍历exmaples["text"]列表,为每个文本生成一个摘要生成提示。提示的格式为"摘要生成: \n"加上文本内容。
  2. 分词:使用分词器tokenizer对生成的内容列表进行分词。这里设置了max_length=384truncation=True,这意味着分词器将尝试将每个内容分词后的序列长度限制在384个token以内,如果超过这个长度,则进行截断。
  3. 生成输入:将分词后的内容列表转换为模型可以理解的格式,即整数序列。这个整数序列将作为模型的输入。
  4. 生成标签:使用分词器tokenizerexmaples["summary"]进行分词。这里同样设置了max_length=64truncation=True,确保摘要分词后的序列长度不超过64个token。
  5. 设置标签:将摘要分词后的整数序列作为模型的标签,并将其添加到输入字典inputs中。
  6. 返回处理后的数据:函数返回包含分词后的输入和标签的inputs字典,这些数据可以被模型用于训练。

总的来说,这个函数将原始文本和摘要转换为模型可以处理的整数序列格式,并为模型提供了输入和标签,以便于训练。

tokenized_ds = sum_datasets.map(process_func, batched=True)
tokenized_ds
DatasetDict({
    train: Dataset({
        features: ['summary', 'text', 'input_ids', 'token_type_ids', 'attention_mask', 'labels'],
        num_rows: 8000
    })
    test: Dataset({
        features: ['summary', 'text', 'input_ids', 'token_type_ids', 'attention_mask', 'labels'],
        num_rows: 2000
    })
})
print(tokenized_ds["train"][0])

{'summary': '新民评论:罚丁书苗25亿意义深远', 'text': '加大对行贿者的惩治力度,应当以人身处罚和财产处罚并重,让行贿者把非法获利“吐”出来,防止“一人坐牢,全家享福”的不正常现象。对丁书苗案的判决,能否在刑法修订、行贿成本有望提高的背景之下,成为一个具有典型意义的判例,令人期待。', 'input_ids': [101, 3036, 6206, 4495, 2768, 131, 1217, 1920, 2190, 6121, 6594, 5442, 4638, 2674, 3780, 1213, 2428, 8024, 2418, 2496, 809, 782, 6716, 1905, 5385, 1469, 6568, 772, 1905, 5385, 2400, 7028, 8024, 6375, 6121, 6594, 5442, 2828, 7478, 3791, 5815, 1164, 100, 1402, 100, 1139, 3341, 8024, 7344, 3632, 100, 671, 782, 1777, 4286, 8024, 1059, 2157, 775, 4886, 100, 4638, 679, 3633, 2382, 4385, 6496, 511, 2190, 672, 741, 5728, 3428, 4638, 1161, 1104, 8024, 5543, 1415, 1762, 1152, 3791, 934, 6370, 510, 6121, 6594, 2768, 3315, 3300, 3307, 2990, 7770, 4638, 5520, 3250, 722, 678, 8024, 2768, 711, 671, 702, 1072, 3300, 1073, 1798, 2692, 721, 4638, 1161, 891, 8024, 808, 782, 3309, 2521, 511, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], '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, 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, 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, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], 'labels': [101, 3173, 3696, 6397, 6389, 8038, 5385, 672, 741, 5728, 8132, 783, 2692, 721, 3918, 6823, 102]}

2.3 创建模型

model = AutoModelForSeq2SeqLM.from_pretrained("uer/t5-base-chinese-cluecorpussmall")

在这里插入图片描述

2.4 创建评估函数

!pip install rouge_chinese

import numpy as np
from rouge_chinese import Rouge

rouge = Rouge()

def compute_metric(evalPred):
    predictions, labels = evalPred
    decode_preds = tokenizer.batch_decode(predictions, skip_special_tokens=True)
    labels = np.where(labels != -100, labels, tokenizer.pad_token_id)
    decode_labels = tokenizer.batch_decode(labels, skip_special_tokens=True)
    decode_preds = [" ".join(p) for p in decode_preds]
    decode_labels = [" ".join(l) for l in decode_labels]
    scores = rouge.get_scores(decode_preds, decode_labels, avg=True)
    return {
        "rouge-1": scores["rouge-1"]["f"],
        "rouge-2": scores["rouge-2"]["f"],
        "rouge-l": scores["rouge-l"]["f"],
    }

这段代码的目的是计算ROUGE(Recall-Oriented Understudy for Gisting Evaluation)分数,这是一种用于评估文本摘要质量的指标。
函数的步骤如下:

  1. 导入库:首先,导入了numpyrouge_chinese库。numpy是一个用于科学计算的库,而rouge_chinese是一个用于计算中文文本ROUGE分数的库。
  2. 创建ROUGE实例:使用Rouge()创建了一个Rouge对象,这通常是一个计算ROUGE分数的函数或类。
  3. 定义函数:函数compute_metric接受一个评估预测(evalPred)作为输入。
  4. 解码预测和标签:使用分词器tokenizer批量解码预测(predictions)和标签(labels)。skip_special_tokens=True参数确保了在解码过程中特殊标记(如<sos><eos>)被忽略。
  5. 处理标签:将标签中的-100替换为分词器的pad_token_id,以确保标签长度与预测长度一致。
  6. 批量解码标签:使用分词器批量解码标签,以便与预测进行比较。
  7. 拼接解码后的预测和标签:将解码后的预测和标签拼接成字符串,以便进行ROUGE计算。
  8. 计算ROUGE分数:使用rouge.get_scores()函数计算ROUGE-1、ROUGE-2和ROUGE-L的分数。avg=True参数表示计算平均分数。
  9. 返回ROUGE分数:函数返回一个字典,其中包含ROUGE-1、ROUGE-2和ROUGE-L的F1分数。

2.5 创建训练器

args = Seq2SeqTrainingArguments(
    output_dir="./summary",
    per_device_train_batch_size=4,
    per_device_eval_batch_size=8,
    gradient_accumulation_steps=8,
    logging_steps=8,
    evaluation_strategy="steps",
    eval_steps=200,
    save_strategy="epoch",
    metric_for_best_model="rouge-l",
    predict_with_generate=True,
    report_to=['tensorboard']
)

因为训练速度比较慢,我们根据step打印一次预测结果

2.6 训练模型

trainer = Seq2SeqTrainer(
    args=args,
    model=model,
    train_dataset=tokenized_ds["train"],
    eval_dataset=tokenized_ds["test"],
    compute_metrics=compute_metric,
    tokenizer=tokenizer,
    data_collator=DataCollatorForSeq2Seq(tokenizer=tokenizer)
)

trainer.train()

在这里插入图片描述

TrainOutput(global_step=750, training_loss=7.258201690673828, metrics={'train_runtime': 948.8402, 'train_samples_per_second': 25.294, 'train_steps_per_second': 0.79, 'total_flos': 3313311337635840.0, 'train_loss': 7.258201690673828, 'epoch': 3.0})

效果很差,虽然我们训练的次数比较少,但是这个效果还是不能接受的,原因很有可能是我们的模型选的有问题,我们重新选一个模型在测试一下

重新选择一个模型,选择搜索出来的第一个试一下
在这里插入图片描述

tokenizer = AutoTokenizer.from_pretrained("lemon234071/t5-base-Chinese")
model = AutoModelForSeq2SeqLM.from_pretrained("lemon234071/t5-base-Chinese")
trainer.train()


在这里插入图片描述
TrainOutput(global_step=750, training_loss=4.802234703063965, metrics={‘train_runtime’: 979.7099, ‘train_samples_per_second’: 24.497, ‘train_steps_per_second’: 0.766, ‘total_flos’: 2839954114953216.0, ‘train_loss’: 4.802234703063965, ‘epoch’: 3.0})

这个明显好了很多

2.7 预测

from transformers import pipeline
pipe = pipeline("text2text-generation", model=model, tokenizer=tokenizer, device=0)

pipe("摘要生成:\n" + sum_datasets["test"][10]["text"], max_length=64, do_sample=True)
[{'generated_text': '<extra_id_0>海口首条水上巴士航线试运行'}]
sum_datasets["test"][10]["summary"]

'海口首条水上巴士将启航航线从万绿园至西秀海滩'

其实生成的效果不是很好,还需要多训练几轮,因为现在的loss还是比较大,而且Rouge-1才0.3

完整代码

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

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

相关文章

Rust中的并发性:Sync 和 Send Traits

在并发的世界中&#xff0c;最常见的并发安全问题就是数据竞争&#xff0c;也就是两个线程同时对一个变量进行读写操作。但当你在 Safe Rust 中写出有数据竞争的代码时&#xff0c;编译器会直接拒绝编译。那么它是靠什么魔法做到的呢&#xff1f; 这就不得不谈 Send 和 Sync 这…

Apache SeaTunnel k8s 集群模式 Zeta 引擎部署指南

SeaTunnel提供了一种运行Zeta引擎(cluster-mode)的方法&#xff0c;可以让Kubernetes在本地运行Zeta引擎&#xff0c;实现更高效的应用程序部署和管理。在本文中&#xff0c;我们将探索SeaTunnel k8s运行zeta引擎(cluster-mode模式)的更多信息&#xff0c;了解如何更好地利用Ze…

大数据技术就业和发展前景怎么样

大数据技术的就业和发展前景极为乐观&#xff0c;具有行业需求旺盛、就业多样性、可持续发展潜力等特点&#xff0c; 上大学网 &#xff08;www.sdaxue.com&#xff09;整理出了大数据技术的就业和发展前景以下几个关键趋势&#xff0c;供大家参考&#xff01; 行业需求旺盛&…

[华为OD] C卷 5G网络 现需要在某城市进行5G网络建设,已经选取N个地点设置5G基站 200

题目 现需要在某城市进行5G网络建设&#xff0c;已经选取N个地点设置5G基站&#xff0c;编号固定为1到N,接 下来需要各个基站之间使用光纤进行连接以确保基站能互联互通&#xff0c;不同基站之间架设光纤的成 本各不相同&#xff0c;且有些节点之间已经存在光纤相连&#…

数据仓库Data Warehouse

数据仓库Data Warehouse 数仓是一种思想,数仓是一种规范,数仓是一种解决方案 1. 数据处理方式 数据处理大致可以分成两大类: 联机事务处理OLTP(on-line transaction processing)联机分析处理OLAP(On-Line Analytical Processing)1.1. OLTP OLTP的全称是On-line Transa…

Unity添加证件

目录 1.问题描述&#xff1a;2.解决方法&#xff1a;小结&#xff1a; 1.问题描述&#xff1a; 2.解决方法&#xff1a; 登录后跳转打开 添加证件 选择个人证件 小结&#xff1a; 关注我给大家分享更多有趣的知识&#xff0c;以下是个人公众号&#xff0c;提供 ||代码兼职||…

基于 React 的图形验证码插件

react-captcha-code NPM 地址 &#xff1a; react-captcha-code - npm npm install react-captcha-code --save 如下我自己的封装&#xff1a; import Captcha from "react-captcha-code";type CaptchaType {captchaChange: (captchaInfo: string) > void;code…

利用大型语言模型提升数字产品创新:提示,微调,检索增强生成和代理的应用

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

【漏洞复现】科达 MTS转码服务器 任意文件读取漏洞

0x01 产品简介 科达 MTS转码服务器是一款专业的视频转码设备&#xff0c;采用了高性能的硬件配置和先进的转码技术&#xff0c;能够实现高效、高质量的视频转码。 0x02 漏洞概述 科达 MTS转码服务器存在任意文件读取漏洞&#xff0c;攻击可以通过该漏洞读取服务器任意敏感信…

ChatGPT向付费用户推“记忆”功能,可记住用户喜好 | 最新快讯

4月30日消息&#xff0c;人工智能巨头OpenAI宣布&#xff0c;其开发的聊天机器人ChatGPT将在除欧洲和韩国以外的市场全面上线“记忆”功能。这使得聊天机器人能够“记住”ChatGPT Plus付费订阅用户的详细信息&#xff0c;从而提供更个性化的服务。 OpenAI早在今年2月就已经宣布…

java同步大量数据到本地数据库方法总结

最近在做一个需求&#xff0c;就是我需要对三方接口调用的数据存放到本地的数据库里的数据表里面。那么一开始我就是直接一条一条save&#xff0c;结果发现耗时非常严重&#xff0c;后面我就进行了改进。就是分批次去同步或者分批次去异步。 现在我直接贴出我写的代码&#xf…

PG后台进程个人解读和与oracle 的比较

1.background writer &#xff08;后台写进程&#xff09; 与OracleDBWR进程工作原理类似&#xff0c;都是负责把缓冲区里面的脏块写到数据文件中&#xff0c;写的目的有两个&#xff1a; 1.为了保存数据。 2.为了释放内存空间。 触发background writer 写的条件&#xff1a…

Virtualbox--下载指定版本

一、前言 下载Virtualbox7.0.10&#xff0c;可参考《Virtualbox–下载指定版本》 Virtualbox7.0.10具体安装步骤&#xff0c;可参考《Virtualbox7.0.10的安装步骤》 Virtualbox7.0.10创建虚拟机&#xff0c;可参考《Virtualbox7.0.10–创建虚拟机》 Virtualbox7.0.10安装Ubuntu…

GPT3 终极指南(二)

原文&#xff1a;zh.annas-archive.org/md5/6de8906c86a2711a5a84c839bec7e073 译者&#xff1a;飞龙 协议&#xff1a;CC BY-NC-SA 4.0 第五章&#xff1a;GPT-3 作为企业创新的下一步 当一个新的创新或技术转变发生时&#xff0c;大公司通常是最后一个采纳的。它们的等级结构…

Linux 文件管理命令Lawk wc comm join fmt

文章目录 2.Linux 文件管理命令2.44 awk&#xff1a;模式匹配语言1&#xff0e;变量2&#xff0e;运算符3&#xff0e;awk 的正则4&#xff0e;字符串函数5&#xff0e;数学函数案例练习 2.45 wc&#xff1a;输出文件中的行数、单词数、字节数案例练习2.46 comm&#xff1a;比较…

Qwen-Audio:推动通用音频理解的统一大规模音频-语言模型(开源)

随着人工智能技术的不断进步&#xff0c;音频语言模型&#xff08;Audio-Language Models&#xff09;在人机交互领域变得越来越重要。然而&#xff0c;由于缺乏能够处理多样化音频类型和任务的预训练模型&#xff0c;该领域的进展受到了限制。为了克服这一挑战&#xff0c;研究…

Spring Data Redis简单使用

Spring Data Redis是一个用于简化应用程序与Redis交互的开发框架。它提供了简单的配置和方便的操作API&#xff0c;使得与Redis的集成变得更加容易。下面是一个快速入门使用Spring Data Redis的步骤&#xff1a; 步骤 1&#xff1a;添加依赖 在您的项目中添加Spring Data Redi…

掌握未来:打造高效、可靠系统的终极指南—RESTful API 设计详解

RESTful API 是一种软件架构风格和开发规范&#xff0c;它基于 Representational State Transfer&#xff08;REST&#xff09;原则。RESTful API 使用 HTTP 协议的标准方法&#xff0c;如 GET、POST、PUT、DELETE 等&#xff0c;来进行资源的创建、读取、更新和删除操作。这种…

四川易点慧电子商务抖音小店:创新引领,开启电商新篇章

随着互联网的快速发展&#xff0c;电子商务行业日新月异&#xff0c;抖音小店作为新兴的电商模式&#xff0c;正逐渐崭露头角。四川易点慧电子商务有限公司紧跟时代步伐&#xff0c;以创新思维引领抖音小店发展&#xff0c;成为了行业的佼佼者。 易点慧电子商务位于风景秀丽的四…

FFmpeg开发笔记(二十三)使用OBS Studio开启RTMP直播推流

OBS是一个开源的直播录制软件&#xff0c;英文全称叫做Open Broadcaster Software&#xff0c;广泛用于视频录制、实时直播等领域。OBS不但开源&#xff0c;而且跨平台&#xff0c;兼容Windows、Mac OS、Linux等操作系统。 OBS的官网是https://obsproject.com/&#xff0c;录制…