Manifest
如何让使用基础模型进行提示编程变得更容易一些。
目录
安装
安装:
pip install manifest-ml
安装支持扩散模型的版本:
pip install manifest-ml[diffusers]
安装支持 HuggingFace 本地模型的版本:
pip install manifest-ml[api]
开发安装:
git clone git@github.com:HazyResearch/manifest.git
cd manifest
make dev
入门
开始使用非常简单。如果使用 OpenAI,设置 export OPENAI_API_KEY=<OPENAIKEY>
(或通过变量 client_connection
传入密钥),然后运行
from manifest import Manifest
# 启动连接到 OpenAI 的 manifest 会话 - 默认 `engine=text-davinci-003`
manifest = Manifest(
client_name = "openai",
)
manifest.run("为什么草是绿色的?")
示例
我们在 examples 目录下提供了示例笔记本和 Python 脚本。这些示例展示了如何使用不同的模型、模型类型(如文本、扩散或嵌入模型)以及异步运行。
Manifest 组件
Manifest 旨在成为一个非常轻量级的包,帮助进行提示设计和迭代。Manifest 的三个关键设计决策是:
- 所有模型都在 API 后面
- 支持模型输入/输出的缓存,以便迭代、复现和节省成本
- 统一的 API 以支持生成、评分和嵌入
模型
Manifest 为 OpenAI、AI21、Cohere、Together 和 HuggingFace 提供模型客户端(关于如何使用本地托管的 HuggingFace 模型,请参见下文)。你可以通过更改 client_name
和 client_connection
在这些模型之间切换。例如,如果在本地加载了 HuggingFace 模型,运行
manifest = Manifest(
client_name = "huggingface",
client_connection = "http://127.0.0.1:5000",
)
如果你想使用 Cohere,运行
manifest = Manifest(
client_name = "cohere",
client_connection = <COHERE_API_KEY>,
)
你也可以直接设置 export COHERE_API_KEY=<COHERE_API_KEY>
,而不使用 client_connection
。
如果你想使用 AI21 Labs,运行
manifest = Manifest(
client_name = "ai21",
client_connection = <AI21_API_KEY>,
)
你可以通过以下方式查看模型详情和可能的 run()
模型输入:
print(manifest.client_pool.get_current_client().get_model_params())
print(manifest.client_pool.get_current_client().get_model_inputs())
全局缓存
我们支持将查询和结果存储在可以在用户之间共享的全局缓存中。我们将输入和输出视为键值对,并支持 SQLite 或 Redis 后端。要使用 SQLite 开始全局缓存,运行
manifest = Manifest(
client_name = "openai",
cache_name = "sqlite",
cache_connection = "mycache.sqlite",
)
缓存将保存在 mycache.sqlite
中。
我们还支持 Redis 后端。
manifest = Manifest(
client_name = "openai",
cache_name = "redis",
cache_connection = "localhost:6379"
)
提示:如果你想运行 Redis,请参见下面开发部分的 docker run
命令。
运行查询
一旦你打开了一个会话,你就可以编写和开发提示。
result = manifest.run("你好,我的名字是 Laurel")
如果客户端支持,你也可以在多个示例上运行。
results = manifest.run(["猫在哪里?", "狗在哪里?"])
我们还支持异步查询:
import asyncio
results = asyncio.run(manifest.arun_batch(["猫在哪里?", "狗在哪里?"]))
如果出现问题,你也可以要求获取原始的 manifest Response。
result_object = manifest.run(["猫在哪里?", "狗在哪里?"], return_response=True)
print(result_object.get_request_obj())
print(result_object.is_cached())
print(result_object.get_response_obj())
默认情况下,我们不会根据停止标记截断结果。你可以通过向 Manifest 会话或 run
传递新的停止标记来改变这一点。
result = manifest.run(prompt, "Laurel", stop_token="and")
如果你想更改模型的默认参数,我们将这些作为 kwargs
传递给客户端。
result = manifest.run(prompt, "Laurel", max_tokens=50)
流式查询
Manifest 还支持流式返回模型响应,前提是底层客户端支持此功能。调用 run
时,传递 stream=True
以获得流式迭代器作为响应。
result_iterator = manifest.run("讲个故事。从前", max_tokens=100, stream=True)
for res_text in result_iterator:
print(res_text)
流式响应仅支持文本补全模型的单个字符串查询(不支持批处理模式)。
模型池
Manifest 支持使用不同的调度器查询多个模型。这是一个正在进行中的工作,但 Manifest 将轮询选择(或随机选择)你想要的客户端。你可以使用具有不同连接字符串(例如不同的 API 密钥)的相同客户端多次,或者可以混合搭配。唯一的要求是所有客户端都是相同的请求类型。也就是说,你不能有一个生成模型和嵌入模型的池。
要在本地模型和 OpenAI 之间进行查询,
from manifest.connections.client_pool import ClientConnection
from manifest import Manifest
client_connection1 = ClientConnection(
client_name="huggingface",
client_connection="http://127.0.0.1:5000",
)
client_connection2 = ClientConnection(client_name="openai", engine="text-ada-001")
manifest = Manifest(
client_pool=[client_connection1, client_connection2],
cache_name="sqlite",
client_connection=sqlite_cache,
)
manifest.run(...)
速度优势体现在异步批处理运行中。使用提示列表调用 arun_batch
时,Manifest 支持 chunk_size
参数。这将把提示分成 chunk_size
大小的块,分布在客户端池中。默认情况下,chunk_size
为 -1
,这意味着只有一个客户端会获得所有提示以异步运行。你必须设置 chunk_size > 1
才能在池中分配。还有一个 batch_size
参数,用于控制发送到模型的单个客户端 batch_size
。
responses = asyncio.run(manifest.arun_batch(prompts, max_tokens=30, chunk_size=20))
其他模型
本地 HuggingFace 模型
要使用 HuggingFace 生成模型,我们在 manifest/api
中提供了一个 Flask 应用程序,为你托管模型。
在单独的终端或Tmux/Screen会话中,要加载6B参数模型,请运行:
python3 -m manifest.api.app \
--model_type huggingface \
--model_name_or_path EleutherAI/gpt-j-6B \
--device 0
你将看到Flask会话启动并输出一个URL http://127.0.0.1:5000
。将此URL传递给Manifest。如果你想使用不同的端口,请设置 FLASK_PORT
环境变量。
manifest = Manifest(
client_name = "huggingface",
client_connection = "http://127.0.0.1:5000",
)
如果你有自己训练的自定义模型,请将模型路径传递给 --model_name_or_path
。
为了帮助加载更大的模型,我们还支持使用HF的 parallelize()
、accelerate、bitsandbytes和deepspeed。你需要先通过 pip install manifest-ml[api]
安装这些包。以下列出了加载更大模型的命令。
- T0pp
python3 -m manifest.api.app \
--model_type huggingface \
--model_name_or_path bigscience/T0pp \
--use_hf_parallelize
- NeoX 20B(至少需要60GB GPU内存)
python3 -m manifest.api.app \
--model_type huggingface \
--model_name_or_path EleutherAI/gpt-neox-20b \
--use_accelerate_multigpu \
--percent_max_gpu_mem_reduction 0.75
- Bloom 175B(至少需要240GB GPU内存)
python3 -m manifest.api.app \
--model_type huggingface \
--model_name_or_path bigscience/bloom \
--use_bitsandbytes \
--percent_max_gpu_mem_reduction 0.85
聊天模型
Manifest专门支持以更标准的"系统"/"用户"对话方式执行聊天模型。要向Manifest传递对话历史,请使用 run
命令,并传入一个包含 role
和 content
键的字典列表,同时使用相关的聊天模型,如 openaichat
。
manifest = Manifest(client_name="openaichat")
dialogue = [
{"role": "system", "content": "你是一个乐于助人且用押韵方式回答的助手"},
{"role": "user", "content": "今天是几号?"},
]
res = manifest.run(dialogue, max_tokens=100)
嵌入模型
Manifest还支持从模型和可用API获取嵌入。我们通过更改 client_name
参数来实现这一点。你仍然使用 run
和 abatch_run
。
要使用OpenAI的嵌入模型,只需运行:
manifest = Manifest(client_name="openaiembedding")
embedding_as_np = manifest.run("给我一个兔子的嵌入")
如上所述,你也可以加载提供嵌入的本地HuggingFace模型。如果你想使用标准生成模型,请按上面的方式加载模型,并使用 client_name="huggingfaceembedding"
。如果你想使用标准嵌入模型,比如来自SentenceTransformers的模型,请通过以下方式加载你的本地模型:
python3 -m manifest.api.app \
--model_type sentence_transformers \
--model_name_or_path all-mpnet-base-v2 \
--device 0
路线图
以下是即将推出的功能:
- 客户端
- HuggingFace Hub
- Azure OpenAI
- Google Vertex
- Anthropic
- 支持流式完成
- 支持聊天模型流式处理
- 数据类型
- 扩散模型
- 编排
- 连接池
- 本地推理
- FlexGen
开发
在提交PR之前,请运行:
export REDIS_PORT="6379" # 或者本地redis运行的任何端口(用于这些测试)
cd <REDIS_PATH>
docker run -d -p 127.0.0.1:${REDIS_PORT}:6379 -v `pwd`:`pwd` -w `pwd` --name manifest_redis_test redis
make test
引用
如果你在任何出版物中使用了Manifest,请引用它。谢谢!
@misc{orr2022manifest,
author = {Orr, Laurel},
title = {Manifest},
year = {2022},
publisher = {GitHub},
howpublished = {\url{https://github.com/HazyResearch/manifest}},
}