你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

预测输出(预览版)

预测输出可以改善聊天补全调用的模型响应延迟,最大程度减少较大文本正文所需的更改。 如果要求模型提供一个响应,而大部分预期响应内容是已知的,则预测输出可以显著减少此请求的延迟。 此功能特别适用于编码的应用场景,包括自动完成、错误检测和实时编辑,速度和响应能力在这些场景下对开发人员和最终用户非常关键。 无需让模型从头开始重新生成所有文本,而是可以将已知文本传递给 prediction 参数,向模型表明大部分响应内容是已知的。

模型支持

  • gpt-4o-mini 版本:2024-07-18
  • gpt-4o 版本:2024-08-06
  • gpt-4o 版本:2024-11-20

API 支持

  • 2025-01-01-preview

不支持的功能

预测输出目前仅支持文本。 这些功能不能与 prediction 参数和预测输出结合使用。

  • 工具/函数调用
  • 音频模型/输入和输出
  • n 值高于 1
  • logprobs
  • presence_penalty 值大于 0
  • frequency_penalty 值大于 0
  • max_completion_tokens

注意

预测输出功能目前不适用于东南亚区域的模型。

入门

为了演示预测输出的基础知识,我们首先要求模型重构常见编程 FizzBuzz 问题中的代码,用 MSFTBuzz 替换 FizzBuzz 实例。 我们将在两个位置将示例代码传递给模型。 首先是在 messages 数组/列表中的用户消息中,第二次是在新 prediction 参数内容中。

可能需要升级 OpenAI 客户端库才能访问 prediction 参数。

pip install openai --upgrade
import os
from openai import AzureOpenAI
from azure.identity import DefaultAzureCredential, get_bearer_token_provider

token_provider = get_bearer_token_provider(
    DefaultAzureCredential(), "https://cognitiveservices.azure.com/.default"
)

client = AzureOpenAI(
  azure_endpoint = os.getenv("AZURE_OPENAI_ENDPOINT"), 
  azure_ad_token_provider=token_provider,
  api_version="2025-01-01-preview"
)

code = """
for number in range(1, 101):
    if number % 3 == 0 and number % 5 == 0:
        print("FizzBuzz")
    elif number % 3 == 0:
        print("Fizz")
    elif number % 5 == 0:
        print("Buzz")
    else:
        print(number)
"""

instructions = """
Replace string `FizzBuzz` with `MSFTBuzz`. Respond only 
with code, and with no markdown formatting.
"""


completion = client.chat.completions.create(
    model="gpt-4o-mini", # replace with your unique model deployment name
    messages=[
        {
            "role": "user",
            "content": instructions
        },
        {
            "role": "user",
            "content": code
        }
    ],
    prediction={
        "type": "content",
        "content": code
    }
)

print(completion.model_dump_json(indent=2))

输出

{
  "id": "chatcmpl-AskZk3P5QGmefqobDw4Ougo6jLxSP",
  "choices": [
    {
      "finish_reason": "stop",
      "index": 0,
      "logprobs": null,
      "message": {
        "content": "for number in range(1, 101):\n    if number % 3 == 0 and number % 5 == 0:\n        print(\"MSFTBuzz\")\n    elif number % 3 == 0:\n        print(\"Fizz\")\n    elif number % 5 == 0:\n        print(\"Buzz\")\n    else:\n        print(number)",
        "refusal": null,
        "role": "assistant",
        "audio": null,
        "function_call": null,
        "tool_calls": null
      },
      "content_filter_results": {
        "hate": {
          "filtered": false,
          "severity": "safe"
        },
        "protected_material_code": {
          "filtered": false,
          "detected": false
        },
        "protected_material_text": {
          "filtered": false,
          "detected": false
        },
        "self_harm": {
          "filtered": false,
          "severity": "safe"
        },
        "sexual": {
          "filtered": false,
          "severity": "safe"
        },
        "violence": {
          "filtered": false,
          "severity": "safe"
        }
      }
    }
  ],
  "created": 1737612112,
  "model": "gpt-4o-mini-2024-07-18",
  "object": "chat.completion",
  "service_tier": null,
  "system_fingerprint": "fp_5154047bf2",
  "usage": {
    "completion_tokens": 77,
    "prompt_tokens": 124,
    "total_tokens": 201,
    "completion_tokens_details": {
      "accepted_prediction_tokens": 6,
      "audio_tokens": 0,
      "reasoning_tokens": 0,
      "rejected_prediction_tokens": 4
    },
    "prompt_tokens_details": {
      "audio_tokens": 0,
      "cached_tokens": 0
    }
  },
  "prompt_filter_results": [
    {
      "prompt_index": 0,
      "content_filter_results": {
        "hate": {
          "filtered": false,
          "severity": "safe"
        },
        "jailbreak": {
          "filtered": false,
          "detected": false
        },
        "self_harm": {
          "filtered": false,
          "severity": "safe"
        },
        "sexual": {
          "filtered": false,
          "severity": "safe"
        },
        "violence": {
          "filtered": false,
          "severity": "safe"
        }
      }
    }
  ]
}

请注意输出中 accepted_prediction_tokensrejected_prediction_tokens 的新响应参数:

  "usage": {
    "completion_tokens": 77,
    "prompt_tokens": 124,
    "total_tokens": 201,
    "completion_tokens_details": {
      "accepted_prediction_tokens": 6,
      "audio_tokens": 0,
      "reasoning_tokens": 0,
      "rejected_prediction_tokens": 4
    }

accepted_prediction_tokens 有助于降低模型响应延迟,但任何 rejected_prediction_tokens 都有和模型生成的额外输出令牌相同的成本影响。 因此,虽然预测输出可以改善模型响应时间,但它可能会导致更高的成本。 需要评估和权衡可能增加的成本和模型性能。

此外请务必了解,使用预测输出不能保证降低延迟。 如果大型请求被拒绝的预测令牌百分比大于接受的预测令牌,可能会导致模型响应延迟增加,而不是减少。

注意

提示缓存仅在请求开始时设置的最小数量初始令牌相同时生效,而预测输出不受令牌位置的限制。 即使响应文本包含将在预测输出之前返回的新输出,仍可能发生 accepted_prediction_tokens

流式处理

在启用流式处理返回响应时,预测输出性能提升通常最为明显。

可能需要升级 OpenAI 客户端库才能访问 prediction 参数。

pip install openai --upgrade
import os
from openai import AzureOpenAI
from azure.identity import DefaultAzureCredential, get_bearer_token_provider

token_provider = get_bearer_token_provider(
    DefaultAzureCredential(), "https://cognitiveservices.azure.com/.default"
)

client = AzureOpenAI(
  azure_endpoint = os.getenv("AZURE_OPENAI_ENDPOINT"), 
  azure_ad_token_provider=token_provider,
  api_version="2025-01-01-preview"
)

code = """
for number in range(1, 101):
    if number % 3 == 0 and number % 5 == 0:
        print("FizzBuzz")
    elif number % 3 == 0:
        print("Fizz")
    elif number % 5 == 0:
        print("Buzz")
    else:
        print(number)
"""

instructions = """
Replace string `FizzBuzz` with `MSFTBuzz`. Respond only 
with code, and with no markdown formatting.
"""


completion = client.chat.completions.create(
    model="gpt-4o-mini", # replace with your unique model deployment name
    messages=[
        {
            "role": "user",
            "content": instructions
        },
        {
            "role": "user",
            "content": code
        }
    ],
    prediction={
        "type": "content",
        "content": code
    },
    stream=True
)

for chunk in completion:
    if chunk.choices and chunk.choices[0].delta.content is not None:
        print(chunk.choices[0].delta.content, end='',)