HuggingGPT 是浙江大学、微软亚洲研究院合作开发的开源项目,以 ChatGPT 和 Hugging Face 为基础构建的一个 AI Agent 框架,融合了 LLM 和 AI 领域模型的能力,用来解决不同领域和不同模态的 AI 任务。
HuggingGPT 是一个以 LLM(比如 ChatGPT)为控制器,以专家模型(HuggingFace)为执行任务的 AI Agent 系统,主要通过连接到各个领域内的专家模型以尝试自动地解决各种复杂的 AI 任务。HuggingGPT 以自然语言为接口,通过 ChatGPT 进行任务规划、模型选择,并通过使用专家模型处理对应领域的问题,生成最终结果,从而能够很好地解决 AI 任务。
HuggingGPT 对应的相关代码和工具,都托管在 Github 上,对应的项目名是 JARVIS:https://github.com/microsoft/JARVIS。
HuggingGPT 设计概览
HuggingGPT 的总体处理流程,如下图所示:
通过上图可以看到,HuggingGPT 的处理过程可以分为如下 4 个阶段:
- 任务规划(Task Planning)
使用一个 LLM(ChatGPT)分析用户的请求,了解用户的意图。通过用户输入到 LLM(ChatGPT)的 Prompt,根据对话结果将用户任务分解为可执行的多个任务。
- 模型选择(Model Selection)
为了解决计划任务,LLM(ChatGPT)通过一定的策略,选择托管在 Hugging Face 网站上的某个领域的专家模型,来执行某个特定的任务。
- 任务执行(Task Execution)
调用并执行选择的某个专家模型,执行任务并将结果返回给 LLM(ChatGPT)。
- 响应生成(Response Generation)
最后,利用 LLM(ChatGPT)集成来自所有专家模型的推理结果,并统一为用户生成响应内容。
HuggingGPT 的上述 4 个阶段,更详细的处理过程,可以参考下图:
任务规划
LLM(ChatGPT) 接受用户的请求,将其分解为一系列结构化的任务。复杂的请求通常涉及多个任务,LLM 需要确定这些任务的依赖关系和执行顺序。为了使 LLM 进行有效的任务规划,HuggingGPT 在 Prompt 提示设计中采用了基于规范化指令(Specification-based Instruction)和基于演示的解析(Demonstration-based Parsing)。
基于规范的指令任务规范为任务提供了统一的模板,允许大型语言模型通过槽位归档进行任务解析。HuggingGPT 为任务解析设计了 4 个字段,分别是任务类型、任务编号、任务依赖、任务参数,各个字段分别说明如下:
- 任务类型:使用 “task” 字段表示,任务类型涵盖语言、视觉、视频、音频等不同任务。
- 任务编号:使用 “id” 字段表示,任务编号为任务规划提供了一个唯一的标识符,用于引用相关任务及其生成的资源。
- 任务依赖:使用 “dep” 字段表示,任务依赖定义了执行所需的先决条件任务。只有在完成所有先决条件相关任务后,才会启动该任务。
- 任务参数:使用 “args” 字段表示,任务参数包含执行任务所需的参数列表。它包含 3 个子字段,根据任务类型填充文本、图像和音频资源,它们是从用户的请求或相关任务的生成资源中解析的。
任务规划阶段,生成的规范化指令模板,示例如下图所示:
生成的任务列表描述格式为:
[{ "task": task, "id", task_id, "dep": dependency_task_ids, "args": { "text": text, "image": URL, "audio": URL, "video": URL } }]
可以在上图中看到,演示部分(Demonstrations)给出了 3 个具体的任务的实例描述,使用 JSON 格式,如下所示:
- 图片 e1.jpg 中有几个实体
[{ "task": "object-detection", "id": 0, "dep": [-1], "args": { "im age": "e1.jpg" } }]
- 图片 e2.jpg 中是什么动物,以及它们在做什么
[{ "task": "image-to-text", "id": 0, "dep": [-1], "args": { "im age": "e2.jpg" } }, { "task": "image-cls", "id": 1, "dep": [-1], "args": { "image": "e2.jpg" } }, { "task": "object-detection", "id": 2, "dep": [-1], "args": { "image": "e2.jpg" } }, { "task": "vi- sual-quesrion-answering", "id": 3, "dep": [-1], "args": { "text": "what’s the animal doing?", "image": "e2.jpg" } }]
- 先生成图片 e3.jpg,基于该图片生成文本 “a girl reading a book”,并以一个新图片的形式做应答
[{ "task": "pose-detection", "id": 0, "dep": [-1], "args": { "im age": "e3.jpg" } }, { "task": "pose-text-to-image", "id": 1, "dep": [0], "args": { "text": "a girl reading a book", "image": "<re- source>-0" } }]
模型选择
在 HuggingFace Hub 上托管的 LLM 模型(专家模型)具有全面的模型描述,这些描述通常由开发人员提供。这些描述的内容包含:模型功能、体系结构、支持的语言和域、许可等,它们能够有效地支持 HuggingGPT 根据用户请求和模型描述的相关性为任务选择正确的模型。
在解析任务列表并完成任务规划后,接下来 HuggingGPT 就需要匹配任务和 LLM 模型(专家模型),即为任务列表中的每个任务选择合适的 LLM 模型(专家模型)。为了获取 LLM 模型,首先需要从 HuggingFace Hub 上获得专家模型的描述信息,然后通过上下文中的任务模型分配机制为任务动态选择模型。具体来说,需要根据模型的任务类型筛选模型,只保留与当前任务类型匹配的模型,对剩下的模型需要根据下载量排序,并选择 top-K 个模型作为 HuggingGPT 可以选择的候选模型集合。
模型选择阶段,生成的规范化指令模板,示例如下图所示:
HuggingGPT 选择后输出的格式必须是严格的 JSON 格式,格式如下所示:
{ "id": "id", "reason": "your detail reason for the choice" }
最终生成的专家模型候选集合,包含 top-K 个模型,以列表形式显示如下:
{ "model_id": model id #1, "metadata": meta-info # 1, "description": description of model #1} {"model_id": model id # 2, "metadata": meta - info #2, "description": description of model # 2 } ········· { "model_id": model id# K, "metadata": meta - info# K, "description": description of model# K }
任务执行
任务被分配给最合适的模型以后,接着就需要使用选定的专家模型,来对任务进行推理以执行任务。具体地,HuggingGPT 会把任务的参数输入给选定的专家模型,执行这些模型来获取推理结果,然后发送回 LLM。由于任务在与专家模型交互过程中,专家模型动态输出结果,所以 HuggingGPT 必须在任务开始执行就计划好,动态地在需要的时候提供任务所需的特定资源,以完成任务的推理执行。
理想情况下,我们只使用 HuggingFace 上的远端服务提供的推理端点(Inference Endpoints)就能完成任务执行。但现实情况并不总是这样,比如某个任务需要使用的专家模型并不存在,这样就不得不在本地部署了推理端点,是任务正常执行。所以,为了加快任务处理速度并保证计算的稳定性,HuggingGPT 会在混合推理端点上运行这些模型。通过将任务参数作为输入,模型计算推理结果,然后将其发送回 LLM。
响应生成
经过任务执行节点,在所有任务执行完成后,HuggingGPT 进入响应生成阶段。HuggingGPT 将前面三个阶段(任务规划、模型选择、任务执行)的所有信息集成在一起,包括计划任务列表、为任务选择的模型以及模型的推理结果,还有推理的结果,HuggingGPT 会依赖推理结果做出最终决策的支持。这些推理结果以结构化格式呈现,例如,对象检测模型中具有检测概率的边界框、问答模型中的答案分布等,HuggingGPT 允许 LLM 接收这些推理结果作为输入,并将具有一定置信度的响应结果进行汇总,返回给最终的用户。
下面是在响应生成阶段,生成的规范化指令模板,示例如下图所示:
收集到前三个阶段的信息,格式模板如下:
- 用户输入(User Input): {{ User Input }}
- 任务规划(Task Planning):{{ Tasks }}
- 模型选择(Model Selection){{ Model Assignment }}
- 任务执行(Task Execution){{ Predictions }}
上面可注入的 Slot(injectable slots),及双花括号内部的标识,会被替换成最终的文本内容,然后输入给 LLM,汇总得到用户需要的最终答案。
HuggingGPT 局限
虽然 HuggingGPT 提出了 AI 解决方案的新范式,但仍然存在一些限制,如下所示:
- 任务规划严重依赖 LLM 的能力
大模型并不能 100% 确保生成的计划始终是可行且最优的,因此,探索优化 LLM 的方法至关重要,进而提升规任务划能力。
- 效率
效率的瓶颈主要在使用大型语言模型的推理上。对于每一轮用户请求,HuggingGPT 都需要在任务规划、模型选择和响应生成阶段至少与大型语言模型进行一次交互,大大增加了响应延迟,并导致用户体验下降。
- 最大上下文长度的限制
受 LLM 可以接受的最大 token 数量的限制,HuggingGPT 面临着最大上下文长度的限制。通过使用会话窗口,在任务规划阶段只跟踪了会话上下文,这样做在一定程度上能够缓解这个问题。
- 系统稳定性
包括两个方面:一是在大型语言模型的推理过程中通常是不可控的。LLM 在推理时偶尔会不符合指令,并且输出格式可能会超出预期,从而导致程序工作流中出现异常;二是 HuggingFace 的推理端点上托管的专家模型的状态不可控。HuggingFace 上的专家模型可能会受到网络延迟或服务状态的影响,导致任务执行阶段出现错误。
HuggingGPT 是一个 AI 智能体的实现,这个系统来解决 AI 任务。它以语言为接口将 LLM 与 AI 模型(专家模型)连接起来,所以,LLM 可以被视为管理 AI 模型的控制器,并且可以利用来自 ML 社区(如 Hugging Face)的模型来自动解决用户的不同需求。
通过利用 LLM 在理解和推理方面的优势,HuggingGPT 可以分析用户的意图,并据此将其分解为多个子任务;然后,基于 Hugging Face 上专家模型的描述,HuggingGPT 能够为每个任务选择并分配最合适的模型,最后集成不同模型的推理结果,以生成最终响应结果内容。通过利用来自 ML 社区的众多 AI 模型的能力,HuggingGPT 在解决具有挑战性的 AI 任务方面展示了巨大的潜力,同时也为实现 AGI 做了一次有意义的探索。
参考资源
- HuggingGPT: Solving AI Tasks with ChatGPT and its Friends in Hugging Face
- https://github.com/microsoft/JARVIS
本文基于署名-非商业性使用-相同方式共享 4.0许可协议发布,欢迎转载、使用、重新发布,但务必保留文章署名时延军(包含链接:http://shiyanjun.cn),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请与我联系。