赞
踩
大语言模型(Large Language Model, LLM)是近年来自然语言处理(NLP)领域最重要的突破之一。它们是在海量文本数据上训练的深度神经网络模型,具有强大的语言理解和生成能力。代表模型有GPT-3、PaLM、BLOOM等。
尽管LLM在多个NLP任务上取得了瞩目的成绩,但它们仍然存在一些局限性:
为了克服这些局限性,研究者提出了Function Calling的思路,即赋予LLM调用外部函数的能力,拓展其应用场景。
Function Calling是指大语言模型在生成文本的过程中,通过某种机制调用预定义的外部函数,获取所需信息或执行特定操作,并将结果融入到生成的文本中的过程。
graph LR
A[大语言模型] -->|理解| B(任务描述)
A -->|生成| C(对话历史)
B -->|明确| D{目标和约束}
C -->|提供上下文| D
D -->|需要额外信息/操作| E[函数接口]
E -->|调用| F(外部函数)
F -->|返回结果| E
E -->|融入| A
为了使LLM具备Function Calling的能力,首先需要在特定领域数据上对预训练模型进行微调。微调过程分为以下步骤:
模型完成微调后,可以应用于实际的对话场景中。函数调用的具体流程如下:
大语言模型的本质是一个条件语言模型,给定上下文 $c$,预测下一个词 $x$ 的概率分布 $P(x|c)$。假设词表大小为 $V$,上下文 $c$ 由 $n$ 个词组成,则模型可以表示为:
其中, $e_i \in \mathbb{R}^d$ 是词表中第 $i$ 个词的嵌入向量, $h_c \in \mathbb{R}^d$ 是上下文 $c$ 的隐藏状态,可以通过神经网络编码器获得:
编码器的具体实现可以采用RNN、Transformer等结构。
函数调用分类器的作用是判断在给定上下文 $c$ 时,是否需要调用外部函数。可以将其建模为一个二分类问题,使用sigmoid函数输出调用函数的概率:
其中, $w \in \mathbb{R}^d$ 和 $b \in \mathbb{R}$ 是分类器的参数。如果 $P(\text{call}|c) > 0.5$,则表示需要调用函数。
函数调用生成器的作用是生成包含函数名、参数等信息的文本片段。可以使用与大语言模型相同的条件语言模型结构,只不过词表换成了函数名、参数、括号等特殊符号。生成的概率分布为:
其中, $y=(y_1,\dots,y_m)$ 是生成的函数调用文本片段,长度为 $m$。生成器的训练目标是最小化负对数似然损失:
下面是一个简单的Python代码示例,展示了如何使用Function Calling增强大语言模型的功能。
import torch import torch.nn as nn import torch.nn.functional as F class FunctionCallingLM(nn.Module): def __init__(self, pretrained_model, num_functions): super().__init__() self.pretrained_model = pretrained_model self.function_classifier = nn.Linear(pretrained_model.config.hidden_size, 1) self.function_generator = nn.Linear(pretrained_model.config.hidden_size, num_functions) def forward(self, input_ids, attention_mask): outputs = self.pretrained_model(input_ids, attention_mask=attention_mask) hidden_states = outputs.last_hidden_state pooled_output = hidden_states[:, 0] # 取第一个token的隐藏状态作为整个输入的表示 # 函数调用分类器 call_logits = self.function_classifier(pooled_output) call_probs = torch.sigmoid(call_logits) # 函数调用生成器 gen_logits = self.function_generator(pooled_output) gen_probs = F.softmax(gen_logits, dim=-1) return call_probs, gen_probs # 加载预训练模型 pretrained_model = transformers.AutoModel.from_pretrained("bert-base-uncased") # 定义函数调用增强的大语言模型 model = FunctionCallingLM(pretrained_model, num_functions=10) # 准备训练数据 train_data = [ { "context": "What is the capital of France?", "question": "The capital of France is", "function_call": "database_lookup(country=France, key=capital)", "answer": "Paris" }, ... ] # 模型微调 optimizer = torch.optim.AdamW(model.parameters(), lr=1e-5) for epoch in range(num_epochs): for batch in train_data: input_ids = ... # 将context和question转换为模型输入 attention_mask = ... call_labels = ... # 根据是否有function_call生成标签 gen_labels = ... # 将function_call转换为模型输出 call_probs, gen_probs = model(input_ids, attention_mask) call_loss = F.binary_cross_entropy(call_probs, call_labels) gen_loss = F.cross_entropy(gen_probs, gen_labels) loss = call_loss + gen_loss loss.backward() optimizer.step() optimizer.zero_grad() # 模型推理 context = "What is the population of New York City?" input_ids = ... attention_mask = ... with torch.no_grad(): call_probs, gen_probs = model(input_ids, attention_mask) if call_probs > 0.5: function_call = ... # 根据gen_probs解码出函数调用文本 result = execute_function_call(function_call) # 调用外部函数 answer = generate_answer(result) # 将函数结果融入到生成的答案中 else: answer = generate_answer() # 直接生成答案 print(answer)
以上代码实现了一个简单的Function Calling增强大语言模型,主要步骤如下:
FunctionCallingLM
类,在预训练模型的基础上添加了函数调用分类器和生成器。实际应用中,还需要根据具体任务设计合适的函数接口和调用方式,并收集高质量的训练数据。
Function Calling增强的大语言模型可以应用于多个实际场景,例如:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。