ChatGPT最近大火?教你实现破产版ChatGPT(一)数据预处理

article/2024/9/17 2:59:25

目录

一.前言

二.下载数据文件

三.导包并设置使用GPU

四.加载和预处理数据

五.为模型准备数据


一.前言

最近ChatGPT大火,成功破圈,到底是个啥?

简单说,它是一个模型,一个语言模型!它是以对话方式与人进行交互的AI语言模型!

在很早以前,国内的大厂百度,就开发过“文心·NLP模型”等语言处理模型,比如用文心·NLP模型生成段落和文章,能做到开篇和文末点题,首位呼应,对文本相关内容进行引用等……

文心·NLP模型总体效果一般,有点差强人意,特别是在人类文字和人类语言的理解方面,有很多不融洽,输出的内容很多都存在衔接生硬牵强的问题。

也正因为如此,所以它也一直不温不火,只有少数相关公司和研究人工智能与机器学习的用户知道它,以前我了解后,觉得还有很长的路要走。

但这几天的ChatGPT明显不一样,对很多不懂不关注相关技术的人,都展示出了极强的吸引力,ChatGPT短短一周不到的时间,用户达到百万级,成功破圈,说明它是有值得研究的地方的。

在本教程中,我们探索一个好玩有趣的循环的序列到序列(sequence-to-sequence)的模型用例。我们将用Cornell Movie-Dialogs Corpus 处的电影剧本来训练一个简单的聊天机器人。

在人工智能研究领域中,对话模型是一个非常热门的话题。聊天机器人可以在各种设置中找到,包括客户服务应用和在线帮助。这些机器人通常 由基于检索的模型提供支持,这些模型的输出是某些形式问题预先定义的响应。在像公司IT服务台这样高度受限制的领域中,这些模型可能足够了, 但是,对于更一般的用例它们还不够健壮。让一台机器与多领域的人进行有意义的对话是一个远未解决的研究问题。最近,深度学习热潮已经允许 强大的生成模型,如谷歌的神经对话模型Neural Conversational Model,这标志着向多领域生成对话模型迈出了一大步。 在本教程中,我们将在PyTorch中实现这种模型。

教程要点

  • 对Cornell Movie-Dialogs Corpus数据集的加载和预处理
  • 用Luong attention mechanism(s)实现一个sequence-to-sequence模型
  • 使用小批量数据联合训练解码器和编码器模型
  • 实现贪婪搜索解码模块
  • 与训练好的聊天机器人互动

二.下载数据文件

下载数据文件点击这里并将其放入到当前目录下的data/ 文件夹下。

三.导包并设置使用GPU

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literalsimport torch
from torch.jit import script, trace
import torch.nn as nn
from torch import optim
import torch.nn.functional as F
import csv
import random
import re
import os
import unicodedata
import codecs
from io import openimport itertools
import mathUSE_CUDA = torch.cuda.is_available()
device = torch.device("cuda" if USE_CUDA else "cpu")

四.加载和预处理数据

#**********************************2.加载和预处理数据**********************************
'''
下一步就是格式化处理我们的数据文件并将数据加载到我们可以使用的结构中。 
Cornell Movie-Dialogs Corpus是一个丰富的电影角色对话数据集: * 10,292 对电影角色之间的220,579次对话 * 617部电影中的9,035个电影角色 * 总共304,713发言量
这个数据集庞大而多样,在语言形式、时间段、情感上等都有很大的变化。我们希望这种多样性使我们的模型能够适应多种形式的输入和查询。
首先,我们通过数据文件的某些行来查看原始数据的格式
'''
corpus_name = "cornell movie-dialogs corpus"
corpus = os.path.join("data", corpus_name)def printLines(file, n=10):with open(file, 'rb') as datafile:lines = datafile.readlines()#输出前n行的数据for line in lines[:n]:print(line)#printLines(os.path.join(corpus, "movie_lines.txt"))#**************************************2.1创建格式化数据文件 start **************************************
'''
为了方便起见,我们将创建一个格式良好的数据文件,其中每一行包含一个由tab制表符分隔的查询语句和响应语句对。
以下函数便于解析原始 movie_lines.txt 数据文件。 
* loadLines:将文件的每一行拆分为字段(lineID, characterID, movieID, character, text)组合的字典 
* loadConversations :根据movie_conversations.txt将loadLines中的每一行数据进行归类 
* extractSentencePairs: 从对话中提取句子对
'''
# 将文件的每一行拆分为字段字典
#fields中是各列字段的名字,即["lineID", "characterID", "movieID", "character", "text"]
def loadLines(fileName, fields):lines = {}with open(fileName, 'r', encoding='iso-8859-1') as f:for line in f:values = line.split(" +++$+++ ")# Extract fieldslineObj = {}for i, field in enumerate(fields):lineObj[field] = values[i]#每一个键值对对应一行数据,键是这一行的lineID,值是这一行对应的数据对象,即lineObj是字典(lines)里的字典lines[lineObj['lineID']] = lineObj#lines是对整个movie_lines.txt文件操作之后返回的含有格式化原数据的字典return lines# 将 `loadLines` 中的行字段分组为基于 *movie_conversations.txt* 的对话
#utterance话语
#fields中是各列字段的名字,即["character1ID", "character2ID", "movieID", "utteranceIDs"]
def loadConversations(fileName, lines, fields):conversations = []with open(fileName, 'r', encoding='iso-8859-1') as f:for line in f:values = line.split(" +++$+++ ")# Extract fields,和上面的那个函数的lineObj一个道理,即把movie_conversations.txt的每行的数据提取到一个字典中convObj = {}for i, field in enumerate(fields):convObj[field] = values[i]# Convert string to list (convObj["utteranceIDs"] == "['L598485', 'L598486', ...]")#eval函数的作用自行百度,就是会把字符串里的表达式进行计算lineIds = eval(convObj["utteranceIDs"])# Reassemble lines,Reassemble:重新组装convObj["lines"] = [] #给字典新加一个键值对,此键为linesfor lineId in lineIds:#即根据lineId把上面那个函数格式化的每行对应的字典对象添加到字典convObj的lines对应的值中convObj["lines"].append(lines[lineId])conversations.append(convObj)# conversations是对整个movie_conversations.txt文件操作之后返回的含有格式化原数据的字典return conversations# 从对话中提取一对句子
def extractSentencePairs(conversations):qa_pairs = []for conversation in conversations:# Iterate over all the lines of the conversationfor i in range(len(conversation["lines"]) - 1):  # We ignore the last line (no answer for it)#strip函数返回删除前导和尾随空格的字符串副本。如果给定了chars而不是None,则删除chars中的字符。inputLine = conversation["lines"][i]["text"].strip()targetLine = conversation["lines"][i+1]["text"].strip()# Filter wrong samples (if one of the lists is empty)if inputLine and targetLine:qa_pairs.append([inputLine, targetLine])#提取了文件中的所有对话return qa_pairs#******************************现在我们将调用这些函数来创建文件,我们命名为formatted_movie_lines.txt。******************************
# 定义新文件的路径(待生成)
datafile = os.path.join(corpus, "formatted_movie_lines.txt")'''
#delimiter:分隔符
delimiter = '\t'
#print('delimiter:',delimiter)
# codecs.decode()方法的使用参考https://zhuanlan.zhihu.com/p/377436438
delimiter = str(codecs.decode(delimiter, "unicode_escape"))
#print('delimiter:',delimiter)# 初始化行dict,对话列表和字段ID
lines = {}
conversations = []
MOVIE_LINES_FIELDS = ["lineID", "characterID", "movieID", "character", "text"]
MOVIE_CONVERSATIONS_FIELDS = ["character1ID", "character2ID", "movieID", "utteranceIDs"]# 加载行和进程对话,即调用函数进行格式化
print("\nProcessing corpus...")
lines = loadLines(os.path.join(corpus, "movie_lines.txt"), MOVIE_LINES_FIELDS)
print("\nLoading conversations...")
conversations = loadConversations(os.path.join(corpus, "movie_conversations.txt"),lines, MOVIE_CONVERSATIONS_FIELDS)# 写入新的csv文件
print("\nWriting newly formatted file...")
with open(datafile, 'w', encoding='utf-8') as outputfile:writer = csv.writer(outputfile, delimiter=delimiter, lineterminator='\n')pairs=extractSentencePairs(conversations)print('句子对数为:',pairs.__len__())for pair in pairs:writer.writerow(pair)# 打印一个样本的行
print("\nSample lines from file:")
printLines(datafile)
'''
#**************************************2.1创建格式化数据文件 end **************************************#*******************************2.2 加载和清洗数据 start *******************************
'''
我们下一个任务是创建词汇表并将查询/响应句子对(对话)加载到内存。
注意我们正在处理词序,这些词序没有映射到离散数值空间。因此,我们必须通过数据集中的单词来创建一个索引。
为此我们创建了一个Voc类,它会存储从单词到索引的映射、索引到单词的反向映射、每个单词的计数和总单词量。
这个类提供向词汇表中添加单词的方法(addWord)、添加所有单词到句子中的方法 (addSentence) 和清洗不常见的单词方法(trim)。更多的数据清洗在后面进行。
'''
# 默认词向量
PAD_token = 0  # Used for padding short sentences
SOS_token = 1  # Start-of-sentence token
EOS_token = 2  # End-of-sentence tokenclass Voc:def __init__(self, name):self.name = nameself.trimmed = False#单词的索引号(键是单词,值是索引)self.word2index = {}#各个单词的数量(键是单词,值是数量)self.word2count = {}#通过索引可以找到单词self.index2word = {PAD_token: "PAD", SOS_token: "SOS", EOS_token: "EOS"}#单词序号,012已经被使用,所以就从3开始了self.num_words = 3  # Count SOS, EOS, PAD#把句子中的每一个单词查出来执行添加单词的操作def addSentence(self, sentence):for word in sentence.split(' '):self.addWord(word)def addWord(self, word):##如果之前没遇到过这个单词if word not in self.word2index:#这个单词的序号self.word2index[word] = self.num_words#这个单词的总数self.word2count[word] = 1#通过单词序号找到单词self.index2word[self.num_words] = wordself.num_words += 1else:#如果之前已经遇到了这个单词那么只对单词总数+1self.word2count[word] += 1# 删除低于特定计数阈值的单词,即单词出现频率太低def trim(self, min_count):if self.trimmed:returnself.trimmed = Truekeep_words = []for k, v in self.word2count.items():if v >= min_count:keep_words.append(k)print('keep_words {} / {} = {:.4f}'.format(#len(self.word2index)即代表总的单词数len(keep_words), len(self.word2index), len(keep_words) / len(self.word2index)))# 重初始化字典self.word2index = {}self.word2count = {}self.index2word = {PAD_token: "PAD", SOS_token: "SOS", EOS_token: "EOS"}self.num_words = 3 # Count default tokensfor word in keep_words:self.addWord(word)'''
现在我们可以组装词汇表和查询/响应语句对。在使用数据之前,我们必须做一些预处理。
首先,我们必须使用unicodeToAscii将 unicode 字符串转换为 ASCII。
然后,我们应该将所有字母转换为小写字母并清洗掉除基本标点之 外的所有非字母字符 (normalizeString)。
最后,为了帮助训练收敛,我们将过滤掉长度大于MAX_LENGTH 的句子 (filterPairs)。
'''
MAX_LENGTH = 10  # Maximum sentence length to consider# 将Unicode字符串转换为纯ASCII,多亏了https://stackoverflow.com/a/518232/2809427
def unicodeToAscii(s):return ''.join(c for c in unicodedata.normalize('NFD', s)if unicodedata.category(c) != 'Mn')# Lowercase, trim, and remove non-letter characters
def normalizeString(s):s = unicodeToAscii(s.lower().strip())#re.sub函数作用:https://blog.csdn.net/weixin_44799217/article/details/115100715s = re.sub(r"([.!?])", r" \1", s)s = re.sub(r"[^a-zA-Z.!?]+", r" ", s)s = re.sub(r"\s+", r" ", s).strip()return s# 初始化Voc对象 和 格式化pairs对话存放到list中
# datafile就是我们上面生成的formatted_movie_lines.txt
#corpus_name就是"cornell movie-dialogs corpus"
def readVocs(datafile, corpus_name):print("Reading lines...")# Read the file and split into lineslines = open(datafile, encoding='utf-8').read().strip().split('\n')# Split every line into pairs and normalizepairs = [[normalizeString(s) for s in l.split('\t')] for l in lines]voc = Voc(corpus_name)return voc, pairs# 如果对 'p' 中的两个句子都低于 MAX_LENGTH 阈值,则返回True,即合法
#p是句子对
def filterPair(p):# Input sequences need to preserve the last word for EOS token#一对句子中只要有一个句子里的单词数超过≥MAX_LENGTH就不合法!所以很多句子都被筛去了return len(p[0].split(' ')) < MAX_LENGTH and len(p[1].split(' ')) < MAX_LENGTH# 过滤满足条件的 pairs 对话
def filterPairs(pairs):# 返回合法句子对的集合return [pair for pair in pairs if filterPair(pair)]# 使用上面定义的函数,返回一个填充的voc对象和对列表
def loadPrepareData(corpus, corpus_name, datafile, save_dir):print("Start preparing training data ...")voc, pairs = readVocs(datafile, corpus_name)print("Read {!s} sentence pairs".format(len(pairs)))pairs = filterPairs(pairs)print("Trimmed to {!s} sentence pairs".format(len(pairs)))print("Counting words...")for pair in pairs:voc.addSentence(pair[0])voc.addSentence(pair[1])print("Counted words:", voc.num_words)return voc, pairs# 加载/组装voc和对
save_dir = os.path.join("data", "save")
voc, pairs = loadPrepareData(corpus, corpus_name, datafile, save_dir)
# 打印一些对进行验证
# print("\npairs:")
# for pair in pairs[:10]:
#     print(pair)'''
另一种有利于让训练更快收敛的策略是去除词汇表中很少使用的单词。减少特征空间也会降低模型学习目标函数的难度。
我们通过以下两个步 骤完成这个操作: 
* 使用voc.trim函数去除 MIN_COUNT 阈值以下单词 。 
* 如果句子中包含词频过小的单词,那么整个句子也被过滤掉。
'''
MIN_COUNT = 3    # 修剪的最小字数阈值def trimRareWords(voc, pairs, MIN_COUNT):# 修剪来自voc的MIN_COUNT下使用的单词,即单词出现频率低于MIN_COUNT的话那么就会筛掉voc.trim(MIN_COUNT)# Filter out pairs with trimmed wordskeep_pairs = []for pair in pairs:input_sentence = pair[0]output_sentence = pair[1]keep_input = Truekeep_output = True# 检查输入句子for word in input_sentence.split(' '):if word not in voc.word2index:keep_input = Falsebreak# 检查输出句子for word in output_sentence.split(' '):if word not in voc.word2index:keep_output = Falsebreak# 只保留输入或输出句子中不包含修剪单词的对if keep_input and keep_output:keep_pairs.append(pair)print("Trimmed from {} pairs to {}, {:.4f} of total".format(len(pairs), len(keep_pairs), len(keep_pairs) / len(pairs)))return keep_pairs# 修剪voc和对
pairs = trimRareWords(voc, pairs, MIN_COUNT)
# for pair in pairs[:10]:
#     print(pair)
#*******************************2.2 加载和清洗数据 end *******************************
#**********************************2.加载和预处理数据**********************************

五.为模型准备数据

尽管我们已经投入了大量精力来准备和清洗我们的数据,将它变成一个很好的词汇对象和一系列的句子对,但我们的模型最终希望数据以 numerical torch张量作为输入。可以在seq2seq translation tutorial 中找到为模型准备处理数据的一种方法。 在该教程中,我们使用batch size大小为1,这意味着我们所要做的就是将句子对中的单词转换为词汇表中的相应索引,并将其提供给模型。

但是,如果你想要加速训练或者想要利用GPU并行计算能力,则需要使用小批量mini-batches来训练。

使用小批量mini-batches也意味着我们必须注意批量处理中句子长度的变化。为了容纳同一batch中不同大小的句子,我们将使我们的批量输 入张量大小(max_length,batch_size),其中短于max_length的句子在EOS_token之后进行零填充(zero padded)。

如果我们简单地将我们的英文句子转换为张量,通过将单词转换为索引indicesFromSentence和零填充zero-pad,我们的张量的大小将是 (batch_size,max_length),并且索引第一维将在所有时间步骤中返回完整序列。但是,我们需要沿着时间对我们批量数据进行索引并且包 括批量数据中所有序列。因此,我们将输入批处理大小转换为(max_length,batch_size),以便跨第一维的索引返回批处理中所有句子的时 间步长。 我们在zeroPadding函数中隐式处理这个转置。

#*******************************3.为模型准备数据 start *******************************
def indexesFromSentence(voc, sentence):#print([3,3,3]+[2])输出[3, 3, 3, 2],即输出句子中每个单词的序号,最后一个序号是结束符号符的数字2return [voc.word2index[word] for word in sentence.split(' ')] + [EOS_token]# zip 对数据进行合并了,相当于行列转置了
def zeroPadding(l, fillvalue=PAD_token):#参数前加一个星号,将传递进来的参数放在同一个元组中,该参数的返回值是一个元组# (在本案例中即把indexesFromSentence返回的列表转化成元组)# itertools.zip_longest作用参考https://blog.csdn.net/yiweiwei516/article/details/118182889return list(itertools.zip_longest(*l, fillvalue=fillvalue))# 记录 PAD_token的位置为0, 其他的为1
def binaryMatrix(l, value=PAD_token):m = []for i, seq in enumerate(l):#即m是一个二维矩阵,一行就对应一个句子,然后用0/1来表示句子中单词是否为填充符m.append([])for token in seq:if token == PAD_token:m[i].append(0)else:m[i].append(1)return m# 返回填充前(加入结束index EOS_token做标记)的长度 和 填充后的输入序列张量
def inputVar(l, voc):#返回值是列表里套列表,每个列表里是每个句子里的各单词对应的索引序号indexes_batch = [indexesFromSentence(voc, sentence) for sentence in l]#indexes就是里层的单个列表,lengths也是个列表,然后转换成了张量,里面每个值对应了每个句子的长度lengths = torch.tensor([len(indexes) for indexes in indexes_batch])# 填充加转置,返回值是列表里面套一个个元组padList = zeroPadding(indexes_batch)#torch.LongTensor是64位整型padVar = torch.LongTensor(padList)return padVar, lengths# 返回填充前(加入结束index EOS_token做标记)最长的一个长度 和 填充后的输出序列张量, 和 填充后的标记 mask
def outputVar(l, voc):indexes_batch = [indexesFromSentence(voc, sentence) for sentence in l]max_target_len = max([len(indexes) for indexes in indexes_batch])padList = zeroPadding(indexes_batch)padVar = torch.LongTensor(padList)mask = binaryMatrix(padList)#torch.ByteTensor构建一个Byte类型的张量mask = torch.ByteTensor(mask)return padVar, mask, max_target_len# 返回给定batch对的所有项目
def batch2TrainData(voc, pair_batch):pair_batch.sort(key=lambda x: len(x[0].split(" ")), reverse=True)input_batch, output_batch = [], []#将语句对分开for pair in pair_batch:print(pair)input_batch.append(pair[0])output_batch.append(pair[1])# 返回填充前(加入结束index EOS_token做标记)的长度 和 填充后的输入序列张量inp, lengths = inputVar(input_batch, voc)# 返回填充前(加入结束index EOS_token做标记)最长的一个长度 和 填充后的输出序列张量, 和 填充后的标记 maskoutput, mask, max_target_len = outputVar(output_batch, voc)return inp, lengths, output, mask, max_target_len# 验证例子
print('***********************************************************************************')
small_batch_size = 5
#random模块中choice()可以从序列中获取一个随机元素,并返回一个(列表,元组或字符串中的)随机项
#batches是随机从所有语句对中国选取的5个语句对
batches = batch2TrainData(voc, [random.choice(pairs) for _ in range(small_batch_size)])
input_variable, lengths, target_variable, mask, max_target_len = batchesprint("input_variable:", input_variable)
print("lengths:", lengths)
print("target_variable:", target_variable)
print("mask:", mask)
print("max_target_len:", max_target_len)
#*******************************3.为模型准备数据 end *******************************

以下代码期间的一些测试,有的时候如果自己不太清楚到底输入了什么输出了什么,就直接打印出来看看,是一个不错的方式:

import itertools#delimiter:分隔符
# import codecs
#
# delimiter = '\t'
# print('delimiter:',delimiter)
# # codecs.decode()方法的使用参考https://zhuanlan.zhihu.com/p/377436438
# delimiter = str(codecs.decode(delimiter, "unicode_escape"))
# print('delimiter:',delimiter)#测试没见过的语法:
'''
lines=['abc','de','f']
def back_for_test():result=[line for line in lines]return result;print(back_for_test())
'''#indexesFromSentence测试
# print([3,3,3]+[2])
#输出[3,3,3,2]#zeroPadding测试PAD_token=0
def zeroPadding(l, fillvalue=PAD_token):#参数前加一个星号,将传递进来的参数放在同一个元组中,该参数的返回值是一个元组# (在本案例中即把indexesFromSentence返回的列表转化成元组)# itertools.zip_longest作用参考https://blog.csdn.net/yiweiwei516/article/details/118182889#print(itertools.zip_longest(*l, fillvalue=fillvalue))return list(itertools.zip_longest(*l, fillvalue=fillvalue))print(zeroPadding((['abc','kevin','kobe'])))#也相当于做了转置
'''
本来传入的矩阵是['abc','kevin','kobe'],可以看作如下
[a b ck e v i nk o b e
]
输出是[('a', 'k', 'k'), ('b', 'e', 'o'), ('c', 'v', 'b'), (0, 'i', 'e'), (0, 'n', 0)],可以看作如下
[a k kb e oc v b0 i e0 n 0
]
相当于做了转置还填充了PAD_token
'''


http://chatgpt.dhexx.cn/article/yl4dNvoB.shtml

相关文章

爆火的ChatGPT 背后的大模型与大数据创新

最近&#xff0c;ChatGPT 迅速引爆 AIGC 领域&#xff0c;依托全网大数据与海量智能模型训练&#xff0c;一举成为 Stable Diffusion 之外的 AI 新宠。不同于过往初阶聊天机器人&#xff0c;这位“懂王”似乎可以取代大型搜索平台&#xff0c;与用户展开高质量同频对话。网友也…

ChatGPT背后有哪些关键技术?CSIG企业行带你一探究竟

目录 1 ChatGPT的时代2 CSIG企业行3 议题&嘉宾介绍3.1 对生成式人工智能的思考3.2 对话式大型语言模型研究3.3 文档图像处理中的底层视觉技术 4 观看入口 1 ChatGPT的时代 2015年&#xff0c;马斯克、美国创业孵化器Y Combinator总裁阿尔特曼、全球在线支付平台PayPal联合…

ChatGPT背后的模型三兄弟

ChatGPT作为最接近强人工智能的系统&#xff0c;具有强大的信息理解和信息抽象总结能力&#xff0c;在这个信息过剩的时代&#xff0c;为我们提供了一个非常好的智能辅助工具。在我们日常的工作中&#xff0c;怎么充分的利用ChatGPT等类似的智能系统&#xff0c;会给我们生活和…

ChatGPT火爆,背后的核心到底是什么?

点击上方“小麦大叔”&#xff0c;选择“置顶/星标公众号” 福利干货&#xff0c;第一时间送达 2022年12月份的时候&#xff0c;ChatGPT还只是个被人各种撩的聊天工具。但进入2023年后&#xff0c;已经向着效率工具迈进了。 微软宣布正和ChatGPT开发团队OpenAI进行洽谈&#xf…

ChatGPT背后的模型

文章目录 1.RLHF方法2.ChatGPT中的RLHF方法2.1 微调模型GPT-32.2 训练奖励模型2.3 利用强化学习进一步微调语言模型 3.效果4.面临挑战5.参考 InstructGPT语言模型&#xff0c;是一个比 GPT-3 更善于遵循用户意图&#xff0c;同时使用通过我们的对齐研究开发的技术使它们更真实、…

ChatGPT既然这么火,有没有弊端呢?

介绍 在现代社会中&#xff0c;人们越来越依赖技术来解决问题。聊天机器人是一种最新的技术趋势&#xff0c;这种技术可以为人们带来很多便利。而ChatGPT聊天机器人则是其中的一种&#xff0c;它使用了大型的语言模型GPT&#xff08;Generative Pre-trained Transformer&#…

突发!ChatGPT疯了!

‍数据智能产业创新服务媒体 ——聚焦数智 改变商业 今天&#xff0c;笔者正常登录ChatGPT&#xff0c;试图调戏一下他。但是&#xff0c;突然震惊的发现&#xff0c;ChatGPT居然疯了。 之所以说他是疯了&#xff0c;而不是崩溃了&#xff0c;是因为他还能回复我&#xff0c;但…

ChatGPT背后的逻辑

版权声明 本文原创作者&#xff1a;谷哥的小弟作者博客地址&#xff1a;http://blog.csdn.net/lfdfhl OpenAI与ChatGPT OpenAI是一个美国的人工智能&#xff08;AI&#xff09;研究实验室&#xff0c;由非营利组织OpenAI Incorporated和其盈利子公司OpenAI Limited Partnersh…

ChatGPT爆火网络背后的故事?

文章目录 前言一、ChatGPT的诞生背景二、ChatGPT的技术原理三、ChatGPT的推广策略四、ChatGPT的未来展望五、橙子送书第2期 前言 ChatGPT是一款基于人工智能技术的聊天机器人&#xff0c;它的出现引起了广泛的关注和热议。在短短的时间内&#xff0c;ChatGPT就成为了全球范围内…

ChatGPT 用户破亿背后...

2022 年 12 月初&#xff0c;ChatGPT 被社会广泛讨论之初&#xff0c;我们就介绍了 ChatGPT 母公司 OpenAI 使用了身份云&#xff08;IDaaS&#xff09;服务。在当时&#xff0c;人们还在感慨 ChatGPT 上线不到一周时间用户量就突破百万&#xff0c;而仅仅在不到两个月后&#…

ChatGPT背后的经济账

ChatGPT能否取代Google、百度这样的传统搜索引擎&#xff1f;为什么中国不能很快做出ChatGPT&#xff1f;当前&#xff0c;对这些问题的探讨大多囿于大型语言模型&#xff08;LLM&#xff09;的技术可行性&#xff0c;忽略或者非常粗糙地估计了实现这些目标背后的经济成本&…

ChatGPT是风口吗?爆火后的质疑猝不及防

作者观&#xff1a; 首先要明确一点&#xff0c;ChatGPT代替不了人类&#xff0c;不要抱不切实际的期望。 作为一款由OpenAI开发的人工智能聊天软件&#xff0c;该程序在一些人的眼里具有革命性的意义。 有人说&#xff0c;这玩意儿可以在一夜之间让无数人失业&#xff0c;也有…

带头抵制高级AI,马斯克在怕什么

Chat-GPT 和 GPT-4 给大家留下的话题实在不少&#xff0c;一边是大家已经开始享受着人工智能带来的便捷&#xff0c;各种写论文出脚本&#xff0c;另一头则是更多的精英人士开始对高级 AI 心存忧虑。 上个月底&#xff0c;据路透社的报道&#xff0c;有一群人工智能专家及行业…

二月安全月报 | 45亿条快递数据疑泄露,Twitter史上最大规模宕机

为了让大家更全面的了解网络安全的风险&#xff0c;顶象针对每月值得关注的安全技术和事件进行盘点总结。 国内安全热点 &#x1f449;业务安全 男子注册上万账号薅羊毛获利13万 近日&#xff0c;上海市&#xff0c;由闵行区人民检察院提起公诉的刘某某诈骗一案开庭审理&…

最先被GPT革掉命的,大概率是你每天都在用的验证码

前段时间&#xff0c;有一个叫 “ Chirper ” 的互联网社区突然火了。 和普通的社区不一样&#xff0c;这个社区拒绝任何真实人类的进入。所有在上面发帖的&#xff0c;都是提前设定好角色属性的 “ 机器人 ”。 它们之中有年龄高达 300 岁的可以使用魔法和动物交流的森林女王…

“用过 Rust 后,我写 Python 的方法都变了!”

近年来&#xff0c;Rust 以其安全性出名&#xff0c;逐渐被各大科技巨头所拥抱——那么&#xff0c;其他主流语言是否可以参考 Rust 的编程思想呢&#xff1f;本文作者以 Python 为例&#xff0c;做了一番尝试。 原文链接&#xff1a;https://kobzol.github.io/rust/python/202…

如何实现在纯 Web 端完成各类 API 调试?

作者 | 张涛&#xff0c;携程机票研发部高级软件工程师 责编 | 夏萌 在软件开发过程中&#xff0c;对于各类 API 的调试工作至关重要。API 调试是验证和测试应用程序接口的有效性和正确性的关键步骤。传统的 API 调试方法通常依赖于独立的工具或桌面应用程序&#xff0c;限制了…

BASIC 之父出生 | 历史上的今天

整理 | 王启隆 透过「历史上的今天」&#xff0c;从过去看未来&#xff0c;从现在亦可以改变未来。 今天是 2023 年 5 月 31 日&#xff0c;在 1962 年的今天&#xff0c;伦纳德克兰罗克&#xff08;Leonard Kleinrock&#xff09;发表了他的第一篇论文&#xff0c;题为“大型通…

22字声明、近400名专家签署、AI教父Hinton与OpenAI CEO领头预警:AI可能灭绝人类!...

整理 | 屠敏 出品 | CSDN&#xff08;ID&#xff1a;CSDNnews&#xff09; 经过不到一年的时间&#xff0c;AI 的发展超乎所有人的想象&#xff0c;也大有失控的风险。 就在今天&#xff0c;全球部分顶尖的 AI 研究员、工程师和 CEO 就他们认为 AI 对人类构成的生存威胁发出了新…

时至 2023 年,2000 万行仍然是 MySQL 表的软限制吗?

一直有传言说&#xff0c;MySQL 表的数据只要超过 2000 万行&#xff0c;其性能就会下降。而本文作者用实验分析证明&#xff1a;至少在 2023 年&#xff0c;这已不再是 MySQL 表的有效软限制。 原文链接&#xff1a;https://yishenggong.com/2023/05/22/is-20m-of-rows-still-…