text-generation-inference 文档

流式传输

Hugging Face's logo
加入 Hugging Face 社区

并获得增强的文档体验

开始使用

流式传输

什么是流式传输?

令牌流式传输是一种模式,其中服务器在模型生成令牌时逐个返回令牌。 这使得可以向用户显示渐进式生成,而不是等待整个生成完成。 流式传输是最终用户体验的重要方面,因为它减少了延迟,而延迟是流畅体验最关键的方面之一。

通过令牌流式传输,服务器可以在生成整个响应之前开始逐个返回令牌。 用户可以在生成结束之前对生成的质量有所了解。 这有不同的积极影响

  • 对于极长的查询,用户可以提前几个数量级获得结果。
  • 看到正在进行中的内容允许用户在生成方向不符合预期时停止生成。
  • 当结果在早期阶段显示时,感知延迟较低。
  • 当在对话式 UI 中使用时,体验感觉更自然。

例如,一个系统每秒可以生成 100 个令牌。 如果系统生成 1000 个令牌,在非流式传输设置下,用户需要等待 10 秒才能获得结果。 另一方面,使用流式传输设置,用户可以立即获得初始结果,虽然端到端延迟将相同,但他们可以在五秒后看到一半的生成内容。 下面你可以看到一个交互式演示,并排显示了非流式传输与流式传输。 点击下面的 **生成**。

如何使用流式传输?

使用 Python 进行流式传输

要使用 InferenceClient 流式传输令牌,只需传递 stream=True 并迭代响应。

from huggingface_hub import InferenceClient

client = InferenceClient(base_url="http://127.0.0.1:8080")
output = client.chat.completions.create(
    messages=[
        {"role": "system", "content": "You are a helpful assistant."},
        {"role": "user", "content": "Count to 10"},
    ],
    stream=True,
    max_tokens=1024,
)

for chunk in output:
    print(chunk.choices[0].delta.content)

# 1
# 2
# 3
# 4
# 5
# 6
# 7
# 8
# 9
# 10

huggingface_hub 库还附带一个 AsyncInferenceClient,以防您需要并发处理请求。

from huggingface_hub import AsyncInferenceClient

client = AsyncInferenceClient(base_url="http://127.0.0.1:8080")
async def main():
    stream = await client.chat.completions.create(
        messages=[{"role": "user", "content": "Say this is a test"}],
        stream=True,
    )
    async for chunk in stream:
        print(chunk.choices[0].delta.content or "", end="")

asyncio.run(main())

# This
# is
# a
# test
#.

使用 cURL 进行流式传输

要将 OpenAI Chat Completions 兼容的 Messages API v1/chat/completions 端点与 curl 一起使用,您可以添加 -N 标志,该标志禁用 curl 默认缓冲并显示从服务器到达的数据

curl localhost:8080/v1/chat/completions \
    -X POST \
    -d '{
  "model": "tgi",
  "messages": [
    {
      "role": "system",
      "content": "You are a helpful assistant."
    },
    {
      "role": "user",
      "content": "What is deep learning?"
    }
  ],
  "stream": true,
  "max_tokens": 20
}' \
    -H 'Content-Type: application/json'

使用 JavaScript 进行流式传输

首先,我们需要安装 @huggingface/inference 库。 npm install @huggingface/inference

如果您使用的是免费的 Inference API,则可以使用 HfInference。 如果您使用的是推理端点,则可以使用 HfInferenceEndpoint

我们可以创建一个 HfInferenceEndpoint,提供我们的端点 URL 和凭据。

import { HfInferenceEndpoint } from '@huggingface/inference'

const hf = new HfInferenceEndpoint('https://YOUR_ENDPOINT.endpoints.huggingface.cloud', 'hf_YOUR_TOKEN')

// prompt
const prompt = 'What can you do in Nuremberg, Germany? Give me 3 Tips'

const stream = hf.textGenerationStream({ inputs: prompt })
for await (const r of stream) {
  // yield the generated token
  process.stdout.write(r.token.text)
}

流式传输在底层是如何工作的?

在底层,TGI 使用服务器发送事件 (SSE)。 在 SSE 设置中,客户端发送带有数据的请求,打开 HTTP 连接并订阅更新。 之后,服务器将数据发送到客户端。 无需进一步请求; 服务器将继续发送数据。 SSE 是单向的,这意味着客户端不向服务器发送其他请求。 SSE 通过 HTTP 发送数据,使其易于使用。

SSE 与以下方式不同:

  • 轮询:客户端不断调用服务器以获取数据。 这意味着服务器可能会返回空响应并导致开销。
  • Webhooks:其中存在双向连接。 服务器可以将信息发送到客户端,但客户端也可以在首次请求后将数据发送到服务器。 Webhooks 操作起来更复杂,因为它们不仅仅使用 HTTP。

如果同时请求过多,TGI 将返回 HTTP 错误,并带有 overloaded 错误类型(huggingface_hub 返回 OverloadedError)。 这允许客户端管理过载的服务器(例如,它可以向用户显示繁忙错误或使用新请求重试)。 要配置最大并发请求数,您可以指定 --max_concurrent_requests,从而允许客户端处理背压。

< > 在 GitHub 上更新