AB
AiBoss
Tutorials

Watsonx.ai

Tutorials

用 Watsonx.ai 调用大模型完成推理:环境配置、参数设置与批量调用

面向需要把 IBM Watsonx.ai 上的大模型接入自己程序的开发者,讲清从安装 langchain-ibm、配置 API 密钥与服务地址,到初始化 WatsonxLLM、设定解码参数、用 PromptTemplate 组链,以及单条与批量调用模型的完整流程,并列出容易踩坑的配置项。

Watsonx.ai 是 IBM 提供的大模型推理平台,开发者可以在上面选择平台托管的模型,通过 API 把生成能力接进自己的程序。它适合已经有一个 Watsonx.ai 项目、需要在自己的 Python 代码里调用模型做文本生成的开发者。这篇教程用 LangChain 的 IBM 集成包 langchain-ibm 作为调用入口,把「装包 → 配环境变量 → 初始化模型对象 → 组提示词链 → 单条与批量调用」这条链路完整走一遍。如果你只是想先了解这个平台在站内的定位,可以看 Watsonx.ai 的工具条目,再回到本文动手配置。

准备工作

开始之前需要确认三件事:运行环境、账号凭据、以及要调用的模型与项目标识。

运行环境

示例代码是 Python,依赖 langchain-ibm 包。在 Notebook 环境里可以直接用 pip 安装:

!pip install -qU langchain-ibm

在普通终端或虚拟环境里则去掉感叹号:

pip install -qU langchain-ibm

安装完成后,代码里会用到两个包路径:langchain_ibm 提供 WatsonxLLM 类,langchain_core.prompts 提供 PromptTemplate。两者都随上述依赖一起就位,不需要额外单独安装。

账号与凭据

调用 Watsonx.ai 需要 IBM Cloud 的用户 API 密钥。这个密钥不要写死在源码里,示例用 getpass 在运行时交互输入,避免密钥落进代码仓库或 Notebook 的输出里:

import os
from getpass import getpass

watsonx_api_key = getpass()
os.environ["WATSONX_APIKEY"] = watsonx_api_key

除了 API 密钥,还需要准备服务实例地址与项目标识:

  • 服务实例 URL:对应环境变量 WATSONX_URL,填你的服务实例地址。
  • 项目 ID:初始化模型对象时通过 project_id 传入,填你在 Watsonx.ai 中创建的项目标识。
  • 模型 ID:通过 model_id 传入,示例使用的是 ibm/granite-13b-instruct-v2。平台上可用的模型清单会变化,实际可选范围以官网当前信息为准。

Cloud Pak for Data 场景的额外变量

如果你访问的不是公有云上的服务实例,而是自建的 Cloud Pak for Data(CPD)集群,那么除了 API 密钥之外,还需要一组集群访问凭据。示例中列出了这些环境变量:

os.environ["WATSONX_URL"] = "your service instance url"
os.environ["WATSONX_TOKEN"] = "your token for accessing the CPD cluster"
os.environ["WATSONX_PASSWORD"] = "your password for accessing the CPD cluster"
os.environ["WATSONX_USERNAME"] = "your username for accessing the CPD cluster"
os.environ["WATSONX_INSTANCE_ID"] = "your instance_id for accessing the CPD cluster"

这五个变量分别对应服务地址、访问令牌、密码、用户名和实例 ID。它们不是每个场景都要全部填写:走公有云 API 密钥认证时,核心是 WATSONX_APIKEY 与 WATSONX_URL;走 CPD 集群时,才需要令牌、用户名、密码、实例 ID 这一组。把用不到的变量留空或填占位符,比填错值更容易排查问题。

操作步骤

第一步:设置环境变量

把凭据写进环境变量,而不是散落在各个函数调用里。这样做的好处是:初始化模型对象时不必重复传参,切换环境时只改一处。示例的写法是先用 getpass() 拿到密钥,再赋值给 os.environ["WATSONX_APIKEY"],随后设置 WATSONX_URL 等服务地址。

需要提醒的是,示例里 WATSONX_URL 的值写的是占位文本 "your service instance url",直接照抄运行会连不上服务。请替换成你自己的实例地址。

第二步:定义模型参数

模型的行为由一组解码参数控制。示例给出的参数集合如下:

parameters = {
    "decoding_method": "sample",
    "max_new_tokens": 100,
    "min_new_tokens": 1,
    "temperature": 0.5,
    "top_k": 50,
    "top_p": 1,
}

逐项说明它们的含义:

  • decoding_method:解码方式,示例取 sample,即采样生成,输出带有随机性。
  • max_new_tokens:生成内容的最大 token 数,示例为 100。这个值直接决定回答能有多长,设得太小会在句子中途被截断。
  • min_new_tokens:生成内容的最小 token 数,示例为 1。
  • temperature:采样温度,示例为 0.5。数值越高输出越发散,越低越保守。
  • top_k:每步从概率最高的 k 个候选 token 中采样,示例为 50。
  • top_p:核采样阈值,示例为 1,表示不按累积概率裁剪候选集。

这些参数的具体取值范围与默认值随模型而异,调参前请以官网当前信息为准。示例中的组合是一个可以直接跑通的起点,不是针对某类任务的最优配置。

第三步:初始化 WatsonxLLM

参数准备好之后,构造 WatsonxLLM 实例,把模型 ID、服务地址、项目 ID 和参数一起传进去:

from langchain_ibm import WatsonxLLM

watsonx_llm = WatsonxLLM(
    model_id="ibm/granite-13b-instruct-v2",
    url="",  # 使用 API 代理服务提高访问稳定性
    project_id="PASTE YOUR PROJECT_ID HERE",
    params=parameters,
)

这里有三个地方必须替换:model_id 换成你要用的模型,project_id 换成你的项目标识,url 换成你的服务实例地址。示例中 url 留空并注释为「使用 API 代理服务提高访问稳定性」,意思是当直连服务实例不稳定时,可以在这里填代理地址;如果你能直连,就填实例地址本身。

如果前面已经把 WATSONX_APIKEY 等环境变量设置好,这里就不必再显式传密钥,客户端会从环境变量读取。

第四步:用 PromptTemplate 组装调用链

LangChain 的写法是把提示词模板和模型对象用管道符串起来,形成一个可复用的链:

from langchain_core.prompts import PromptTemplate

template = "Generate a random question about {topic}: Question: "
prompt = PromptTemplate.from_template(template)
llm_chain = prompt | watsonx_llm

topic = "dog"
llm_chain.invoke(topic)

模板里的 {topic} 是占位符,invoke(topic) 时把实际值填进去。这样同一个链可以反复用于不同主题,不必每次重写提示词。模板末尾的 Question: 是给模型的格式提示,让它按「问题」的形式续写。

第五步:直接调用模型

如果不需要模板,也可以跳过链,直接对模型对象调用 invoke,传入一段完整提示:

response = watsonx_llm.invoke("Who is man's best friend?")
print(response)

返回值是模型生成的文本,可以直接打印或继续处理。

第六步:批量调用

一次提交多条提示时用 generate,传入提示词列表:

responses = watsonx_llm.generate([
    "The fastest dog in the world?",
    "Describe your chosen dog breed",
])

for response in responses.generations:
    print(response[0].text)

注意返回结构:responses.generations 是一个与输入提示一一对应的列表,每个元素本身又是一个列表,所以要取 response[0].text 才能拿到该条提示的生成文本。批量调用适合一次处理多条互不依赖的提示,比循环调用 invoke 更省事。

一个完整示例

把上面的步骤串起来,下面是一个从头到尾可以跑通的最小脚本。运行前请替换 WATSONX_URL 与 project_id 两处占位值:

import os
from getpass import getpass

from langchain_ibm import WatsonxLLM
from langchain_core.prompts import PromptTemplate

# 1. 凭据与环境
os.environ["WATSONX_APIKEY"] = getpass()
os.environ["WATSONX_URL"] = "your service instance url"

# 2. 模型参数
parameters = {
    "decoding_method": "sample",
    "max_new_tokens": 100,
    "min_new_tokens": 1,
    "temperature": 0.5,
    "top_k": 50,
    "top_p": 1,
}

# 3. 初始化模型
watsonx_llm = WatsonxLLM(
    model_id="ibm/granite-13b-instruct-v2",
    url="",
    project_id="PASTE YOUR PROJECT_ID HERE",
    params=parameters,
)

# 4. 模板 + 链
prompt = PromptTemplate.from_template(
    "Generate a random question about {topic}: Question: "
)
llm_chain = prompt | watsonx_llm
print(llm_chain.invoke("dog"))

# 5. 直接调用
print(watsonx_llm.invoke("Who is man's best friend?"))

# 6. 批量调用
responses = watsonx_llm.generate([
    "The fastest dog in the world?",
    "Describe your chosen dog breed",
])
for response in responses.generations:
    print(response[0].text)

这段脚本依次演示了三种调用方式:通过链调用、单条直接调用、批量调用。如果第 4 步能正常输出,说明凭据、地址、项目 ID 和模型 ID 都配置正确,后面两步通常不会再有配置层面的问题。

注意事项

网络访问不稳定

部分地区的开发者可能遇到访问 Watsonx.ai 服务不稳定的情况。示例在初始化 WatsonxLLM 时把 url 留空并注释为「使用 API 代理服务提高访问稳定性」,就是为这种情况预留的位置。如果直连频繁超时,可以在 url 中填入代理地址;如果直连正常,填实例地址即可。

配置错误是最常见的失败原因

调用失败时,优先检查环境变量和 API 密钥是否配置正确。具体要核对:

  • WATSONX_APIKEY 是否真的被赋值,而不是空字符串。
  • WATSONX_URL 是否还是占位文本 "your service instance url"。
  • project_id 是否还是 "PASTE YOUR PROJECT_ID HERE"。
  • model_id 是否在当前项目可用的模型范围内。
  • 走 CPD 集群时,令牌、用户名、密码、实例 ID 是否齐全且相互匹配。

这些占位符原样保留是新手最容易犯的错:代码不报语法错误,但请求发出去就会被拒。

生成长度受 max_new_tokens 限制

示例把 max_new_tokens 设为 100,生成的回答会比较短。需要更长的输出时调大这个值,但要注意它会影响单次请求的耗时与资源消耗。具体上限与计费口径以官网当前信息为准。

采样参数影响可复现性

decoding_method 取 sample 时,同样的提示多次调用可能得到不同结果,这是采样解码的正常表现。如果任务需要稳定输出,应调整解码方式与温度等参数,而不是反复重试期待固定结果。

密钥不要写进代码

示例用 getpass() 交互输入密钥,就是为了避免密钥出现在源码、Notebook 输出或版本历史里。把密钥硬编码进脚本再提交到仓库,是凭据泄露的常见途径。

模型与参数以官网为准

可用的模型清单、各参数的取值范围与默认值、配额与计费方式都可能调整。本文示例中的模型 ID 与参数组合只是演示调用流程,实际使用前请核对官网当前信息。