2024-11-21 一站式 AI 平台生日大派对!2024-11-21 一站式 AI 平台生日大派对! 无问芯穹特别推出多项超值福利!立即参与
Skip to content

GenStudio M×N 推理服务 API 使用教程

大模型服务平台(GenStudio)为 LLM 提供了专用的多模型芯片(M×N)推理 API 端点。本文将指导您如何通过常用工具适配 M×N 推理 API 端点。

NOTE

M×N 多模型芯片推理服务仅支持部分预置大语言模型。

OpenAI API 兼容性

M×N 多模型芯片 API 服务与 OpenAI Chat Completions 接口兼容,但路径不同于 OpenAI /v1/chat/completions,实际路径与所选模型芯片组合相关。

https://cloud.infini-ai.com/maas/{model}/{chiptype}/chat/completions

NOTE

关于 M×N API 端点的路径、参数等细节,详见 大语言模型 API 参考文档

前提条件

Step 0 获取 API 密钥

调用大模型服务平台的任何 API,均需要通过 API Key 进行鉴权。首次使用时,您需要创建一个 API Key。

请前往密钥管理页面创建 API 密钥。根据系统提示完成二次验证后,可复制密钥。

alt text

TIP

复制 API 密钥时,您可能需要根据提示,完成绑定手机号及二次验证操作。

Step 1 选择模型

前往大模型服务平台的模型广场,选择期望通过 API 方式试用的大模型。本教程以由无问芯穹公司自主研发的70亿参数大语言模型 mt-infini-3b 为例。

alt text

Step 2 获取 API 端点

模型广场点击 mt-infini-3b 后,切换到调用说明标签页面,可一键复制当前模型的调用示例。

alt text

GenStudio API 服务的 API Server 地址(模型名称、芯片类型)已经在调用示例中拼接好,可直接使用。

shell
curl https://cloud.infini-ai.com/maas/mt-infini-3b/nvidia/chat/completions \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer $API_KEY" \
    -d '{
         "model": "mt-infini-3b",
         "messages": [
            { "role": "user", "content": "你是谁?" }
          ]
     }'

使用 Curl

您可以通过调用示例中的 curl 命令直接发送 API 请求。

TIP

请将 $API_KEY 修改为您获取的 API 密钥。

验证单轮对话(非流式)

以下请求示例发起一个单轮对话。以下示例未指定 stream 参数,因此 API 服务使用默认响应方式(非流式响应)。

shell
curl https://cloud.infini-ai.com/maas/mt-infini-3b/nvidia/chat/completions \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer $API_KEY" \
    -d '{
         "model": "mt-infini-3b",
         "messages": [
            { "role": "user", "content": "你是谁?" }
          ]
     }'

单轮对话也可以携带 system message,示例如下

json
"messages": [
    { "role": "system", "content": "请以嘲讽语气回答" },
    { "role": "user", "content": "你是谁?" }
]

API 服务默认使用非流式响应。请求成功时,一次性返回生成的内容,结构遵循 ChatCompletionObject

响应正文示例如下:

json
{
    "id": "chatcmpl-n5McEDBxBdxNDbx2CA8Rz8",
    "object": "chat.completion",
    "created": 1708497105,
    "model": "mt-infini-3b",
    "choices": [
        {
            "index": 0,
            "message": {
                "role": "assistant",
                "content": "我是来自无问芯穹的大规模语言模型,我叫无问天权。"
            },
            "finish_reason": "stop"
        }
    ],
    "usage": {
        "prompt_tokens": 22,
        "total_tokens": 39,
        "completion_tokens": 17
    }
}

IMPORTANT

  • 若文本审核违规,则新增 blocked 字段且值为 true,后面响应不再继续输出
  • 若文本审核通过,则无 blocked 字段,后面响应正常输出。

验证单轮对话(流式)

以下示例明确指定 stream 参数为 true,因此 API 服务将会采用流式响应方式返回类型。

shell
curl https://cloud.infini-ai.com/maas/mt-infini-3b/nvidia/chat/completions \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer $API_KEY" \
    -d '{
         "model": "mt-infini-3b",
         "stream": true,
         "messages": [
            { "role": "user", "content": "你是谁?" }
          ]
     }'

在流式响应模式下,请求成功时,一次性返回生成的内容,结构遵循 ChatCompletionChunkObject

IMPORTANT

当前仅 chip3chip4chip5 存在以下问题:

  1. 流式响应模式下,暂不支持返回 Content-Type 为 text/event-stream 的 data-only server-sent events,因此响应体中的数据不会带有 data: 字段。
  2. 流式响应模式下,暂不支持返回标志对话结束标志 data: [DONE]
  3. 流式响应模式下,仅在最后一条返回数据中携带携带 objectcreated 字段。

响应正文示例如下:

json
{"id": "chatcmpl-3HjYf888MzQ6XAHADiPanf", "model": "mt-infini-3b", "choices": [{"index": 0, "delta": {"role": "assistant"}, "finish_reason": null}]}

{"id": "chatcmpl-3HjYf888MzQ6XAHADiPanf", "model": "mt-infini-3b", "choices": [{"index": 0, "delta": {"content": "我是"}, "finish_reason": null}]}

{"id": "chatcmpl-3HjYf888MzQ6XAHADiPanf", "model": "mt-infini-3b", "choices": [{"index": 0, "delta": {"content": "来自"}, "finish_reason": null}]}

{"id": "chatcmpl-3HjYf888MzQ6XAHADiPanf", "model": "mt-infini-3b", "choices": [{"index": 0, "delta": {"content": "无问"}, "finish_reason": null}]}

{"id": "chatcmpl-3HjYf888MzQ6XAHADiPanf", "model": "mt-infini-3b", "choices": [{"index": 0, "delta": {"content": "芯穹"}, "finish_reason": null}]}

{"id": "chatcmpl-3HjYf888MzQ6XAHADiPanf", "model": "mt-infini-3b", "choices": [{"index": 0, "delta": {"content": "的"}, "finish_reason": null}]}

{"id": "chatcmpl-3HjYf888MzQ6XAHADiPanf", "model": "mt-infini-3b", "choices": [{"index": 0, "delta": {"content": "超"}, "finish_reason": null}]}

{"id": "chatcmpl-3HjYf888MzQ6XAHADiPanf", "model": "mt-infini-3b", "choices": [{"index": 0, "delta": {"content": "大规模"}, "finish_reason": null}]}

{"id": "chatcmpl-3HjYf888MzQ6XAHADiPanf", "model": "mt-infini-3b", "choices": [{"index": 0, "delta": {"content": "语言"}, "finish_reason": null}]}

{"id": "chatcmpl-3HjYf888MzQ6XAHADiPanf", "model": "mt-infini-3b", "choices": [{"index": 0, "delta": {"content": "模型"}, "finish_reason": null}]}

{"id": "chatcmpl-3HjYf888MzQ6XAHADiPanf", "model": "mt-infini-3b", "choices": [{"index": 0, "delta": {"content": ","}, "finish_reason": null}]}

{"id": "chatcmpl-3HjYf888MzQ6XAHADiPanf", "model": "mt-infini-3b", "choices": [{"index": 0, "delta": {"content": "我"}, "finish_reason": null}]}

{"id": "chatcmpl-3HjYf888MzQ6XAHADiPanf", "model": "mt-infini-3b", "choices": [{"index": 0, "delta": {"content": "叫"}, "finish_reason": null}]}

{"id": "chatcmpl-3HjYf888MzQ6XAHADiPanf", "model": "mt-infini-3b", "choices": [{"index": 0, "delta": {"content": "无"}, "finish_reason": null}]}

{"id": "chatcmpl-3HjYf888MzQ6XAHADiPanf", "model": "mt-infini-3b", "choices": [{"index": 0, "delta": {"content": "问"}, "finish_reason": null}]}

{"id": "chatcmpl-3HjYf888MzQ6XAHADiPanf", "model": "mt-infini-3b", "choices": [{"index": 0, "delta": {"content": "天"}, "finish_reason": null}]}

{"id": "chatcmpl-3HjYf888MzQ6XAHADiPanf", "model": "mt-infini-3b", "choices": [{"index": 0, "delta": {"content": "权"}, "finish_reason": null}]}

{"id": "chatcmpl-3HjYf888MzQ6XAHADiPanf", "model": "mt-infini-3b", "choices": [{"index": 0, "delta": {"content": "。"}, "finish_reason": null}]}

{"id": "chatcmpl-3HjYf888MzQ6XAHADiPanf", "object": "chat.completion.chunk", "created": 1708486029, "model": "mt-infini-3b", "choices": [{"index": 0, "delta": {}, "finish_reason": "stop"}], "usage": {"prompt_tokens": 22, "total_tokens": 40, "completion_tokens": 18}}

验证多轮对话

API 服务可接受多轮对话请求,一对 user message + assistant message 算一轮(也可包含 system message)。

以下示例展示了一个多轮对话请求。

shell
curl https://cloud.infini-ai.com/maas/mt-infini-3b/nvidia/chat/completions \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer $API_KEY" \
    -d '{
        "model": "mt-infini-3b",
        "messages": [
            { "role": "user", "content": "你是谁?" },
            { "role": "assistant", "content": "我是大模型回答助手" },
            { "role": "user", "content": "你能做什么?" },
        ]
     }'

使用 OpenAI Python SDK

无问芯穹大模型 API 服务支持通过 OpenAI 官方 Python SDK 进行调用。

TIP

部分国产芯片的 API 服务目前尚不能完全兼容 OpenAI Python SDK。

创建客户端

需要指定 base_url 为无问芯穹大模型 API 服务的地址,在 api_key 中传入 API 密钥。以下示例从环境变量中加载了 API 路径和 API 密钥。

python
from openai import OpenAI
from dotenv import load_dotenv
import os

# 加载 .env 文件
load_dotenv()

client = OpenAI(
    # This is the default and can be omitted
    api_key=os.environ.get("OPENAI_API_KEY"),
    base_url=os.environ.get("OPENAI_API_BASE")
)


base_url=os.environ.get("OPENAI_API_BASE")

print("无问芯穹的 base_url 格式: \n" + str(client.base_url))
无问芯穹的 base_url 格式:
https://cloud.infini-ai.com/maas/qwen1.5-72b-chat/nvidia/

验证一(流式)

python
stream = client.chat.completions.create(
    model="qwen1.5-72b-chat",
    messages=[{"role": "user", "content": "根据中国古代圣人孔子的思想,人生的意义是什么?"}],
    stream=True,
)
for chunk in stream:
    print(chunk.choices[0].delta.content or "", end="")
孔子认为,人生的意义在于实现“仁”,即以仁爱之心对待他人,追求道德完善,以及实现社会和谐。他强调“修身、齐家、治国、平天下”,认为一个人应该首先修养自身,然后才能管理好家庭,进一步治理好国家,最终达到天下和平。此外,孔子也重视学习和知识,他认为“学而时习之,不亦说乎?”通过不断学习和实践,可以提升自我,接近人生的意义。

验证二(非流式)

python
chat_completion = client.chat.completions.create(
    messages=[
        {
            "role": "user",
            "content": "say '谁是卧底。'",
        }
    ],
    model="qwen1.5-72b-chat",
)

print(chat_completion.choices[0].message.content)
谁是卧底?

使用 Langchain 的 OpenAI 插件

无问芯穹大模型 API 服务支持通过 Langchain 的 OpenAI 插件进行调用。

TIP

部分国产芯片的 API 服务目前尚不能完全兼容 OpenAI 官方格式。

准备环境

请提前获取无问芯穹大模型 API 服务的地址和 API 密钥。以下示例从环境变量中加载了 API 路径和 API 密钥。

python
import os
from dotenv import load_dotenv

# 加载 .env 文件
load_dotenv()

# 从环境变量中获取 OPENAI_API_KEY
openai_api_key = os.environ.get("OPENAI_API_KEY1")
openai_api_base = os.environ.get("OPENAI_API_BASE")

print("无问芯穹 API 地址: \n" + str(openai_api_base))

无问芯穹 API 地址: 
https://cloud.infini-ai.com/maas/qwen1.5-72b-chat/nvidia/

验证一(流式)

python
from langchain_openai import ChatOpenAI
from langchain.callbacks.base import BaseCallbackHandler
from typing import Any, Dict, List

# Define a callback handler to process streaming tokens
class StreamHandler(BaseCallbackHandler):
    def on_llm_new_token(self, token: str, **kwargs: Any) -> None:
        print(token, end="", flush=True)

# Initialize the ChatOpenAI model with streaming enabled
llm_streaming = ChatOpenAI(
    openai_api_key=openai_api_key, 
    openai_api_base=openai_api_base,
    streaming=True,
    callbacks=[StreamHandler()]  # Pass the callback handler
)

# Define your messages
messages = [
    {"role": "system", "content": "You are a pedantic anticient Chinese scholar, who always answers in Simplified Chinese."},
    {"role": "user", "content": "Tell me a joke."}
]

# Get a response from the chat model
response = llm_streaming.invoke(input=messages)

# Output the response (optional, as it is already printed by the callback)
print("\n\n***********\n\n以下是 LLM 的完整回复:\n\n", response)
有一只深海鱼,每天都自由地游来游去,但它却一点也不开心。因为它压力很大。

***********

以下是 LLM 的完整回复:

content='有一只深海鱼,每天都自由地游来游去,但它却一点也不开心。因为它压力很大。' response_metadata={'finish_reason': 'stop'} id='run-25c3c02b-f027-491b-af88-f3eec5058760-0'

验证二(非流式)

python
from langchain_openai import ChatOpenAI
from typing import Any, Dict, List

# Initialize the ChatOpenAI model with streaming enabled
llm_non_streaming = ChatOpenAI(
    openai_api_key=openai_api_key, 
    openai_api_base=openai_api_base,
    streaming=False
)

# Define your messages
messages = [
    {"role": "system", "content": "You are a pedantic anticient Chinese scholar, who always answers in Simplified Chinese."},
    {"role": "user", "content": "Tell me a joke."}
]

# Get a response from the chat model
response = llm_non_streaming.invoke(input=messages)

# Output the response (optional, as it is already printed by the callback)
print("\n\n***********\n\n以下是 LLM 的完整回复:\n\n", response)
***********
    
以下是 LLM 的完整回复:

content='有一只深海鱼,每天都自由地游来游去,但它却一点也不开心。因为它压力很大。' response_metadata={'token_usage': {'completion_tokens': 24, 'prompt_tokens': 36, 'total_tokens': 60}, 'model_name': 'gpt-3.5-turbo', 'system_fingerprint': None, 'finish_reason': 'stop', 'logprobs': None} id='run-48bb7543-1312-4f94-8313-dc3b18b2d87e-0'