绝不夸年夜地说,20 世纪 40 年代到 60 年代是人工智能探索的黄金时期。只管随着大量数据和前所未有的打算能力的涌现,形势开始迅速发生变革,但人工智能已经存在了很长一段韶光。1943 年,神全心理学家Warren McCulloch和数学家Walter Pitts在他们的论文《神经活动中内在思想的逻辑演算》中发明了第一种形式的 ANN。
图片来自作者。
我们本日常常利用的“人工智能”一词(智能的观点)是在 1956 年达特茅斯人工智能研讨会上正式提出的。如今,当人们评论辩论人工智能时,他们常常指的是天生式人工智能,它是机器学习和深度学习的一个子集。
在我看来,在探索人工智能项目时,我们该当优先考虑那些供应以下功能的项目:
想象一下,您有一个关于书本的完全数据库(),并且您想根据您的问题检索干系书本并回答有关某些书本的问题,这是一个利用 RAG 创建文档检索运用程序的完美用例。
>>> 您将创造什么?
在根本模型涌现之前,只有拥有足够资源开拓AI模型的机构才能开拓AI运用。而有了根本模型,任何人都可以构建AI运用。
我们将创建一个谈天机器人,它接管用户查询,从我们的数据库中返回干系书本并回答有关书本的任何问题!
>>> 你将学到的技能
什么是RAG系统创建文本数据的矢量嵌入利用向量存储/数据库(例如 FAISS、Qdrant、Chroma)存储和查询嵌入结合向量存储和 LLM 进行信息检索>>> 基本理论和观点什么是检索增强天生(RAG)系统?
基于 RAG 的架构为 LLM(即 Claude3.5)供应了对外部知识源的访问,这些知识源为用户查询供应了额外的高下文。这常日涉及按与查询的相似性进行搜索,检索最干系的文档,并将它们插入提示中作为信息检索的高下文。
RAG 用于办理开放式场景中的幻觉,例如用户与谈天机器人交谈,当被问及演习数据中没有的内容时,谈天机器人很随意马虎编造一些事情。
这是一个基于 RAG 的大略谈天机器人示例,用于查询您的私人知识库。来源
RAG 的事情流程如下:
将文档分成多个块将每个块转换为向量嵌入,并在向量数据库中对块进行索引查询:给定用户输入,对用户输入进行矢量化,通过矢量在矢量数据库中搜索最靠近的记录并检索干系高下文天生:结合查询和干系高下文,获取 LLM 相应嵌入和向量存储/数据库
只管嵌入模型早在天生式 AI 涌现之前就已经存在。天生式 AI 模型再次催生了文本的矢量表示或词嵌入,这是一种奇特的说法,即文本或图像可以呈现为数字列表。例如,您可以将其视为某个位置的坐标。
例如,你可以打算巴黎—法国+荷兰,结果是靠近巴黎的向量嵌入的向量嵌入,这彷佛表明都城的观点也被编码在嵌入中。
另一个著名的例子是:如果你打算 King — Man + Woman(对这些词的嵌入向量进行加减),那么结果将非常靠近 Queen 这个词的嵌入。彷佛嵌入编码了性别的观点!
图片来自作者。
当你向 ChatGPT 提问时,你的问题将在后台转换为 ChatGPT 可以理解的嵌入/向量。该嵌入被编入索引并存储在向量数据库中。向量数据库以文本记录的向量表示作为键来存储文本记录。该技能通过引用提示中未演习的干系高下文来帮助减少幻觉,以便它可以利用此高下文来打算相应。
>>>履行步骤:
技能栈:
框架:Langchain。它为您供应了许多与 LLM 合营利用的组件根本模型:GPT4o矢量存储:Qdrant(可以利用 Chroma 或 FAISS)前端:Holoviz Panel(也可以选择 Streamlit)嵌入模型:OpenAI text-embedding-large-03Langchain 组件。来源
步骤1:设置环境
首先,确保您已经安装了必要的库:
uv pip install --upgrade langchain openai qdrant-client pandas nltk tomotopy pyvis
第 2 步:Scrape book
为简洁起见,省略了函数实现细节,可在此 repo 中找到。
def scrape_book(): 34;""""" # (Function implementation details omitted for brevity) # This function would include scraping books from google book using google API # and reviews from amazon using Selinium,, return df_books
步骤2:设置矢量数据库
首先,我们须要创建嵌入工具并设置一个向量数据库来存储嵌入。我将利用 OpenAI text-embedding-3-large 来天生嵌入。
embeddings = OpenAIEmbeddings(model="text-embedding-3-large")def create_db(documents): return Qdrant.from_documents( documents=documents, embedding=embeddings, collection_name="my_documents", location=":memory:", force_recreate=False, )db = create_db(documents)
在设置向量数据库时,我们通过location=”:memory:”指定应在内存中创建数据库,并且我们操持在同一会话中与其进行交互。
步骤3:利用干系高下文进行信息检索
接下来,我们接管用户查询,搜索数据库并返回干系文档列表。这里,您可以调度一些参数,例如搜索空间(要返回的文档数 k)、相似类型(…)
retriever = db.as_retriever( search_type="mmr", search_kwargs={"k": 2, "lambda_mult": 0.25} )# Create a chain to answer questionsqa = RetrievalQA.from_chain_type( llm=llm, chain_type="stuff", retriever=retriever, return_source_documents=True)query = "Can you tell me about the key theme for the book Life 3.0 in 20 words?"result = qa({"query": query})print(result)
天生式 AI 模型催生了基于代理的架构。
>>> 您将创造什么?在这个第二个项目中,我们将创建项目 1 中的 RAG 谈天机器人的增强版本,它可以自主决策并采纳行动,无需人工干预。令人愉快!
什么是代理?
代理是一个自主实体,在得到高等指令后,它可以操持、利用动作/工具并实行多个迭代步骤来实现期望的目标。
代理可以采纳各种行动,例如实行 Python 函数;然后,代理将不雅观察实行某项行动的结果,并决定下一步要采纳什么行动。这个过程会不断重复,直到代理对紧张任务有了终极答案。
您还可以看到用以下伪代码写出的这个过程:
next_action = agent.get_action(...)while next_action != AgentFinish: observation = run(next_action) next_action = agent.get_action(..., next_action, observation)return next_action
代理具有以下组件,例如输入、期望目标和可用操作。
例如,考虑一辆自动驾驶汽车,它吸收传感器数据(摄像头或超声波)等输入。目标是确保安全、高效的导航。褒奖函数可以是无人干预行驶的英里数(特斯拉)。可用的操作可以是加速、减速、转弯、变道、停滞等……
有许多代理框架旨在提高 LLM 的相应能力。最初的框架是ReAct,许可 LLM 通过工具采纳行动后创建不雅观察结果。然后,这些不雅观察结果会转化为关于下一步利用什么工具最得当的想法,直到得出终极答案。
OpenAI发布了针对函数调用而定制的更多风雅化的 LLM。它为工具利用供应了一种与标准 ReAct 模式不同的替代方案。
>>> 履行步骤LangChain 许可用户在不同代理类型之间切换,包括 ReAct、OpenAI 函数等等。对付这个项目,我们将利用 OpenAI 函数调用和 Langchain LCEL 来构建代理。
步骤1:定义工具
工具只是一个预定义的功能,许可代理采纳特定的操作。
由于 GPT-4 等 LLM 常日仅天生文本(单一模态),我们可以供应可实行其他操作的工具,例如与数据库交互或仅实行 Python 代码。
首先,我们将定义代理将利用的四个紧张工具。为简洁起见,这里省略了一些函数实现细节,所有细节都可以在此 repo 中找到。
scrape_books:从谷歌和亚马逊抓取书本和书评find_relevant_books:根据用户查询检索干系书本。create_topic_network:创建书中主题的可视化。qa:根据检索到的文档回答用户的问题这些工具被定义为函数,并用@toolLangChain 的装饰器进行装饰,例如:
@tooldef find_relevant_books(user_query): """ Return all relevant books based on user query. Important: This function should be called only for queries that require finding specific books. For general queries that do not require finding specific books, use other available functions. """ retriever = db.as_retriever( search_type="mmr", search_kwargs={"k": 4, "lambda_mult": 0.25} ) relevant_docs = retriever.get_relevant_documents(user_query) session_state["relevant_docs"] = relevant_docs session_state["retriever"] = retriever return relevant_docsllm = ChatOpenAI( model="gpt-4o", temperature=0, openai_api_key=os.getenv("OPEN_AI_KEY"))@tooldef qa(user_query): """ Answer user questions based on the retrieved documents """ retriever = session_state["retriever"] relevant_docs = session_state.get("relevant_docs") if relevant_docs is None: # If no documents are stored, retrieve them relevant_docs = retriever.get_relevant_documents(user_query) session_state["relevant_docs"] = relevant_docs # Create a chain to answer questions using stored documents qa = ConversationalRetrievalChain.from_llm(llm, retriever) chat_history = [] result = qa( {"question": user_query, "chat_history": chat_history, "context": relevant_docs} ) return result
当利用润色这些操作时@tool,主代理将可以访问函数列表、它们的参数和文档字符串。这使代理能够智能地选择与任务最干系的工具。
为了方便起见,我们将干系文档和检索器存储在全局定义的字典中session_state。这使得代理更随意马虎访问这些信息。
步骤 2. 创建Prompt
首先,您将利用系统、用户和MessagesPlaceholder来设置提示,这许可代理存储个中央步骤:
from langchain.prompts import ChatPromptTemplate, MessagesPlaceholder# Define the prompt templateprompt_template = """You are a helpful AI assistant specializing in answering questions related to books from users. Use retrieved relevant books to answer questions.===================={relevant_docs}"""prompt = ChatPromptTemplate.from_messages( [ ( "system", """You are helpful AI assistant. Use the following template for your actions and observations.""" ), ("user", prompt_template), MessagesPlaceholder(variable_name="chat_history"), ("user", "{input}"), MessagesPlaceholder(variable_name="agent_scratchpad"), ])
暂存器是代理存储所有中间结果的地方。例如,如果用户哀求创建第一本《哈利波特》书本的所有主题的可视化,代理将首先找到干系书本(邪术石),将输出存储在暂存器中,然后推理它该当调用create_topic_network下一个。
步骤3.初始化代理
为了让代理理解所有可用的工具,您须要首先将工具直接绑定到 LLM 进行函数调用:
from langchain.agents.format_scratchpad import format_to_openai_functionsfrom langchain.tools import Tool# These are custom functions for finding books, answering questions, and creating topic networks.tools = [find_relevant_books, qa, create_topic_network]# OpenAI Function Formatting. This converts the tools into a format compatible with OpenAI's function calling feature.functions = [format_tool_to_openai_function(f) for f in tools]#This sets up the GPT-4o model with the defined functions.model = ChatOpenAI( openai_api_key=openai.api_key, temperature=0, model_name="gpt-4o",).bind(functions=functions)
现在我们已经定义了工具和提示,接下来我们创建代理:
from langchain.agents import AgentExecutorfrom langchain.agents.output_parsers import OpenAIFunctionsAgentOutputParserfrom langchain.schema.runnable import RunnablePassthroughfrom langchain.memory import ConversationBufferMemory# Set up the agent chain.# including assigning relevant documents and agent scratchpad, applying the prompt, running the model, and parsing the output.agent_chain = ( RunnablePassthrough.assign( agent_scratchpad=lambda x: format_to_openai_functions(x["intermediate_steps"]), relevant_docs=lambda x: "\n".join( str(doc) for doc in session_state.get("relevant_docs", []) ), ) | prompt | model | OpenAIFunctionsAgentOutputParser())# Set up a memory component to store conversation history.memory = ConversationBufferMemory( return_messages=True, memory_key="chat_history", input_key="input", output_key="output",)# Initialize an agent with the agent and defined tools# This combines all components into an executable agent that can process queries and maintain conversation context.# With AgentExecutor, the agent is equipped with the tools and verbose output is enabled, allowing for detailed logging.agent = AgentExecutor(agent=agent_chain, tools=tools, verbose=True, memory=memory)
便是这样!
一个功能完好的代理,可以利用一些工具,随时可以开始事情。
步骤 4. 利用面板创建用户界面
现在我们已经设置了代理,让我们利用 Panel 创建一个用户友好的界面来与该代理进行交互:
import panel as pnimport paramimport hashlibfrom agent import from panel.chat import ChatMessagepn.extension()pn.config.theme = "dark"custom_css = """body { background-color: #212121; color: #FFFFFF;}.bk-root .bk-sidebar { background-color: #171717 !important; color: #FFFFFF;}.bk-root .bk-main { background-color: #212121;}"""pn.extension(raw_css=[custom_css])# define a BookInterface class that encapsulates our chat interface.class BookInterface(param.Parameterized): cache = {} def __init__(self, params): super().__init__(params) self.chat_interface = pn.chat.ChatInterface( callback=self.chat_callback, callback_user="Book AI", show_rerun=False, show_undo=False, sizing_mode="stretch_width", min_height=600, ) self.chat_interface.send( "Hello! How can I assist you with books today?", user="System", respond=False, ) self.relevant_books_pane = pn.pane.Markdown("", sizing_mode="stretch_width") self.logging_pane = pn.pane.Markdown("", sizing_mode="stretch_width") def log_message(self, message): """Log a message to the logging pane.""" self.logging_pane.object += f"{message}\n" def detect_function_calls(self, response): function_calls = [] # Add all potential function names here functions = ["find_relevant_books", "qa", "create_topic_network"] for function in functions: if function in response: function_calls.append(function) return function_calls def compute_hash(value): return hashlib.sha256(value.encode()).hexdigest() # The chat_callback method is the core, it handles queries and returns the response to be displayed in the chat. def chat_callback(self, contents: str, user: str, instance: pn.chat.ChatInterface): try: self.log_message("Invoking qa function...") cache_key = compute_hash(contents) if cache_key in self.cache: response = self.cache[cache_key] else: # Show that we're invoking the agent instance.objects.append(ChatMessage(object="Thinking...", user="System", avatar="assets/book_logo.png")) # Capture the standard output to get the verbose output import io import sys old_stdout = sys.stdout sys.stdout = buffer = io.StringIO() result = agent.invoke({ "input": contents, "chat_history": memory.chat_memory.messages if memory.chat_memory else [] }) # Restore the standard output sys.stdout = old_stdout verbose_output = buffer.getvalue() # Parse the verbose output to find function calls for line in verbose_output.split('\n'): if line.startswith("Invoking:"): instance.objects.append(ChatMessage(object=line, user="System", avatar="assets/book_logo.png")) response = result.get('output', "No output found in the response.") self.cache[cache_key] = response except Exception as e: response = f"An error occurred: {str(e)}" instance.objects.append(ChatMessage(object=response, user="Book AI", avatar="assets/book_logo.png")) return ChatMessage(object=response, user="Book AI", avatar="assets/book_logo.png") def view(self): return pn.Column( pn.Spacer( styles=dict(background="rgb(240, 240, 240)"), sizing_mode="stretch_both" ), pn.pane.Markdown("# Ask me anything about books! ", align="center"), self.chat_interface, self.relevant_books_pane, # Add the relevant books pane to the layout self.logging_pane, # Add the logging pane to the layout sizing_mode="stretch_both", )#create an instance of BookInterface and set up a MaterialTemplateinterface = BookInterface()template = pn.template.MaterialTemplate( title="Book AI Assistant", logo="assets/book_logo.png", # Add a logo header_background="#4A90E2", # Custom header color sidebar=[ pn.pane.Markdown("## About", css_classes=["bk-sidebar"]), pn.pane.Markdown( "This AI assistant can help you find books, answer questions, and analyze book topics.", css_classes=["bk-sidebar"] ), pn.pane.PNG("assets/book_logo.png", width=200, css_classes=["bk-sidebar"]), ], main=[interface.view()],)template.servable()if __name__ == "__main__": pn.serve({"/": template}, static_dirs={"/assets": "./assets"})
上述代码将返回以下接口:
项目 3:演习自己的LLM(一名歌曲作家)
如果你关心人工智能的理论根本,你也希望自己能够深入理解其根本模型是如何演习的。从头开始学习LLM将极大地帮助你理解这一点。
如果你刚打仗基于 Transformer 的措辞模型,并且想要入门,那么你很幸运,由于利用 nanoGPT 非常大略。Andrej Kapathy 在此存储库中供应了基于莎士比亚文本构建 babyGPT 模型的代码。我
>>> 您将创造什么?你喜好音乐吗?为什么不建立一个可以按照你想要的风格创作歌曲的 LLM 呢?
由于我喜好 Ed Sheeran,以是在这个项目中,我们将创建一个基于单词的小型转换器模型,以 Ed Sheeran 的风格创作歌曲!
与本文其他部分比较,本节数学内容较多。如果您以为困惑,可以跳过数学部分。
神经网络根本
人工神经网络的构造有输入旗子暗记和输出旗子暗记,当输入被激活时它就会大略地激活输出。
神经网络中的每个输入都与一个权重干系联。首先,神经网络对所有输入值进行加权求和。
前向传播在隐蔽层中,激活函数考虑到每个输入的输入和权重,运用于每个神经元并产生一个输出,该输出用作下一层的输入。
激活函数是一种帮助神经网络学习数据模式并将前一层的输出通报到下一隐蔽层的输入的函数。这个过程持续到我们得到神经网络末了一层的输出,也便是预测值。
反向传播过程
现在,我们有了输出,网络将开始反向传播过程。这统统都与所谓的丢失函数有关。实质上,丢失函数是一种比较网络的预测输出和实际输出并返回偏差信息(y 和 ŷ 之间的差异)的函数。
对付每个演习实例,反向传播都会丈量网络中的每个权重对整体偏差的影响。这许可模型利用优化算法更新权重,该算法会调度网络中的所有权重,直到丢失函数最小化。
在优化算法中,基于梯度低落的算法是最广泛利用的算法。要理解如何利用梯度低落调度权重,可以在此处找到详细阐明。您还可以在这篇文章中得到一些有关梯度低落替代方案的见地。
过去,循环神经网络 (RNN)和卷积神经网络 (CNN)是用于图像 (CNN) 和文本 (RNN) 深度学习的盛行神经网络架构。然而,2017 年,具有里程碑意义的论文《Attention is all you need》先容了 transformer 架构,它永久改变了人工智能的天下,由于它是当今 LLM 背后的架构,包括 ChatGPT。
来源:https://lena-voita.github.io/nlp_course/seq2seq_and_attention.html
标记化
标记是措辞模型的构建块。标记化是一种将一段文本分成更小的块(称为标记)的方法。因此,您可以将标记视为单词的片段。将原始文本分解为标记的过程称为标记化。对付 OpenAI GPT 模型,均匀标记大约是单词长度的 ¾,因此 1,000 个标记大约是 750 个单词。根据您利用的标记器,标记可以是单词、字符或子单词。
来源
该库是用于对文本进行标记的常用库,尤其是在利用 OpenAI 的 GPT-3 或 GPT-4 等模型时。下面是如何将单词转换为标记tiktoken的示例:tiktoken
图片来自作者
>>> 履行步骤好了,说得够多了,让我们开始动手吧。我们正在演习一个基于单词的小型 Transformer 模型,用于预测接下来会涌现哪个词。
步骤1.准备演习数据
加载数据集
在本文中,我们将利用包含Ed Sheeran 所有歌曲歌词的Ed-sheeran 数据集。您可以利用数据集库加载此数据集:
from datasets import load_datasetdataset = load_dataset("huggingartists/ed-sheeran")
太棒了!
我们现在准备进行一些数据处理,以获取数据集中每首歌曲的歌词。以下代码块将把数据处理成 csv 文件:
import pandas as pddf = pd.DataFrame(data=dataset)df['text'] = df.train.apply(lambda row: row.get("text"))df = df[df.text != ""]def get_title_lyrics(text): lyrics_start = "Lyrics" lyrics_index = text.index(lyrics_start) title = text[:lyrics_index].strip() lyrics = text[lyrics_index + len(lyrics_start):].strip() return {'Title': title, 'Lyrics': lyrics}df[['Title', 'Lyrics']] = df['text'].apply(get_title_lyrics).apply(pd.Series)df.to_csv("data/ed-sheeran/ed_sheeran.csv")
对文本进行编码并创建演习/测试/验证集
由于措辞模型利用 token,我们将原始歌词转换为整数序列或 token-id。由于我们要演习一个单词级转换器模型,以是我们将利用 GPT2 tokenizer 对每个 token 进行编码,这些 token 由唯一的 token id(整数)表示。
我们选择 90% 的文本作为演习数据,10% 用于验证。
编码后的文本被分成演习集 ( train_ids) 和验证集 ( val_ids)。这些演习集和验证集包含与原始文本中的标记相对应的整数序列:
import osimport tiktokenimport numpy as npimport pandas as pddf = pd.read_csv("data/ed-sheeran/ed_sheeran.csv")data = df["Lyrics"].str.cat(sep="\n")n = len(data)train_data = data[: int(n 0.9)]val_data = data[int(n 0.9) :]# encode with tiktoken gpt2 bpeenc = tiktoken.get_encoding("gpt2")train_ids = enc.encode_ordinary(train_data)val_ids = enc.encode_ordinary(val_data)# export to bin filestrain_ids = np.array(train_ids, dtype=np.uint16)val_ids = np.array(val_ids, dtype=np.uint16)train_ids.tofile(os.path.join(os.path.dirname(__file__), "train.bin"))val_ids.tofile(os.path.join(os.path.dirname(__file__), "val.bin"))# train has 433,585 tokens# val has 48,662 tokens
现在,我将上述代码保存在名为的文件中prepare-edsheeran.py,并运行以下命令:
python data/prepare-edsheeran.py
这样做的目的是将train_ids和val_ids序列保存为二进制文件 -train.bin并将val.binGPT2 令牌 ID 保存在一个序列中。便是这样!
数据已准备就绪。我们可以开始演习了。
步骤2.定义模型
为简洁起见,省略了代码实现细节,可在此 repo 中找到。以下过程概括了创建模型和演习的基本步骤:
利用 GPT 类定义创建 model.py:
初始化变压器组件(嵌入、块等)定义前向通报:通过嵌入和转换器块处理输入配置优化器:权重衰减的单独参数对付每个期间和批次,实行前向通报,打算丢失并反向传播并更新参数然后,我们将创建 train.py 来初始化模型,运行演习循环并天生文本。
步骤 3. 演习 babyGPT 模型
在本节中,我们将实际演习一个小型 GPT 模型。让我们创建一个名为 的新文件,config/train_edsheeran.py 其设置如下:
out_dir = "out-lyrics"eval_interval = 250 # keep frequent because we'll overfiteval_iters = 20log_interval = 10 # don't print too often# we expect to overfit on this small dataset, so only save when val improvesalways_save_checkpoint = Falsedataset = "ed-sheeran"batch_size = 12 # 12 samples per iterationblock_size = 64 # context size# a baby GPT model :)n_layer = 6n_head = 6n_embd = 384 # each embedding vector for each token will have 384 dimensionsdropout = 0.2learning_rate = 1e-3 # with baby networks can afford to go a bit highermax_iters = 2000lr_decay_iters = 2000 # make equal to max_iters usuallymin_lr = 1e-4 # learning_rate / 10 usuallybeta2 = 0.99 # make a bit bigger because number of tokens per iter is smallwarmup_iters = 100 # not super necessary potentially
要演习模型,请在终端中运行以下代码:
python train.py config/train_edsheeran.py
演习开始了…!
等待
瞧!
演习完成了。我们将创建一个图,以迭代次数为函数显示验证集上的丢失。不雅观察下图,我们把稳到 500 次迭代后验证丢失有所增加,这表明存在过度拟合。
为理解决这个问题,我们将选择限定在这 500 次迭代中,并连续重新演习模型。重新演习完成后,演习后的模型ckpt.pt将直接保存到输出中out-lyrics
步骤 4. 天生 Ed Sheeran 风格的歌曲
现在到了最有趣的部分!
让我们看看我们的模型能学得多好,能创作出像 Ed Sheeran 的歌曲!
我们可以通过将采样脚本指向此目录来从最佳模型中进行采样:
python sample.py --out_dir= out -lyrics
运行上述代码会天生一些示例。结果如下:
项目 4:微调 Bert 模型以理解法律文本
如果你可以利用最前辈的模型,而不必为自己的特界说务从头开始演习,那会很棒吗?微调是一种非常强大的演习技能!
我们将利用法律文本为语义角色标记任务创建一个基于 Bert 的专门领域模型!
Transformers 为广泛的任务供应了数千个预演习模型。
什么是微调?
微调模型意味着利用特定于您的任务的数据集连续演习之前演习过的模型。因此,模型权重是从之前的演习过程中得到的。例如,如果您将童年日记输入 ChatGPT 并连续演习它,这便是微调。
>>> 履行步骤(代码改编自Hugging face )
步骤 1. 加载数据集工具并分为演习/测试/验证:
显然,这须要有标记的数据集。
加载数据集进行微调
data = "data/all_annotations_cleaned.csv" df_to_train = pd.read_csv(data, sep = ";", converters={'tokens': eval, 'srl_tags': eval})dataset = Dataset.from_pandas(df_to_train)# SPLITTING main dataset into train, validation, test as DatasetDicttrain_testvalid = dataset.train_test_split(test_size=0.1)# Split the 10% test + valid in half test, half validtest_valid = train_testvalid['test'].train_test_split(test_size=0.5)# Collect the two into a single DatasetDictdatasets = DatasetDict({ 'train': train_testvalid['train'], 'test': test_valid['test'], 'validation': test_valid['train']})
步骤2.标记化
为了一步完成数据集的标记化,我们将利用 robbert-v2-dutch-base Tokenizer(由于我利用荷兰法律文本来微调基于荷兰 Bert 的模型)。该datasets.map方法将对全体数据集运用标记化:
tokenizer = AutoTokenizer.from_pretrained( "pdelobelle/robbert-v2-dutch-base" , add_prefix_space= True ) def tokenize_and_align_labels ( examples, label_all_tokens = True ): tokenized_inputs = tokenizer(examples[ "tokens" ], truncation= True , is_split_into_words= True ) tokenized_datasets = datasets.map (tokenize_and_align_labels, batched= True ) tokenized_datasets.save_to_disk( "/content/drive/MyDrive/finetuningbert/dataset_robert_new" )
在对数据集进行标记后,我们现在还可以得到“input_ids”和“attention_mask”:
步骤 3. 利用 Trainer进行微调
加载演习器Load Trainer
Transformers 供应了一个针对演习 Transformers 模型优化的Trainer类。我们将首先加载所选模型。我将利用 Dutch Bert 模型:
model = AutoModelForTokenClassification.from_pretrained("GroNLP/bert-base-dutch-cased", num_labels=len(label_list))
创建演习超参数
接下来,创建一个TrainingArguments类,个中包含可以调度的超参数:
batch_size = 1 args = TrainingArguments( output_dir= "." , evaluation_strategy = "epoch" , learning_rate=5e-5, num_train_epochs=5, weight_decay=0.01, seed=1 )
定义评估指标
Transformers 的数据集包供应了准确度指标的方法:
from datasets import load_metricmetric = load_metric("seqeval")def compute_metrics(p): predictions, labels = p predictions = np.argmax(predictions, axis=2) true_predictions = [ [label_list[p] for (p, l) in zip(prediction, label) if l != -100] for prediction, label in zip(predictions, labels) ] true_labels = [ [label_list[l] for (p, l) in zip(prediction, label) if l != -100] for prediction, label in zip(predictions, labels) ] results = metric.compute(predictions=true_predictions, references=true_labels) return { "precision": results["overall_precision"], "recall": results["overall_recall"], "f1": results["overall_f1"], "accuracy": results["overall_accuracy"], }
微调模型
利用所选模型、演习参数、演习和测试数据集以及评估指标创建一个Trainer工具:
trainer = Trainer( model=model, args=args, train_dataset=reloaded_encoded_dataset["train"], eval_dataset=reloaded_encoded_dataset["validation"], data_collator=data_collator, tokenizer=tokenizer, compute_metrics=compute_metrics)
然后我们可以通过调用train()方法大略地微调模型:
trainer.trains()trainer.save_model("robbert-srl")
就这样!
模型演习已完成,可用于语义角色标记任务。让我们检讨一下性能是否优于预演习的 Robbert 模型:
嗯,看起来改进并不是那么显著但至少,我们学会了如何微调 Bert 模型!
评估措辞模型的输出至关主要,而且富有寻衅性。
在 GenAI 时期之前,您只需将数据分成演习/测试/验证集 - 在演习集上演习模型,并在验证和测试集上评估性能。在监督学习中,我们利用 R 平方、精确度、召回率或 F 平方来评估性能。如何评估 LLM?在天生新文本时,基本事实是什么?
>>> 您将创造什么?在这个项目中,我们将运用不同的技能来评估 LLM 的开放式反应,包括人类和人工智能输出的相似性、模型输出的同等性、人工智能作为法官。
>>> 你将学到的技能理解 NLP 模型的评估指标(例如 ROUGE)与参考数据的相似度丈量检讨模型输出的同等性以LLM身份担当法官>>> 基本理论和观点与参考数据的相似度丈量
一种常见的方法是根据参考数据评估人工智能的输出。天生的相应越靠近参考相应越好。有四种方法可以衡量两个开放式文本之间的相似性:
哀求评估者判断两段文本是否相同。
用于比较两个答案的评估者可以是人类,也可以是人工智能。但是,如果您已经在利用人类进行这种比较,那么您可能不须要参考数据——人类可以直接评估天生的答案。
词汇相似性
词汇相似度衡量两段文本是否看起来相似,而不是它们是否具有相同的含义。换句话说,它衡量两段文本的重叠程度。此类指标的一个例子是 ROUGE 分数:
语义相似性
语义相似度衡量天生的相应在含义(语义)上与参考相应的靠近程度。这须要将文本转换为数字表示或嵌入,我们在项目 1 和 2 中提到过。
图片来自作者
检讨模型输出的同等性
LLM 的一个大问题是可重复性。谈天完成默认情形下是不愿定的,纵然在温度 = 0 时也是如此,这意味着模型输出可能因要求而异。
为了评估模型相应的同等性,我们可以用不同的种子对相同的问题和相同的提示进行多次运行,以查看答案在不同运行中的分布情形。
利用相同的提示和数据,在 20 次运行中输出。大多数情形下,模型会为所有文档返回相同的分数 — 这便是分布只是点分布的缘故原由。仅对付文档 7,我们不雅观察到模型相应在多次运行中的小变革,大多数情形下模型返回的分数为 0.2,但有时返回 0.4。图片来自作者。
用LLM当法官
既然人工智能已成功用于自动化许多具有寻衅性的任务,那么人工智能是否也能自动化评估呢?利用人工智能评估人工智能的方法称为人工智能作为法官或 LLM 作为法官。用于评估其他人工智能模型的人工智能模型称为人工智能法官。
在这个例子中,大多数情形下,初始分数和评审分数很靠近。但有一年,即 2017 年,模型最初给出了正分,但后来在评审流程中返回了负分。好吧,这彷佛有点可疑。您可以进行检讨以理解此案例的模型行为。图片来自作者。
>>>履行步骤:
所有代码都可以在我之前的一篇文章中找到。
>>> 资源
OpenAI Cookbook — 评估示例人工智能工程(chip Huyen)结论我希望这些项目能带您进入天生式人工智能的天下,从构建谈天机器人到演习您自己的措辞模型,以及如何评估您的人工智能运用程序,这对付该技能的采取至关主要。
我们仍处于 GenAI 的早期阶段,存在很多不愿定性,我们根本不知道事情会如何发展。但我不会押注人工智能会失落败。就像所有成熟的职业一样,每个职业在开始时都曾不成熟。人工智能也是如此。
参考:
https://levelup.gitconnected.com/learn-genai-through-the-following-project-ideas-build-real-world-project-ideas-for-generative-ai-138f32f82572