开源 AI 食谱文档
Serverless Inference API
并获得增强的文档体验
开始使用
Serverless Inference API
作者: Andrew Reed
Hugging Face 提供 Serverless Inference API,使用户可以通过简单的 API 调用快速测试和评估数千个公开访问(或您自己私有许可)的机器学习模型,完全免费!
在本笔记本食谱中,我们将演示几种不同的查询 Serverless Inference API 的方法,同时探索各种任务,包括
- 使用开放 LLM 生成文本
- 使用 Stable Diffusion 创建图像
- 使用 VLM 对图像进行推理
- 从文本生成语音
目标是通过涵盖基础知识来帮助您入门!
由于我们免费提供 Serverless Inference API,因此对于普通的 Hugging Face 用户存在速率限制(约每小时几百个请求)。要获得更高的速率限制,您可以升级到 PRO 帐户,每月只需 9 美元。但是,对于高容量、生产环境推理工作负载,请查看我们的 Dedicated Inference Endpoints 解决方案。
开始吧
要开始使用 Serverless Inference API,您需要一个 Hugging Face Hub 个人资料:如果您没有,可以注册,如果您有,可以在此处登录。
接下来,您需要创建一个 用户访问令牌。具有 read
或 write
权限的令牌都可以使用。但是,我们强烈建议使用细粒度令牌。
对于本笔记本,您需要一个细粒度令牌,其中包含 Inference > Make calls to the serverless Inference API
用户权限,以及对 meta-llama/Meta-Llama-3-8B-Instruct
和 HuggingFaceM4/idefics2-8b-chatty
仓库的读取权限,因为我们必须下载它们的 tokenizer 才能运行此笔记本。
完成这些步骤后,我们可以安装所需的软件包,并使用您的用户访问令牌验证 Hub 的身份。
%pip install -U huggingface_hub transformers
import os
from huggingface_hub import interpreter_login, whoami, get_token
# running this will prompt you to enter your Hugging Face credentials
interpreter_login()
我们上面使用了 interpreter_login()
以编程方式登录 Hub。作为替代方案,我们还可以使用其他方法,例如来自 Hub Python Library 的 notebook_login()
或来自 Hugging Face CLI 工具 的 login
命令。
现在,让我们验证是否已正确登录,使用 whoami()
打印出活动用户名以及您的个人资料所属的组织。
whoami()
查询 Serverless Inference API
Serverless Inference API 通过一个简单的 API 在 Hub 上公开模型
https://api-inference.huggingface.co/models/<MODEL_ID>
其中 <MODEL_ID>
对应于 Hub 上模型仓库的名称。
例如,codellama/CodeLlama-7b-hf 变为 https://api-inference.huggingface.co/models/codellama/CodeLlama-7b-hf
通过 HTTP 请求
我们可以通过 requests
库,使用简单的 POST
请求轻松调用此 API。
>>> import requests
>>> API_URL = "https://api-inference.huggingface.co/models/codellama/CodeLlama-7b-hf"
>>> HEADERS = {"Authorization": f"Bearer {get_token()}"}
>>> def query(payload):
... response = requests.post(API_URL, headers=HEADERS, json=payload)
... return response.json()
>>> print(
... query(
... payload={
... "inputs": "A HTTP POST request is used to ",
... "parameters": {"temperature": 0.8, "max_new_tokens": 50, "seed": 42},
... }
... )
... )
[{'generated_text': 'A HTTP POST request is used to send data to a web server.\n\n# Example\n```javascript\npost("localhost:3000", {foo: "bar"})\n .then(console.log => console.log(\'success\'))\n```\n\n'}]
不错!API 使用我们输入提示的延续进行了响应。但您可能想知道……API 如何知道如何处理有效负载?以及作为用户,我如何知道可以为给定模型传递哪些参数?
在幕后,推理 API 将动态加载请求的模型到共享计算基础设施上以提供预测。加载模型后,Serverless Inference API 将使用模型卡中指定的 pipeline_tag
(请参阅此处)来确定适当的推理任务。您可以参考相应的任务或 pipeline 文档来查找允许的参数。
如果在请求时,请求的模型尚未加载到内存中(这由最近对该模型的请求决定),则 Serverless Inference API 最初将返回 503 响应,然后才能成功响应预测。稍后重试,让模型有时间启动。您还可以使用 InferenceClient().list_deployed_models()
检查哪些模型已加载并在任何给定时间可用。
使用 huggingface_hub Python 库
要在 Python 中发送您的请求,您可以利用 InferenceClient
,这是 huggingface_hub
Python 库中提供的便捷实用程序,可让您轻松调用 Serverless Inference API。
>>> from huggingface_hub import InferenceClient
>>> client = InferenceClient()
>>> response = client.text_generation(
... prompt="A HTTP POST request is used to ",
... model="codellama/CodeLlama-7b-hf",
... temperature=0.8,
... max_new_tokens=50,
... seed=42,
... return_full_text=True,
... )
>>> print(response)
A HTTP POST request is used to send data to a web server. # Example ```javascript post("localhost:3000", {foo: "bar"}) .then(console.log => console.log('success')) ```
请注意,使用 InferenceClient
,我们仅指定模型 ID,并将参数直接传递到 text_generation()
方法中。我们可以轻松检查函数签名,以查看有关如何使用任务及其允许参数的更多详细信息。
# uncomment the following line to see the function signature
# help(client.text_generation)
除了 Python 之外,您还可以使用 JavaScript 将推理调用集成到您的 JS 或 node 应用程序中。查看 huggingface.js 以开始使用。
应用
现在我们了解了 Serverless Inference API 的工作原理,让我们试用一下,并在此过程中学习一些技巧。
1. 使用开放 LLM 生成文本
文本生成是一个非常常见的用例。但是,与开放 LLM 交互有一些细微之处,理解这些细微之处对于避免无声的性能下降非常重要。在文本生成方面,底层语言模型可能具有几种不同的风格
- 基础模型: 指的是普通的预训练语言模型,如 codellama/CodeLlama-7b-hf 或 meta-llama/Meta-Llama-3-8B。这些模型擅长从提供的提示中继续生成(就像我们在上面的示例中看到的那样)。但是,它们尚未针对对话式使用进行微调,例如回答问题。
- 指令调优模型: 以多任务方式进行训练,以遵循广泛的指令,例如“为我写一个巧克力蛋糕的食谱”。像 meta-llama/Meta-Llama-3-8B-Instruct 或 mistralai/Mistral-7B-Instruct-v0.3 这样的模型就是以这种方式训练的。与基础模型相比,指令调优模型将对指令产生更好的响应。通常,这些模型也针对多轮聊天对话进行了微调,使其非常适合对话用例。
理解这些细微的差异很重要,因为它们会影响我们应如何查询特定模型的方式。Instruct 模型使用特定于模型的 聊天模板 进行训练,因此您需要注意模型期望的格式,并在查询中复制它。
例如,meta-llama/Meta-Llama-3-8B-Instruct 使用以下提示结构来区分系统、用户和助手对话轮次
<|begin_of_text|><|start_header_id|>system<|end_header_id|> {{ system_prompt }}<|eot_id|><|start_header_id|>user<|end_header_id|> {{ user_msg_1 }}<|eot_id|><|start_header_id|>assistant<|end_header_id|> {{ model_answer_1 }}<|eot_id|>
特殊标记和提示格式因模型而异。为了确保我们使用正确的格式,我们可以通过模型的 tokenizer 依赖于模型的 聊天模板,如下所示。
>>> from transformers import AutoTokenizer
>>> # define the system and user messages
>>> system_input = "You are an expert prompt engineer with artistic flair."
>>> user_input = "Write a concise prompt for a fun image containing a llama and a cookbook. Only return the prompt."
>>> messages = [
... {"role": "system", "content": system_input},
... {"role": "user", "content": user_input},
... ]
>>> # load the model and tokenizer
>>> model_id = "meta-llama/Meta-Llama-3-8B-Instruct"
>>> tokenizer = AutoTokenizer.from_pretrained(model_id)
>>> # apply the chat template to the messages
>>> prompt = tokenizer.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
>>> print(f"\nPROMPT:\n-----\n\n{prompt}")
PROMPT: ----- <|begin_of_text|><|start_header_id|>system<|end_header_id|> You are an expert prompt engineer with artistic flair.<|eot_id|><|start_header_id|>user<|end_header_id|> Write a concise prompt for a fun image containing a llama and a cookbook. Only return the prompt.<|eot_id|><|start_header_id|>assistant<|end_header_id|>
请注意,apply_chat_template()
方法如何获取熟悉的邮件列表,并将其转换为我们的模型期望的正确格式化字符串。我们可以使用此格式化字符串传递给 Serverless Inference API 的 text_generation
方法。
>>> llm_response = client.text_generation(prompt, model=model_id, max_new_tokens=250, seed=42)
>>> print(llm_response)
"A whimsical illustration of a llama proudly holding a cookbook, with a sassy expression and a sprinkle of flour on its nose, surrounded by a colorful kitchen backdrop with utensils and ingredients scattered about, as if the llama is about to whip up a culinary masterpiece."
在不遵守模型的提示模板的情况下查询 LLM 不会 产生任何明显的错误!但是,它会导致输出质量差。看看当我们传递相同的系统和用户输入,但 没有 根据聊天模板对其进行格式化时会发生什么。
>>> out = client.text_generation(system_input + " " + user_input, model=model_id, max_new_tokens=250, seed=42)
>>> print(out)
Do not write the... 1 answer below » You are an expert prompt engineer with artistic flair. Write a concise prompt for a fun image containing a llama and a cookbook. Only return the prompt. Do not write the image description. A llama is sitting at a kitchen table, surrounded by cookbooks and utensils, with a cookbook open in front of it. The llama is wearing a chef's hat and holding a spatula. The cookbook is titled "Llama's Favorite Recipes" and has a llama on the cover. The llama is surrounded by a warm, golden light, and the kitchen is filled with the aroma of freshly baked bread. The llama is smiling and looking directly at the viewer, as if inviting them to join in the cooking fun. The image should be colorful, whimsical, and full of texture and detail. The llama should be the main focus of the image, and the cookbook should be prominently displayed. The background should be a warm, earthy color, such as terracotta or sienna. The overall mood of the image should be playful, inviting, and joyful. 1 answer below » You are an expert prompt engineer with artistic flair. Write a concise prompt for a fun image containing a llama and a
哎呀!LLM 幻想着一个无意义的介绍,意外地重复了提示,并且未能保持简洁。为了简化提示过程并确保正在使用正确的聊天模板,InferenceClient
还提供了一个 chat_completion
方法,该方法抽象出了 chat_template
详细信息。这使您可以简单地传递消息列表
>>> for token in client.chat_completion(messages, model=model_id, max_tokens=250, stream=True, seed=42):
... print(token.choices[0].delta.content)
"A whims ical illustration of a fashion ably dressed llama proudly holding a worn , vintage cookbook , with a warm cup of tea and a few freshly baked treats scattered around , set against a cozy background of rustic wood and blo oming flowers ."
流式传输
在上面的示例中,我们还设置了 stream=True
以启用从端点流式传输文本。要了解有关此类功能的更多信息以及查询 LLM 时的最佳实践,我们建议阅读以下支持资源
- 如何生成文本:使用不同的解码方法通过 Transformers 进行语言生成
- 文本生成策略
- Inference for PROs - 特别是关于 控制文本生成 的部分
- Inference Client 文档
2. 使用 Stable Diffusion 创建图像
Serverless Inference API 可用于许多不同的任务。在这里,我们将使用它通过 Stable Diffusion 生成图像。
>>> image = client.text_to_image(
... prompt=llm_response,
... model="stabilityai/stable-diffusion-xl-base-1.0",
... guidance_scale=8,
... seed=42,
... )
>>> display(image.resize((image.width // 2, image.height // 2)))
>>> print("PROMPT: ", llm_response)
缓存
默认情况下,InferenceClient
将缓存 API 响应。这意味着如果您多次使用相同的有效负载查询 API,您将看到 API 返回的结果完全相同。看看
>>> image = client.text_to_image(
... prompt=llm_response,
... model="stabilityai/stable-diffusion-xl-base-1.0",
... guidance_scale=8,
... seed=42,
... )
>>> display(image.resize((image.width // 2, image.height // 2)))
>>> print("PROMPT: ", llm_response)
要强制每次获得不同的响应,我们可以使用 HTTP 标头让客户端忽略缓存并运行新的生成:x-use-cache: 0
。
>>> # turn caching off
>>> client.headers["x-use-cache"] = "0"
>>> # generate a new image with the same prompt
>>> image = client.text_to_image(
... prompt=llm_response,
... model="stabilityai/stable-diffusion-xl-base-1.0",
... guidance_scale=8,
... seed=42,
... )
>>> display(image.resize((image.width // 2, image.height // 2)))
>>> print("PROMPT: ", llm_response)
3. 使用 Idefics2 对图像进行推理
视觉语言模型 (VLM) 可以同时将文本和图像作为输入,并生成文本作为输出。这使他们能够处理从视觉问题解答到图像字幕的许多任务。让我们使用 Serverless Inference API 查询 Idefics2,这是一个强大的 8B 参数 VLM,并让它为我们新生成的图像写一首诗。
我们首先需要将 PIL 图像转换为 base64
编码的字符串,以便我们可以通过网络将其发送到模型。
import base64
from io import BytesIO
def pil_image_to_base64(image):
buffered = BytesIO()
image.save(buffered, format="JPEG")
img_str = base64.b64encode(buffered.getvalue()).decode("utf-8")
return img_str
image_b64 = pil_image_to_base64(image)
然后,我们需要使用聊天模板正确格式化我们的文本 + 图像提示。有关提示格式的详细信息,请参阅 Idefics2 模型卡。
from transformers import AutoProcessor
# load the processor
vlm_model_id = "HuggingFaceM4/idefics2-8b-chatty"
processor = AutoProcessor.from_pretrained(vlm_model_id)
# define the user messages
messages = [
{
"role": "user",
"content": [
{"type": "image"},
{"type": "text", "text": "Write a short limerick about this image."},
],
},
]
# apply the chat template to the messages
prompt = processor.apply_chat_template(messages, add_generation_prompt=True)
# add the base64 encoded image to the prompt
image_input = f"data:image/jpeg;base64,{image_b64}"
image_input = f""
prompt = prompt.replace("<image>", image_input)
最后,调用 Serverless API 以获得预测。在我们的例子中,是一首关于我们生成的图像的有趣的五行打油诗!
>>> limerick = client.text_generation(prompt, model=vlm_model_id, max_new_tokens=200, seed=42)
>>> print(limerick)
In the heart of a kitchen, so bright and so clean, Lived a llama named Lulu, quite the culinary queen. With a book in her hand, she'd read and she'd cook, Her recipes were magic, her skills were so nook. In her world, there was no room for defeat, For Lulu, the kitchen was where she'd meet.
4. 从文本生成语音
最后,让我们使用基于 transformers 的文本到音频模型 Bark 为我们的诗歌生成可听见的配音。
tts_model_id = "suno/bark"
speech_out = client.text_to_speech(text=limerick, model=tts_model_id)
>>> from IPython.display import Audio
>>> display(Audio(speech_out, rate=24000))
>>> print(limerick)
In the heart of a kitchen, so bright and so clean, Lived a llama named Lulu, quite the culinary queen. With a book in her hand, she'd read and she'd cook, Her recipes were magic, her skills were so nook. In her world, there was no room for defeat, For Lulu, the kitchen was where she'd meet.
下一步
就是这样!在本笔记本中,我们学习了如何使用 Serverless Inference API 查询各种强大的 transformer 模型。我们只是触及了您可以执行的操作的冰山一角,并建议查看文档,以了解更多可能的功能。
< > 在 GitHub 上更新