国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

GPT2-Chinese 文本生成,訓(xùn)練AI寫小說,AI寫小說2

這篇具有很好參考價值的文章主要介紹了GPT2-Chinese 文本生成,訓(xùn)練AI寫小說,AI寫小說2。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

GPT2-Chinese 介紹

GPT-2 (Generative Pre-trained Transformer 2) 是由 OpenAI 開發(fā)的一種基于 Transformer 模型的自然語言處理(NLP)模型,旨在生成自然流暢的文本。它是一種無監(jiān)督學(xué)習(xí)模型,其設(shè)計目標是能夠理解人類語言的復(fù)雜性并模擬出自然的語言生成。

GPT-2 是目前最先進的自然語言處理模型之一,因為它具有大量的訓(xùn)練數(shù)據(jù)和強大的算法,可以生成自然流暢、準確的文本,其中文版本為GPT2-Chinese:使用wiki中文通用語料訓(xùn)練。

與其他基于神經(jīng)網(wǎng)絡(luò)的語言模型相比,GPT-2 具有許多獨特的優(yōu)點。首先,它采用了自監(jiān)督學(xué)習(xí)的方式進行訓(xùn)練,使其能夠處理多種語言和任務(wù)。其次,GPT-2 可以生成各種類型的文本,例如新聞、故事、對話和代碼等。最后,GPT-2 模型使用了大量的預(yù)訓(xùn)練參數(shù),使其具有強大的表現(xiàn)力和泛化能力。

GPT2-Chinese 版本是 GPT-2 模型的中文版本,也是基于 Transformer 模型構(gòu)建的,具有相同的架構(gòu)和訓(xùn)練技術(shù)。GPT2-Chinese 已經(jīng)在多項中文 NLP 任務(wù)上取得了顯著的成果,并被廣泛應(yīng)用于中文文本生成、問答、文本摘要和翻譯等領(lǐng)域。

GPT-2 參數(shù)數(shù)量?1.5億到1.75億模型大小0.5GB到1.5GB

模型

每個參數(shù)占用的字節(jié)大小

模型大小

模型大小

層數(shù)

頭數(shù)

GPT-1

4 個字節(jié)的 FP32 精度浮點數(shù)

117M

446MB

12

12

GPT-2

2 個字節(jié)的 FP16

1.5億到1.75億

0.5GB到1.5GB

48

16

GPT-3

2 個字節(jié)的 FP16

1.75萬億(17500億)

350GB

175

96個頭

下載代碼

https://github.com/Morizeyao/GPT2-Chinese


?

在根目錄(目錄\GPT2-Chinese\)下建立文件夾data和model

\GPT2-Chinese\data

\GPT2-Chinese\model

把要訓(xùn)練的小說復(fù)制到train.json這里面

train.json(也即->?\GPT2-Chinese\data\train.json),需要注意的是,train.json編碼格式嚴格為UTF-8,并且不帶BOM頭<-去頭咱用的sublime。

?

vocab

  • vocab.txt:詞匯表。默認的大小為13317,若需要使用自定義字典,需要將confog.json文件中的vocab_size字段設(shè)為相應(yīng)的大小。也就是vocab.txt文件有多少行,多少個分詞.
  • 把?vocab.txt 字典文件里的 [SEP]?行號減1,設(shè)置為?Config.json 配置文件? "bos_token_id": 1,和? "eos_token_id": 1,的值.減1是因為vocab是從0下標開始,而行下標是從1開始.我這里設(shè)置為1是因為我的?[SEP]?在vocab的第二行.

特殊 token?符號

[UNK]:表示未知標記(即,詞匯表中沒有的詞);
[SEP]:表示句子分隔符;換行
[PAD]:表示填充標記,用于填充序列的長度;也就是無效符號。
pad_token_id默認為tokenizer.eos_token_id,這是特殊token [EOS]的位置。它被用來指示模型當(dāng)前生成的句子已經(jīng)結(jié)束,因此當(dāng)我們想要生成一個開放式文本時,我們可以將pad_token_id設(shè)置為eos_token_id,以確保生成文本不會被提前結(jié)束。
[CLS]:表示分類標記,用于BERT模型的分類任務(wù);文章之間添加CLS表示文章結(jié)束
[MASK]:表示掩碼標記,用于BERT模型的掩碼語言建模任務(wù)。文章開頭添加MASK表示文章開始

?vocab 詞匯表

在自然語言處理任務(wù)中,將文本轉(zhuǎn)換成數(shù)字是非常重要的預(yù)處理步驟之一。這個過程叫做文本編碼。傳統(tǒng)的文本編碼方法,如one-hot編碼或詞袋模型,通常會忽略單詞之間的語義和上下文關(guān)系,因此不太適用于語義相似性計算、文本分類、問答系統(tǒng)等需要更深層次理解文本含義的任務(wù)。
通過詞匯表 把一個字 、一個短語 、一個短句 轉(zhuǎn)換成一個數(shù)字 ,形成了 數(shù)字 映射 成 文字,文字映射成 數(shù)字的過程。字典 詞典?

model_config = transformers.modeling_gpt2.gpt2config.from_json_file(args.mod,pytorch,深度學(xué)習(xí),pytorch,人工智能

?詞匯表的大小會對訓(xùn)練模型的大小和復(fù)雜度產(chǎn)生影響。
在自然語言處理中,詞匯表是所有可能的單詞集合。如果詞匯表很大,那么訓(xùn)練模型需要處理更多的單詞和更多的單詞組合,因此會增加模型的復(fù)雜度和大小。
此外,詞匯表的大小還會影響模型的訓(xùn)練時間和資源消耗。一個包含更多單詞的詞匯表需要更多的內(nèi)存和計算資源來存儲和處理。
因此,為了訓(xùn)練一個高效且準確的自然語言處理模型,需要平衡詞匯表大小和模型大小之間的關(guān)系,并考慮可用的計算資源和訓(xùn)練時間。

?安裝依賴

transformers>=2.1.1
torch
numpy
tqdm
sklearn
keras
tb-nightly
future
thulac

?如果transformers>=4.2.1? 要修改的改以下代碼

transformers  報錯 got_ver is None,重裝numpy,
pip uninstall numpy
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple numpy
#model_config = transformers.modeling_gpt2.GPT2Config.from_json_file(args.model_config)
    model_config = transformers.models.gpt2.GPT2Config.from_json_file(args.model_config)
    if not args.pretrained_model:
        #model = transformers.modeling_gpt2.GPT2LMHeadModel(config=model_config)
        model = transformers.models.gpt2.GPT2LMHeadModel(config=model_config)
    else:
        #model = transformers.modeling_gpt2.GPT2LMHeadModel.from_pretrained(args.pretrained_model)
        model = transformers.models.gpt2.GPT2LMHeadModel(args.pretrained_model)
提示模塊'transformers'沒有屬性'WarmupLinearSchedule'的異常
這是因為在新版本中WarmupLinearSchedule方法已經(jīng)沒有了,可以換為get_linear_schedule_with_warmup方法

    # scheduler = transformers.WarmupLinearSchedule(optimizer, warmup_steps=warmup_steps,
    #                                                       t_total=total_steps)
    scheduler = transformers.get_linear_schedule_with_warmup(optimizer, num_warmup_steps =warmup_steps,
                                                           num_training_steps =total_steps)

?Config.json 配置文件

{
  "_name_or_path": "model/",
  "activation_function": "gelu_new",
  "architectures": [
    "GPT2LMHeadModel"
  ],
  "attn_pdrop": 0.1,
  "bos_token_id": 1,
  "embd_pdrop": 0.1,
  "eos_token_id": 1,
  "initializer_range": 0.02,
  "layer_norm_epsilon": 1e-05,
  "model_type": "gpt2",
  "n_ctx": 512,
  "n_embd": 1024,
  "n_head": 16,
  "n_inner": null,
  "n_layer": 12,
  "n_positions": 512,
  "reorder_and_upcast_attn": false,
  "resid_pdrop": 0.1,
  "scale_attn_by_inverse_layer_idx": false,
  "scale_attn_weights": true,
  "summary_activation": null,
  "summary_first_dropout": 0.1,
  "summary_proj_to_labels": true,
  "summary_type": "cls_index",
  "summary_use_proj": true,
  "torch_dtype": "float16",
  "transformers_version": "4.26.1",
  "use_cache": true,
  "vocab_size": 47689
}

??Config.json 配置文件參數(shù)解釋

"activation_function": "gelu_new": 激活函數(shù),這里使用改進版的GELU函數(shù)
"attn_pdrop": 0.1: 注意力機制中的dropout概率,每個注意力機制的權(quán)重有10%的概率被置為0
"bos_token_id": 50256: 開始標記(Begin-Of-Sequence)的token ID,這里是50256
"embd_pdrop": 0.1: 輸入嵌入層中的dropout概率,每個輸入token的嵌入向量有10%的概率被置為0
"eos_token_id": 50256: 結(jié)束標記(End-Of-Sequence)的token ID,這里是50256
"initializer_range": 0.02: 初始化權(quán)重矩陣的范圍,權(quán)重值在正負0.02之間均勻分布
"layer_norm_epsilon": 1e-05: Layer Normalization的epsilon值,防止分母為0
"model_type": "gpt2": 模型類型,這里是GPT-2
"n_ctx": 512: 輸入的文本序列的最大長度,這里是512
"n_embd": 768: 輸入嵌入層的維度,這里是768
"n_head": 12: Transformer中的多頭注意力機制中頭的數(shù)量,這里是12
"n_inner": null: Transformer中全連接層的隱層層數(shù),這里是null表示使用默認值(4)
"n_layer": 10: Transformer中的層數(shù),這里是10
"n_positions": 512: 輸入的位置編碼的維度,這里是512
"reorder_and_upcast_attn": false: 是否需要重新排序并升級注意力機制的權(quán)重矩陣,這里是false
"resid_pdrop": 0.1: 殘差連接的dropout概率,每個殘差連接的輸出向量有10%的概率被置為0
"scale_attn_by_inverse_layer_idx": false: 是否根據(jù)層數(shù)來縮放注意力機制的權(quán)重矩陣,這里是false
"scale_attn_weights": true: 是否需要縮放注意力機制的權(quán)重矩陣,這里是true
"summary_activation": null: 摘要(Summary)層的激活函數(shù),這里是null表示使用默認值(softmax)
"summary_first_dropout": 0.1: 摘要(Summary)層中第一個dropout的概率,這里是10%
"summary_proj_to_labels": true: 摘要(Summary)層是否需要將摘要結(jié)果投影到標簽空間,這里是true
"summary_type": "cls_index": 摘要(Summary)的類型,這里是CLS池化層
"summary_use_proj": true: 摘要(Summary)層是否需要使用投影層,這里是true
"transformers_version": "4.22.1": 使用


訓(xùn)練材料處理流程

0.根據(jù)小說制作詞匯表文件

import os
import jieba
from collections import Counter


def build_vocab(text_file, vocab_file, vocab_size, ignore_single=False):
    # 讀取文本文件并進行分詞
    '''
    text_file:要處理的文本文件路徑。
    vocab_file:生成的詞匯表文件路徑。
    vocab_size:詞匯表大小,即最多包含多少個單詞。
     ignore_single 的布爾型參數(shù),默認為 False。如果設(shè)置為 True,則不會將單個字添加到詞匯表中
    '''
    # 讀取文本文件并進行分詞
    with open(text_file, 'r', encoding='utf-8') as f:
        text = f.read()
    words = jieba.lcut(text)

    # 統(tǒng)計詞頻
    counter = Counter(words)
    if ignore_single:
        counter = {word: freq for word, freq in counter.items() if len(word) > 1}
    sorted_words = sorted(counter.items(), key=lambda x: x[1], reverse=True)

    # 保存詞匯表文件
    with open(vocab_file, 'w', encoding='utf-8') as f:
        for i, (word, freq) in enumerate(sorted_words):
            if i >= vocab_size:
                break
            f.write(word + '\n')


dir_path = os.path.dirname(os.path.abspath(__file__))  # 本腳本所在的目錄路徑,
novel_file_path = os.path.join(dir_path, "西游記.txt")
vocab_path = os.path.join(dir_path, "vocab.txt")
build_vocab(novel_file_path, vocab_path, 48000)

?

1.讀取小說文件,平分成100份,100份后多余的部分舍棄.每份保存到一個文件

import os
from tqdm import tqdm

if __name__ == '__main__':
    dir_path = os.path.dirname(os.path.abspath(__file__))  # 本腳本所在的目錄路徑
    novel_file_path = os.path.join(dir_path, "西游記.txt")
    split_novel_path = os.path.join(dir_path, "split_novel")

    # 創(chuàng)建保存 tokenized 文件的目錄
    if not os.path.exists(split_novel_path):
        os.mkdir(split_novel_path)

    with open(novel_file_path, 'r', encoding='utf8') as f:
        print('reading lines')
        single = f.read()

    len_single = len(single)
    num_pieces = 100
    for i in tqdm(range(num_pieces)):
        # 從 single 中截取一段長度為 len_single // num_pieces
        # 并進行分詞
        sub_text = single[len_single // num_pieces * i: len_single // num_pieces * (i + 1)]
        seg_file_path = os.path.join(split_novel_path, f"split_novel_{i}.txt")
        with open(seg_file_path, 'w', encoding='utf8') as f:
            f.write(sub_text)

2.每份字符串用cut函數(shù)分詞,單詞之間用空格連接區(qū)分 ,然后把每份寫到 word_segmentation文件夾內(nèi),每份名稱word_segmentation_0.txt-word_segmentation_99.txt

'''
from vocab import Vocab

# 創(chuàng)建一個詞匯表對象
vocab = Vocab('vocab.txt')

# 對輸入文本進行分詞
text = '我愛自然語言處理'
tokens = vocab.cut(text)
print(tokens) # ['我', '愛', '[UNK]', '[UNK]']

# 將單詞列表編碼成單詞索引列表
token_ids = vocab.encode_tokens(tokens)
print(token_ids) # [143, 54, 0, 0]

# 將單詞索引列表解碼成單詞列表
decoded_tokens = vocab.decode_tokens(token_ids)
print(decoded_tokens) # ['我', '愛', '[UNK]', '[UNK]']
'''



class Vocab:
    def __init__(self, vocab_file):
        """
        從給定的詞匯表文件中構(gòu)建一個詞匯表對象,并將每個單詞與其對應(yīng)的索引建立映射關(guān)系。
        Args:
            vocab_file (str): 詞匯表文件路徑。
        """
        self.token2id = {}  # 詞匯表中每個單詞與其索引之間的映射(字典)
        self.id2token = {}  # 詞匯表中每個索引與其對應(yīng)的單詞之間的映射(字典)

        # 讀取詞匯表文件,將每個單詞映射到其索引
        with open(vocab_file, 'r', encoding='utf-8') as f:
            for i, line in enumerate(f):
                token = line.strip()  # 移除行尾的換行符并得到單詞
                self.token2id[token] = i  # 將單詞映射到其索引
                self.id2token[i] = token  # 將索引映射到其對應(yīng)的單詞
        self.num_tokens = len(self.token2id)  # 詞匯表中單詞的數(shù)量
        self.unknown_token = '[UNK]'  # 特殊的未知標記
        self.pad_token = '[PAD]'  # 用于填充序列的特殊標記(在這里僅用于編碼)
        self.pad_token_id = self.token2id.get(self.pad_token, -1)  # 填充標記的索引

    def cut(self, input_str):
        """
        中文語句分詞的算法  用python代碼 cut函數(shù) 參數(shù) 詞匯表文件 和 語句str
        詞匯表文件 每行一個詞語,

        1.詞匯表字典的鍵為詞匯,值為該詞匯在詞匯表中的行號-1,也即該詞匯在詞匯表中的索引位置。
        3.輸入的中文語句,從左到右依次遍歷每一個字符,以當(dāng)前字符為起點嘗試匹配一個詞匯。具體匹配方式如下:

        a. 從當(dāng)前字符開始,依次向后匹配,直到找到一個最長的詞匯。如果該詞匯存在于詞典中,就將其作為一個分詞結(jié)果,并將指針移動到該詞匯的后面一個字符。如果該詞匯不存在于詞典中,則將當(dāng)前字符作為一個單獨的未知標記,同樣將其作為一個分詞結(jié)果,并將指針移動到下一個字符。
        b. 如果從當(dāng)前字符開始,沒有找到任何詞匯,則將當(dāng)前字符作為一個單獨的未知標記,同樣將其作為一個分詞結(jié)果,并將指針移動到下一個字符。
        重復(fù)上述過程,直到遍歷完整個輸入的中文語句,得到所有的分詞結(jié)果列表。
        """
        result = []
        i = 0
        while i < len(input_str):
            longest_word = input_str[i]
            for j in range(i + 1, len(input_str) + 1):
                if input_str[i:j] in self.token2id:
                    longest_word = input_str[i:j]
            result.append(longest_word)
            i += len(longest_word)
        return result


    def encode_tokens_strToint(self, tokens):
        """
        將給定的單詞列表編碼成對應(yīng)的單詞索引列表。
        如果一個單詞在詞匯表中沒有出現(xiàn),則將其替換為特殊的未知標記。
        Args:
            tokens (list): 待編碼的單詞列表。
        Returns:
            token_ids (list): 編碼后的單詞索引列表。
        """
        return [self.token2id.get(token, self.token2id[self.unknown_token]) for token in tokens]

    def decode_tokens_intTostr(self, token_ids):

        """
        將給定的單詞索引列表解碼成對應(yīng)的單詞列表。
        如果一個索引在詞匯表中沒有對應(yīng)的單詞,則將其替換為特殊的未知標記。
        Args:
            token_ids (list): 待解碼的單詞索引列表。
        Returns:
        tokens (list): 解碼后的單詞列表。
        """
        return [self.id2token.get(token_id, self.unknown_token) for token_id in token_ids]

import os
import threading
from multiprocessing import Process
from Vocab import Vocab


def process_file(i: int, content: str, vocab: Vocab, word_segmentation_path: str):
    # 進行分詞并保存到文件
    seg = vocab.cut(content)
    file_path = os.path.join(word_segmentation_path, f"word_segmentation_{i}.txt")
    with open(file_path, "w", encoding="utf-8") as f:
        f.write(" ".join(seg))

    print(f"Thread-{threading.current_thread().ident} finished processing file-{i}")


def many_Process():
    dir_path = os.path.dirname(os.path.abspath(__file__))  # 本腳本所在的目錄路徑
    novel_file_path = os.path.join(dir_path, "西游記.txt")
    tokenized_data_path = os.path.join(dir_path, "tokenized")
    vocab_path = os.path.join(dir_path, "vocab.txt")
    word_segmentation_path = os.path.join(dir_path, "word_segmentation")
    split_novel_path = os.path.join(dir_path, "split_novel")

    # 創(chuàng)建保存結(jié)果的文件夾
    os.makedirs(word_segmentation_path, exist_ok=True)

    # 定義文件名和分割數(shù)
    num_splits = 100

    for i in range(num_splits):
        seg_file_path = os.path.join(split_novel_path, f"split_novel_{i}.txt")
        with open(seg_file_path, 'r', encoding='utf8') as f:
            content = f.read()
        # 創(chuàng)建Vocab實例
        vocab = Vocab(vocab_path)
        proc1 = Process(target=process_file, args=(i, content, vocab, word_segmentation_path))
        proc1.start()


if __name__ == '__main__':
    many_Process()

3.把分詞文件轉(zhuǎn)換為int數(shù)字文件

import os

def main():
    dir_path = os.path.dirname(os.path.abspath(__file__))  # 本腳本所在的目錄路徑
    novel_file_path = os.path.join(dir_path, "西游記.txt")
    tokenized_data_path = os.path.join(dir_path, "tokenized")
    vocab_path = os.path.join(dir_path, "vocab.txt")
    word_segmentation_path = os.path.join(dir_path, "word_segmentation")

    # 讀取詞匯表
    with open(vocab_path, "r", encoding="utf-8") as f:
        vocab = {}
        for i, line in enumerate(f):
            word = line.strip()
            vocab[word] = i

    # 讀取分詞文件并轉(zhuǎn)換為token
    for i in range(100):
        seg_file_path = os.path.join(word_segmentation_path, f"word_segmentation_{i}.txt")
        token_file_path = os.path.join(tokenized_data_path, f"tokenized_train_{i}.txt")
        with open(seg_file_path, "r", encoding="utf-8") as f:
            with open(token_file_path, "w", encoding="utf-8") as fw:
                for line in f:
                    tokens = []
                    for word in line.strip().split():
                        if word in vocab:
                            tokens.append(str(vocab[word]))
                    if tokens:
                        fw.write(" ".join(tokens) + "\n")


if __name__ == '__main__':
    main()

5.調(diào)用訓(xùn)練腳本 train.py

import transformers
import torch
print(torch.cuda.current_device())
import os
import random
import argparse
import numpy as np
from torch.nn import DataParallel
from tqdm import tqdm
import datetime


def is_tokenizer(tokenized_data_path):
    if not os.path.exists(tokenized_data_path):
        return False

    # 獲取目錄下(包含子目錄)的所有文件數(shù)
    file_nums = sum([len(files) for root, dirs, files in os.walk(tokenized_data_path)])
    if file_nums > 1:
        return True
    else:
        return False


def main():
    # char_to_int.run()
    parser = argparse.ArgumentParser()
    parser.add_argument('--device', default='0,1,2,3', type=str, required=False, help='設(shè)置使用哪些顯卡')
    parser.add_argument('--model_config', default='./config.json', type=str, required=False,help='選擇模型參數(shù)')
    parser.add_argument('--tokenizer_path', default='./newvocab.txt', type=str, required=False, help='選擇詞庫')
    parser.add_argument('--tokenized_data_path', default='./tokenized/', type=str, required=False,help='tokenized語料存放位置')
    parser.add_argument('--raw', action='store_true', help='是否先做tokenize')
    parser.add_argument('--epochs', default=50000, type=int, required=False, help='訓(xùn)練循環(huán)')
    parser.add_argument('--batch_size', default=1, type=int, required=False, help='訓(xùn)練batch size')
    parser.add_argument('--lr', default=1.5e-4, type=float, required=False, help='學(xué)習(xí)率')
    parser.add_argument('--warmup_steps', default=2000, type=int, required=False, help='warm up步數(shù)')
    parser.add_argument('--log_step', default=1, type=int, required=False, help='多少步匯報一次loss')
    parser.add_argument('--stride', default=768, type=int, required=False, help='訓(xùn)練時取訓(xùn)練數(shù)據(jù)的窗口步長')
    parser.add_argument('--gradient_accumulation', default=1, type=int, required=False, help='梯度積累')
    parser.add_argument('--fp16', action='store_true', help='混合精度')
    parser.add_argument('--fp16_opt_level', default='O1', type=str, required=False)
    parser.add_argument('--max_grad_norm', default=1.0, type=float, required=False)
    parser.add_argument('--num_pieces', default=100, type=int, required=False, help='將訓(xùn)練語料分成多少份')
    parser.add_argument('--output_dir', default='model/', type=str, required=False, help='模型路徑')
    parser.add_argument('--pretrained_model', default='', type=str, required=False, help='模型訓(xùn)練起點路徑')
    parser.add_argument('--segment', action='store_true', help='中文以詞為單位')
    args = parser.parse_args()
    print('args:\n' + args.__repr__())


    is_random_shuffle_data=False    # 是否打亂順序進行訓(xùn)練

    if args.segment:
        from tokenizations import tokenization_bert_word_level as tokenization_bert
    else:
        from tokenizations import tokenization_bert

    os.environ["CUDA_VISIBLE_DEVICES"] = args.device  # 此處設(shè)置程序使用哪些顯卡
    model_config = transformers.models.gpt2.GPT2Config.from_json_file(args.model_config)
    print('config:\n' + model_config.to_json_string())

    n_ctx = model_config.n_ctx
    full_tokenizer = tokenization_bert.BertTokenizer(vocab_file=args.tokenizer_path)
    full_tokenizer.max_len = 999999
    device = 'cuda' if torch.cuda.is_available() else 'cpu'

    print('using device:', device)


    tokenized_data_path = args.tokenized_data_path
    raw = is_tokenizer(tokenized_data_path)  # 選擇是否從零開始構(gòu)建數(shù)據(jù)集
    epochs = args.epochs
    batch_size = args.batch_size
    lr = args.lr
    warmup_steps = args.warmup_steps
    log_step = args.log_step
    stride = args.stride
    gradient_accumulation = args.gradient_accumulation
    fp16 = args.fp16  # 不支持半精度的顯卡請勿打開
    fp16_opt_level = args.fp16_opt_level
    max_grad_norm = args.max_grad_norm
    num_pieces = args.num_pieces
    output_dir = args.output_dir

    if raw == False:
        print('building files')


    model_dir = args.output_dir
    config_file = os.path.join(model_dir, 'config.json')
    pytorch_model_file = os.path.join(model_dir, 'pytorch_model.bin')

    if os.path.isfile(config_file) and os.path.isfile(pytorch_model_file):
        print('模型文件存在,加載已訓(xùn)練過的模型,繼續(xù)訓(xùn)練...')
        model = transformers.models.gpt2.GPT2LMHeadModel.from_pretrained(model_dir)
    else:
        print('模型文件不存在,創(chuàng)建新的模型,開始訓(xùn)練...')
        model = transformers.models.gpt2.GPT2LMHeadModel(config=model_config)

    model.train()
    model.to(device)
    print(model)
    multi_gpu = False
    full_len = 0
    print('calculating total steps')
    for i in tqdm(range(num_pieces)):
        with open(tokenized_data_path + 'tokenized_train_{}.txt'.format(i), 'r') as f:
            full_len += len([int(item) for item in f.read().strip().split()])
    total_steps = int(full_len / stride * epochs / batch_size / gradient_accumulation)
    print('total steps = {}'.format(total_steps))
    optimizer = transformers.AdamW(model.parameters(), lr=lr, correct_bias=True)
    scheduler = transformers.get_linear_schedule_with_warmup(optimizer, num_warmup_steps=warmup_steps,
                                                             num_training_steps=total_steps)

    steps_Count = 0
    if fp16:
        try:
            from apex import amp
        except ImportError:
            raise ImportError("Please install apex from https://www.github.com/nvidia/apex to use fp16 training.")
        model, optimizer = amp.initialize(model, optimizer, opt_level=fp16_opt_level)

    if torch.cuda.device_count() > 1:
        print("Let's use", torch.cuda.device_count(), "GPUs!")
        model = DataParallel(model)
        multi_gpu = True
    print('calculating total steps')
    for i in tqdm(range(num_pieces)):  # 迭代處理所有的 tokenized_train_{}.txt 文件
        with open(tokenized_data_path + 'tokenized_train_{}.txt'.format(i), 'r') as f:  # 打開文件
            full_len += len([int(item) for item in f.read().strip().split()])  # 統(tǒng)計文件中數(shù)字的數(shù)量
    total_steps = int(full_len / stride * epochs / batch_size / gradient_accumulation)  # 計算總共需要迭代的步數(shù)
    print('total steps = {}'.format(total_steps))  # 打印總共需要迭代的步數(shù)
    optimizer = transformers.AdamW(model.parameters(), lr=lr, correct_bias=True)  # 定義優(yōu)化器
    scheduler = transformers.get_linear_schedule_with_warmup(optimizer, num_warmup_steps=warmup_steps,
                                                             num_training_steps=total_steps)  # 定義學(xué)習(xí)率調(diào)度器

    steps_Count = 0  # 初始化迭代步數(shù)
    if fp16:  # 判斷是否使用半精度浮點數(shù)
        try:
            from apex import amp  # 嘗試導(dǎo)入 apex 庫
        except ImportError:
            raise ImportError("Please install apex from https://www.github.com/nvidia/apex to use fp16 training.")
        model, optimizer = amp.initialize(model, optimizer, opt_level=fp16_opt_level)  # 將模型和優(yōu)化器轉(zhuǎn)換成半精度浮點數(shù)

    if torch.cuda.device_count() > 1:  # 判斷是否有多個 GPU
        print("Let's use", torch.cuda.device_count(), "GPUs!")
        model = DataParallel(model)  # 多 GPU 并行計算
        multi_gpu = True  # 標記啟用了多 GPU
    print('starting training')  # 打印開始訓(xùn)練
    running_loss = 0  # 初始化損失值
    run_pice = 0  # 初始化處理的文件數(shù)量

    elapsed_minutes = 3  # 每過 20 分鐘后 就會休息 3.5分鐘.
    rest_minutes = 1.2
    start_time = datetime.datetime.now()

    for epoch in range(epochs):
        print('epoch {}'.format(epoch + 1))
        now = datetime.datetime.now()
        print('time: {}'.format(now))
        x = np.linspace(0, num_pieces - 1, num_pieces, dtype=np.int32)  # 生成0~num_pieces-1的等差數(shù)列
        if is_random_shuffle_data:
            random.shuffle(x)  # 打亂數(shù)列順序
        piece_num = 0
        for i in x:  # 遍歷每個文件
            with open(tokenized_data_path + 'tokenized_train_{}.txt'.format(i), 'r') as f:  # 打開tokenized_train_i.txt文件
                line = f.read().strip()  # 讀取整個文件的內(nèi)容,并移除字符串首尾的空格符
            tokens = line.split()  # 按照空格符分割字符串,得到單詞列表
            tokens = [int(token) for token in tokens]  # 將單詞列表中的元素轉(zhuǎn)化為整型數(shù)值
            start_point = 0
            samples = []  # 存儲數(shù)據(jù)樣本的列表
            while start_point < len(tokens) - n_ctx:  # 循環(huán)采樣數(shù)據(jù)樣本,直到文本結(jié)束
                samples.append(tokens[start_point: start_point + n_ctx])  # 截取長度為n_ctx的數(shù)據(jù)樣本,并加入列表
                start_point += stride  # 步長為stride
            if start_point < len(tokens):  # 如果剩下的單詞數(shù)小于n_ctx
                samples.append(tokens[len(tokens) - n_ctx:])  # 將剩下的單詞作為一個數(shù)據(jù)樣本加入列表
            if is_random_shuffle_data:
                random.shuffle(samples)  # 打亂數(shù)據(jù)樣本的順序
            for step in range(len(samples) // batch_size):  # 將數(shù)據(jù)樣本按batch_size分組,遍歷每個batch
                #  準備數(shù)據(jù)  # 1. 獲取輸入的 batch
                batch = samples[step * batch_size: (step + 1) * batch_size]  # 獲取當(dāng)前batch的數(shù)據(jù)樣本
                batch_labels = []  # 存儲batch的標簽
                batch_inputs = []  # 存儲batch的輸入
                for ids in batch:  # 遍歷當(dāng)前batch的數(shù)據(jù)樣本
                    int_ids_for_labels = [int(x) for x in ids]  # 將數(shù)據(jù)樣本中的每個單詞轉(zhuǎn)化為整型數(shù)值,得到標簽序列
                    int_ids_for_inputs = [int(x) for x in ids]  # 將數(shù)據(jù)樣本中的每個單詞轉(zhuǎn)化為整型數(shù)值,得到輸入序列
                    batch_labels.append(int_ids_for_labels)  # 將標簽序列加入batch_labels列表
                    batch_inputs.append(int_ids_for_inputs)  # 將輸入序列加入batch_inputs列表
                batch_labels = torch.tensor(batch_labels).long().to(device)  # 將batch_labels轉(zhuǎn)化為PyTorch的tensor,并移動到GPU上
                batch_inputs = torch.tensor(batch_inputs).long().to(device)  # 將batch_inputs轉(zhuǎn)化為PyTorch的tensor,并移動到GPU上

                # 2. 正向傳播
                outputs = model.forward(input_ids=batch_inputs, labels=batch_labels)
                loss, logits = outputs[:2]

                # 3. 計算損失函數(shù)
                if multi_gpu:
                    loss = loss.mean()
                if gradient_accumulation > 1:
                    loss = loss / gradient_accumulation

                # 4. 損失函數(shù)反向傳播
                if fp16:
                    with amp.scale_loss(loss, optimizer) as scaled_loss:
                        scaled_loss.backward()
                        torch.nn.utils.clip_grad_norm_(amp.master_params(optimizer), max_grad_norm)
                else:
                    loss.backward()
                    torch.nn.utils.clip_grad_norm_(model.parameters(), max_grad_norm)

                # 5. 更新參數(shù) optimizer step
                if (step + 1) % gradient_accumulation == 0:
                    running_loss += loss.item()
                    optimizer.step()
                    optimizer.zero_grad()
                    scheduler.step()
                if (step + 1) % log_step == 0:
                    steps_Count += 1
                    print('now time: {}:{}. Step {} / {} of piece {} of epoch {}, loss {}'.format(
                        datetime.datetime.now().hour,
                        datetime.datetime.now().minute,
                        steps_Count,
                        total_steps,
                        len(samples) // batch_size,
                        epoch + 1,
                        running_loss / log_step))
                    running_loss = 0

                if run_pice % 1000 == 0 and run_pice > 999:
                    model_to_save = model.module if hasattr(model, 'module') else model
                    print('保存模型中...')
                    model_to_save.save_pretrained(output_dir)
                run_pice += 1
            piece_num += 1

    print('saving model for epoch {}'.format(epoch + 1))
    if not os.path.exists(output_dir):
        os.mkdir(output_dir)
    model_to_save = model.module if hasattr(model, 'module') else model
    model_to_save.save_pretrained(output_dir)
    print('epoch {} finished'.format(epoch + 1))

    then = datetime.datetime.now()
    print('time: {}'.format(then))
    print('time for one epoch: {}'.format(then - now))

    print('training finished')

    if not os.path.exists(output_dir):
        os.mkdir(output_dir)
    model_to_save = model.module if hasattr(model, 'module') else model
    model_to_save.save_pretrained(output_dir)

if __name__ == '__main__':
    torch.cuda.init()
    main()

6.生成腳本?generate.py

import torch
from transformers import GPT2LMHeadModel
from tokenizations import tokenization_bert

def top_k_top_p_filtering(logits, top_k=0, top_p=0.0, filter_value=-float('Inf')):
    if top_k > 0:
        top_k_values, top_k_indices = torch.topk(logits, top_k, dim=-1)
        logits = logits.masked_fill(logits < torch.max(top_k_values, dim=-1, keepdim=True).values, filter_value)

    if top_p > 0.0:
        sorted_logits, sorted_indices = torch.sort(logits, descending=True)
        cumulative_probs = torch.cumsum(torch.softmax(sorted_logits, dim=-1), dim=-1)
        sorted_indices_to_remove = cumulative_probs > top_p

    if top_k > 0:
        sorted_indices_to_remove[..., :top_k] = 0
        indices_to_remove = sorted_indices[sorted_indices_to_remove]
        mask = torch.zeros_like(logits, dtype=torch.bool).to(device)
        for idx in indices_to_remove:
            mask = torch.logical_or(mask, torch.eq(logits, idx))
        logits = logits.masked_fill(mask, filter_value)

    return logits


def is_word(word):
    for item in list(word):
        if item not in 'qwertyuiopasdfghjklzxcvbnm':
            return False
    return True

def _is_chinese_char(char):
    """Checks whether CP is the codepoint of a CJK character."""
    # This defines a "chinese character" as anything in the CJK Unicode block:
    #   https://en.wikipedia.org/wiki/CJK_Unified_Ideographs_(Unicode_block)
    #
    # Note that the CJK Unicode block is NOT all Japanese and Korean characters,
    # despite its name. The modern Korean Hangul alphabet is a different block,
    # as is Japanese Hiragana and Katakana. Those alphabets are used to write
    # space-separated words, so they are not treated specially and handled
    # like the all of the other languages.
    cp = ord(char)
    if ((cp >= 0x4E00 and cp <= 0x9FFF) or  #
            (cp >= 0x3400 and cp <= 0x4DBF) or  #
            (cp >= 0x20000 and cp <= 0x2A6DF) or  #
            (cp >= 0x2A700 and cp <= 0x2B73F) or  #
            (cp >= 0x2B740 and cp <= 0x2B81F) or  #
            (cp >= 0x2B820 and cp <= 0x2CEAF) or
            (cp >= 0xF900 and cp <= 0xFAFF) or  #
            (cp >= 0x2F800 and cp <= 0x2FA1F)):  #
        return True
    return False

def tokenizer_decode(tokenizer,out_text):
    text = tokenizer.convert_ids_to_tokens(out_text)

    for i, item in enumerate(text[:-1]):  # 確保英文前后有空格
        if is_word(item) and is_word(text[i + 1]):
            text[i] = item + ' '
    for i, item in enumerate(text):
        if '[UNK]' ==item:
            text[i] = ''
        if item == '[CLS]' or item == '[SEP]':
            text[i] = '\n'
        if item == '[PAD]' or '[MASK]' == item:
            text[i] = ' '

    text = ''.join(text)
    return text



def generate_novel(prompt, temperature=0.7, top_k=0, top_p=0.9, length=2000, repetition_penalty=1.0):
    print(prompt, end="")
    # 將輸入的 prompt 轉(zhuǎn)化為 token id
    input_ids = tokenizer.encode(prompt, return_tensors='pt').to(device)
    # 生成一個和 input_ids 相同形狀的 tensor,全部為 1
    input_mask = torch.ones(input_ids.shape, dtype=torch.long).to(device)

    # 生成的文本初始化為 prompt
    generated_text = tokenizer.decode(input_ids[0], skip_special_tokens=True)
    # 禁用梯度計算
    with torch.no_grad():
        # 控制生成文本長度小于 length
        while len(generated_text) < length:
            # 對 input_ids 進行前向傳播,獲取輸出 logits
            outputs = model(input_ids=input_ids, attention_mask=input_mask)
            logits = outputs.logits[:, -1, :] / temperature
            # 對 logits 進行 top-k 和 top-p 過濾
            filtered_logits = top_k_top_p_filtering(logits, top_k=top_k, top_p=top_p)
            
            # 對已經(jīng)生成的 token 進行重復(fù)懲罰
            for i in range(len(input_ids[0])):
                if input_ids[0][i] == filtered_logits[0].argmax().item():
                    filtered_logits[0][i] /= repetition_penalty
            
            # 計算下一個 token 的概率分布,并采樣出下一個 token
            probabilities = torch.softmax(filtered_logits, dim=-1)
            next_token = torch.multinomial(probabilities, num_samples=1)
            # 將生成的 token 拼接到 input_ids 中
            input_ids = torch.cat((input_ids, next_token), dim=1)
            # 重新生成一個和 input_ids 相同形狀的 tensor,全部為 1
            input_mask = torch.ones(input_ids.shape, dtype=torch.long).to(device)
            # 將生成的 token 轉(zhuǎn)化為文本,拼接到 generated_text 中
            new_text = tokenizer_decode(tokenizer,next_token[0])
            print(new_text, end="")
            generated_text +=new_text
            # 如果生成的文本長度已經(jīng)超過 length,結(jié)束生成過程
            if len(generated_text) >= length:
                break
    return generated_text


tokenizer = tokenization_bert.BertTokenizer('./vocab.txt')
model = GPT2LMHeadModel.from_pretrained( "./model/")
device = "cuda" if torch.cuda.is_available() else "cpu"
model.to(device)
model.eval()
prompt =  "孫悟空吃完仙桃,"

generate_novel(prompt)

?文本生成效果

第三回情友。卻說那沙僧急急抬頭觀看, 第二指腰尸往里觀看,闖入斗柄賀喜環(huán)現(xiàn)出鮮紅之下,看見八戒者即著腳手往里觀看,看見, 著實個活捉了鋼刀,半霧,把個燈籠。行者道:“老施主,上禪。那長老看何地方,只見海邊此必是救出師父,潑猢猻打破唐僧,拿住得受用槍!” 慌得就問老大慌了手腳,把釘鈀輪著訣,對對唐僧,就問曰:“若不是甚么披掛來也!開門,又搖身抵語,有莫打破人頭打破了?!?旁有張睜睛看處,釘鈀筑了,把個大睜睛看處,原來那怪見有八萬四千鋼頭鉆將出來厲聲高叫道:“潑猢猻!你從成精之對你這潑物,長的根,卻不認得尊神饒命!你不知是個器只叫你,我也?”八戒道:“你,把門的?”八戒道:“你不知,斷乎是我們斗瓦噴,把他就跳下何處睡看我,我們且是個假的?!?八戒道:“不要怕,你轉(zhuǎn)鈀,皺頭綁得甚,把個干凈,卻將起來,八戒道:“拿得我等我?” 八戒道:“我還未哭得象盤跌了,卻就顧得脫了八戒道:“師父不濟!我們幾口,等不知,就答應(yīng)?!卑私涞溃骸按糇訝?,乃是個假八戒道:“看棍!” 八戒道:“我再不敢看。你使兵,使一條槍槍就去救師,八戒依言,只情打了,八戒道:“正是!正是!” 那長老歡歡喜喜。八戒道:“且顧得脫手。你不知,卻又吩咐,等候他繩來!”須臾跪倒,盡睡去尋看去,八戒對八戒道:“虧他綁在那里去了。”好行者道:“正是,只說:“都到此盡皆是假人頭下海。但只說開了!我們走過法兒,再不敢歸寢,斷然傾勢,卻又從澗枯眼就把他個卻又從木兒,把勢盡皆看處,卻又使盡盡盡盡鈀鐵棒把勢盡盡拔下起,又不見了一下,就變做個一股之內(nèi)卻又只見了:“小的們!果然是甚的們!” 三藏認得他?行者道:“他!” 行者道:“也不怕,看得明白,見駕祥云,到后門邊,見了,就趕到山門前枕了手,徑至山門,見了一把摸觀看。三藏忽抬頭看時,慌得只見那僧官叫聲“仙童,你下馬來至林中,慌得孫大圣開上來接起了,右手淚落的笑道:“拿住了。你怎么就低頭看時,那里認得?” 忙忙答禮道:“我不是甚么?” 八戒道:“師父請你從何來?”八戒道:“你從何來?”八戒道:“你多目魔何在?” 八戒道:“你之命,八戒道:“我把你受用!你把我們定,把行李埋,就低頭而來。八戒道:“我有一樁這個猴子!不打緊,怎么今日卻要回,你!你認他多破了我使尸綁了我們救了,把你將下去,八戒笑道:“你!那呆子不去了,卻怎么轉(zhuǎn)要法,卻怎么不認得誰?” 八戒道:“我想?你受了!你要蒸死了!你得翻倒一鈀逼,卻怎么去,放聲大哭?!?八戒道:“我。你了,把勢!令牌俱念了一下,莫誤了,使鈀鉆入里面走時,又是開之筑倒在空中干鼓撒了!” 八戒道:“八戒道:“兄弟們起個人言,咬著牙,那木叉勒掯兵盡棍好取笑。!打,卻將下去戲他賭物景象!”那推云先鋒道:“你便就弄本事,呆子!你聽我內(nèi)中樹林皎,上前來趕我綁在空中影,倒飛下來,又依舊返隔架遮攔,直在身上,伏尸,倒丹爐念了。畢竟不知休齁,且駕祥云。你看得溫苗。卻說無事,功完大覺圣,且聽下回分解。休教威風(fēng)無二推倒兇心,修身檄安營破 第六十回黑河潮攀雨車囊施威性本性盡念無心,夜忘解懷車鉆兒,休教神狂。休教兇,炬照氣滾了性參差。至今終剛強原檄,文章來源地址http://www.zghlxwxcb.cn/news/detail-647080.html

到了這里,關(guān)于GPT2-Chinese 文本生成,訓(xùn)練AI寫小說,AI寫小說2的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • 開啟想象翅膀:輕松實現(xiàn)文本生成模型的創(chuàng)作應(yīng)用,支持LLaMA、ChatGLM、UDA、GPT2、Seq2Seq、BART、T5、SongNet等模型,開箱即用

    開啟想象翅膀:輕松實現(xiàn)文本生成模型的創(chuàng)作應(yīng)用,支持LLaMA、ChatGLM、UDA、GPT2、Seq2Seq、BART、T5、SongNet等模型,開箱即用

    TextGen 實現(xiàn)了多種文本生成模型,包括:LLaMA、ChatGLM、UDA、GPT2、Seq2Seq、BART、T5、SongNet等模型,開箱即用。 [2023/06/15] v1.0.0版本: 新增ChatGLM/LLaMA/Bloom模型的多輪對話微調(diào)訓(xùn)練,并發(fā)布醫(yī)療問診LoRA模型shibing624/ziya-llama-13b-medical-lora。詳見Release-v1.0.0 [2023/06/02] v0.2.7版本: 新增ChatG

    2024年02月13日
    瀏覽(22)
  • 【預(yù)訓(xùn)練語言模型】使用Transformers庫進行GPT2預(yù)訓(xùn)練

    【預(yù)訓(xùn)練語言模型】使用Transformers庫進行GPT2預(yù)訓(xùn)練

    基于 HuggingFace的Transformer庫,在Colab或Kaggle進行預(yù)訓(xùn)練。 本教程提供:英文數(shù)據(jù)集wikitext-2和代碼數(shù)據(jù)集的預(yù)訓(xùn)練。 注:可以自行上傳數(shù)據(jù)集進行訓(xùn)練 目的 :跑通自回歸語言模型的預(yù)訓(xùn)練流程 注意:在Colab上訓(xùn)練時,最好將datasets更新到最新版(再重啟kernel),避免版本低報

    2024年03月14日
    瀏覽(21)
  • GPT2訓(xùn)練自己的對話問答機器人

    GPT2訓(xùn)練自己的對話問答機器人

    這里我搭建了虛擬的3.6環(huán)境 基于GPT2的中文閑聊機器人,模型實現(xiàn)基于HuggingFace的transformers ,精讀GPT2-Chinese的論文和代碼,獲益匪淺。 data/train.txt:默認的原始訓(xùn)練集文件,存放閑聊語料;data/train.pkl:對原始訓(xùn)練語料進行tokenize之后的文件,存儲一個list對象,list的每條數(shù)據(jù)表示一個

    2024年02月12日
    瀏覽(23)
  • Midreal AI 互動小說文本生成工具游戲更新了網(wǎng)頁版本,不需要在 Discord 里面使用了

    Midreal AI是一款革命性的AI小說生成工具,它不僅能夠生成具有邏輯性和創(chuàng)造力的小說,還具備高度的互動能力。用戶在使用過程中可以在關(guān)鍵節(jié)點選擇劇情走向,甚至還能生成配圖,使得整個創(chuàng)作過程更加豐富和個性化。Midreal AI的開發(fā)背后是MIT、NYU、劍橋、普林斯頓等頂尖大

    2024年04月16日
    瀏覽(26)
  • 阿里云AIGC- 使用Megatron-Deepspeed訓(xùn)練GPT-2并生成文本

    阿里云AIGC- 使用Megatron-Deepspeed訓(xùn)練GPT-2并生成文本

    本文介紹如何使用GPU云服務(wù)器,使用 Megatron-Deepspeed框架 訓(xùn)練GPT-2模型并生成文本。 GPT-2模型是OpenAI于 2018年在GPT模型 的基礎(chǔ)上發(fā)布的新的 無監(jiān)督NLP模型 ,當(dāng)時被稱為“史上最強通用NLP模型”。該模型可以生成 連貫的文本段落 ,并且能在 未經(jīng)預(yù)訓(xùn)練 的情況下,完成閱讀理解

    2024年02月09日
    瀏覽(19)
  • 大語言模型的預(yù)訓(xùn)練[2]:GPT、GPT2、GPT3、GPT3.5、GPT4相關(guān)理論知識和模型實現(xiàn)、模型應(yīng)用以及各個版本之間的區(qū)別詳解

    大語言模型的預(yù)訓(xùn)練[2]:GPT、GPT2、GPT3、GPT3.5、GPT4相關(guān)理論知識和模型實現(xiàn)、模型應(yīng)用以及各個版本之間的區(qū)別詳解

    在自然語言處理問題中,可從互聯(lián)網(wǎng)上下載大量無標注數(shù)據(jù),而針對具體問題的有標注數(shù)據(jù)卻非常少,GPT 是一種半監(jiān)督學(xué)習(xí)方法,它致力于用大量無標注數(shù)據(jù)讓模型學(xué)習(xí) “常識”,以緩解標注信息不足的問題。其具體方法是在針對有標簽數(shù)據(jù)訓(xùn)練 Fine-tune 之前,用無標簽數(shù)據(jù)

    2024年02月16日
    瀏覽(91)
  • 檢測文本是否由AI生成,GPT、文心一言等均能被檢測

    檢測文本是否由AI生成,GPT、文心一言等均能被檢測

    目前很多機構(gòu)推出了ChatGPT等AI文本檢測工具,但是準確率主打一個模棱兩可,基本和拋硬幣沒啥區(qū)別。 先說結(jié)論,我們對比了常見的幾款A(yù)I檢測工具,copyleaks檢測相比較而言最準確。 來源:GPT3.5 提問詞:Redis有什么作用? Redis是一種開源的內(nèi)存數(shù)據(jù)庫,它具有多種作用和用途

    2024年02月14日
    瀏覽(24)
  • 手寫GPT實現(xiàn)小說生成(一)

    手寫GPT實現(xiàn)小說生成(一)

    本文開始從零實現(xiàn)GPT1做一個小說續(xù)寫器,即只需要給出一些文本,讓模型幫你續(xù)寫,主要內(nèi)容包含: 模型編寫 訓(xùn)練適配小說的中文分詞器 將小說按固定大小拆分生成數(shù)據(jù)集 拆分訓(xùn)練/測試集 訓(xùn)練 體驗小說續(xù)寫效果 同時結(jié)合HuggingFace的 transformers ,可以將處理好的數(shù)據(jù)集、訓(xùn)

    2024年01月20日
    瀏覽(15)
  • 文本生成高精準3D模型,北京智源AI研究院等出品—3D-GPT

    文本生成高精準3D模型,北京智源AI研究院等出品—3D-GPT

    北京智源AI研究院、牛津大學(xué)、澳大利亞國立大學(xué)聯(lián)合發(fā)布了一項研究—3D-GPT,通過文本問答方式就能創(chuàng)建高精準3D模型。 據(jù)悉,3D-GPT使用了大語言模型的多任務(wù)推理能力,通過任務(wù)調(diào)度代理、概念化代理和建模代理三大模塊,簡化了3D建模的開發(fā)流程實現(xiàn)技術(shù)民主化。 但3D-

    2024年02月03日
    瀏覽(29)
  • AIGC:利用多個AI技術(shù)前沿模型(GPT-3.5/GPT-4/Claude/ForefrontChat/HuggingChat)實現(xiàn)文本理解、生成文本類/圖片類的結(jié)果對比并分析性能案例集合

    AIGC:利用多個AI技術(shù)前沿模型(GPT-3.5/GPT-4/Claude/ForefrontChat/HuggingChat)實現(xiàn)文本理解、生成文本類/圖片類的結(jié)果對比并分析性能案例集合

    AIGC:利用多個AI技術(shù)前沿模型(GPT-3.5/GPT-4/Claude/ForefrontChat/HuggingChat)實現(xiàn)文本理解、生成文本類/圖片類的結(jié)果對比并分析性能案例集合 目錄 文本理解 1、理解語境中的術(shù)語含義 GPT-4的回答 GPT-3.5的回答 Forefront Chat(GPT-3.5)的回答 Claude+的回答 HuggingChat的回答 2、請用一句話總結(jié)貝

    2024年02月09日
    瀏覽(58)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包