MetaStone AI 近期发布了 XBai-o4 ,这是一款开源推理模型,引入了并行测试时扩展和反思式生成架构。XBai o4 具有 328 亿参数,并集成自评估头,可在本地运行的同时,在核心数学推理基准上优于 OpenAI 的 o3-mini(中等模式)。
本文将重点介绍 XBai o4 独特的反思式推理能力,演示它如何通过由 LM Studio 驱动的本地部署 Streamlit 界面,为数学问题生成并评估多条解题轨迹。
在本教程中,我将逐步讲解如何:
使用 LM Studio 和 GGUF 量化在本地部署 XBai-o4,以获得最佳性能。
构建一个 Streamlit 应用,用于实时可视化分支式逐步推理。
试验测试时扩展、动态温度控制和奖励模型评分。
分析并比较不同推理策略和设置如何影响解的质量与效率。
最后,您的应用将如下所示:
什么是 XBai-o4?
XBai-o4 是 MetaStone AI 的第四代开源推理模型,引入了反思式生成架构,力图重新定义 AI 处理复杂问题求解的方式。不同于将答案生成与答案评估视为两种独立过程的传统大模型,XBai o4 通过共享过程奖励模型(Shared Process Reward Model,SPRM)将两者融合为一个统一模型。该设计使模型能够并行生成、打分并选择多条推理路径。
来源: SPRM Head
从本质上说,XBai o4 将 长链式思维(Long-CoT)强化学习 与 过程奖励学习 融合进一条训练流水线。以下是该模型的一些关键创新:
反思式生成架构: SPRM 头与主干模型共享,使生成与自评估能够在一次高效的前向过程中完成。
动态测试时扩展: 模型可在 2、8 或 32 分支推理模式间即时切换,根据您的用例在速度与准确率之间权衡。
统一的推理风格: 该模型擅长直接证明、反证法、归纳法、代数与可视化推理,并能处理广泛的数学与逻辑问题。
性能领先: 在 AIME24 基准上,XBai-o4 表现出色。即使在最低设置下,XBai o4 也能持平或超越 OpenAI o3-mini,同时显著降低计算开销。
来源: XBai-O4 文档
如何使用 LM Studio 在本地配置 XBai o4
您可以使用 LM Studio 在本地运行 XBai o4,它会在可用时自动利用您系统的 GPU 或 Apple Silicon(Metal/MLX)加速(无需手动设置)。为获得最佳性能与兼容性,建议使用该模型的 GGUF 量化版本。
为何使用 GGUF 量化版本?
GGUF(GPT-Generated Unified Format)标准通过降低模型权重精度,实现高效的本地推理。在本项目中,我们将使用广受欢迎的 Q3_K_S 量化变体,其在质量与内存占用之间达成了出色平衡。
最佳平衡:Q3_K_S 格式仅 14.39 GB,相比全精度模型几乎不损失质量,却能提供强劲的推理性能。
广泛兼容:GGUF 是当前本地运行量化大模型的通用标准,可在 Mac、Windows 与 Linux 上无缝使用。
资源高效:3 位量化 让大型模型在常见的 32 GB 内存环境中也能轻松运行。
稳定且快速:即便在并行、多轨迹负载下,该模型也能输出稳定、推理速度一致的结果。
下面我们通过分步流程,使用 LM Studio 配置量化 GGUF 模型,实现高效的本地推理。
步骤 1:安装 LM Studio
LM Studio 提供 GGUF 支持,并会根据您的硬件自动选择最优推理后端,无论是 Metal、GPU,还是 CPU。
如果您尚未安装 LM Studio,请从 lmstudio.ai 下载并按说明安装。
步骤 2:下载 XBai-o4 GGUF 模型
在 LM Studio 中:
进入 Search 选项卡
搜索 mradermacher/XBai-o4-GGUF
下载 XBai-o4.Q3_K_S.gguf 变体(14.39 GB)。
步骤 3:加载并配置模型
安装好 LM Studio 后,加载并配置 XBai o4 模型以进行本地推理:
打开 LM Studio,前往 Local Server 选项卡(在 Mac 顶部栏)。
从已下载模型列表中选择并加载 XBai-o4.Q3_K_S.gguf 模型。
设置以下配置选项:
上下文长度:8192
温度:0.7(稍后在演示中将动态调整)
最大生成 Token:1024
GPU 层数:自动检测(LM Studio 将根据您的硬件能力自动优化)
启动本地服务器,默认运行在 http://localhost:1234。
运行后,您的系统即可使用 XBai o4 进行多轨迹推理。
演示:交互式 XBai-o4 反思式推理
接下来我们将构建一个 Streamlit 应用,实时展示 XBai o4 的反思式推理能力并进行性能对比。
步骤 1:安装依赖
首先安装依赖:
pip install streamlit plotly pandas numpy requests技术支持
该命令确保您具备用于界面、数据处理、绘图与 API 请求的核心依赖。
步骤 2:导入库并设置页面
然后导入所需库,并配置您的 Streamlit 页面布局与基础设置。
import streamlit as st
import time
import requests
import numpy as np
import pandas as pd
import plotly. express as px
from typing import List, Dict, Any
LM_STUDIO_URL = "http://localhost:1234/v1"
REASONING_MODES = { "Low (k=2)" : 2 , "Medium (k=8)" : 8 , "High (k=32)" : 8 }
st. set_page_config( page_title= "MetaStone-XBai-o4 Reflective Reasoning Demo" , layout= "wide" )
st. markdown( """
<style>
.main-header {
background: linear-gradient(90deg, #1e3c72 0%, #2a5298 100%);
border-radius: 10px;
color: white;
text-align: center;
}
</style>
""" , unsafe_allow_html= True ) 技术支持
该代码块导入了演示所需的核心库,包括用于 Web 界面的 Streamlit,以及 time、requests、numpy、pandas、plotly.express 和类型标注等基础库。
随后设置模型 API 端点 LM_STUDIO_URL,使应用知道请求发送位置,并定义推理模式(REASONING_MODES),便于用户选择要生成的解题分支数量。
最后,我们使用 st.set_page_config() 配置 Streamlit 界面,包括自定义标题、宽屏布局和带渐变样式的 CSS 头部。
注意:LM_STUDIO_URL 是 LLM 服务器的基础 URL,您可从 LM Studio 复制。通常为 "http://localhost:1234/v1",但可能有所不同。同时,请根据服务器能力选择合适的推理模式。
步骤 3:辅助函数
现在,我们来构建一组辅助函数,驱动应用的核心“反思式推理”逻辑。这些函数可便捷地处理多条轨迹、选择最佳解,并为每个答案打分。
步骤 3.1:检查模型是否支持多轨迹采样
本步骤提供一个简单的辅助函数,自动检查我们的 LM Studio 服务器是否支持多轨迹采样。部分服务器支持 n 参数,允许在一次 API 调用中请求多份独立补全,从而显著加速流程。
def supports_n_param ( ) :
payload = {
"messages" : [ { "role" : "user" , "content" : "What is 1+1?" } ] ,
"max_tokens" : 80 ,
"temperature" : 0.1 ,
"n" : 2 ,
"stream" : False
}
try :
resp = requests. post( f" { LM_STUDIO_URL} /chat/completions" , json= payload, timeout= 120 )
if resp. status_code == 200 and len ( resp. json( ) . get( "choices" , [ ] ) ) == 2 :
return True
except Exception:
pass
return False 技术支持
该函数用于检测您的 LM Studio 服务器是否支持通过 n 参数在一次 API 调用中生成多个答案(“轨迹”)。它发送一个快速测试请求,若功能可用则返回 True,从而启用真正的“Best-of-N”采样,提升推理速度与可扩展性。
步骤 3.2:生成轨迹
在确认后端是否支持多轨迹采样后,下一步是针对给定问题生成多条推理路径。本节引入一组辅助函数:在可用时使用服务器端多样本采样,否则高效并行单次补全,确保应用依旧快速且可扩展。
def lm_studio_generate_multiple ( problem, k, temperature= 0.8 , seed= 2025 ) :
prompt = f"<think> { problem} \n</think>"
payload = {
"messages" : [ { "role" : "user" , "content" : prompt} ] ,
"max_tokens" : 196 ,
"temperature" : temperature,
"top_p" : 0.9 ,
"top_k" : 30 ,
"n" : k,
"stream" : False ,
"seed" : seed
}
start = time. time( )
resp = requests. post( f" { LM_STUDIO_URL} /chat/completions" , json= payload, timeout= 120 )
latency = time. time( ) - start
if resp. status_code == 200 :
result = resp. json( )
return [ {
"content" : choice[ "message" ] [ "content" ] . strip( ) ,
"latency" : latency / k,
"success" : True ,
} for choice in result. get( "choices" , [ ] ) ]
else :
raise RuntimeError( f"LM Studio error: { resp. status_code} : { resp. text} " )
def lm_studio_generate_single ( problem, temperature, seed= None ) :
prompt = f"<think> { problem} \n</think>"
payload = {
"messages" : [ { "role" : "user" , "content" : prompt} ] ,
"max_tokens" : 196 ,
"temperature" : temperature,
"top_p" : 0.9 ,
"top_k" : 30 ,
"stream" : False ,
"seed" : seed
}
start = time. time( )
resp = requests. post( f" { LM_STUDIO_URL} /chat/completions" , json= payload, timeout= 120 )
latency = time. time( ) - start
if resp. status_code == 200 :
content = resp. json( ) [ "choices" ] [ 0 ] [ "message" ] [ "content" ] . strip( )
return { "content" : content, "latency" : latency, "success" : True }
else :
return { "success" : False , "error" : f"HTTP { resp. status_code} : { resp. text} " , "latency" : latency}
def parallel_candidate_generation ( problem, k, progress_cb= None ) :
import concurrent. futures
temperatures = np. linspace( 0.1 , 1.0 , k)
results = [ ]
with concurrent. futures. ThreadPoolExecutor( max_workers= min ( 8 , k) ) as executor:
futures = [ ]
for i in range ( k) :
seed = 2025 + i * 31
futures. append( executor. submit( lm_studio_generate_single, problem, temperatures[ i] , seed) )
for i, future in enumerate ( concurrent. futures. as_completed( futures) ) :
res = future. result( )
res[ "trajectory_id" ] = i + 1
results. append( res)
if progress_cb:
progress_cb( i + 1 , k)
results. sort( key= lambda x: x. get( "trajectory_id" , 0 ) )
return results技术支持
每个函数在多轨迹流水线中的作用如下:
lm_studio_generate_multiple() 函数:当 LM Studio 服务器支持 n 参数时,该函数发送一次 API 请求,即可一次性生成 k 个多样化解法。这是最高效模式,实现真正的测试时扩展。
lm_studio_generate_single() 函数:若服务器不支持多样本采样,该函数作为回退方案,每次请求生成一个解题轨迹,同时支持不同温度与通过种子重现实验。
parallel_candidate_generation() 函数:为保证回退模式的性能,该工具并行触发多次 lm_studio_generate_single() 调用,每次采用不同采样温度,并汇总所有响应。即便无法进行真正的多样本采样,也能快速得到多样解法。
步骤 3.3:最佳轨迹
在生成多条推理路径后,我们需要一种结构化方式来识别最强解。本步骤引入评分与选择工具,模拟MetaStone 反思式推理论文 中的奖励建模(SPRM)技术。
def step_tokenize ( trajectory: str ) - > List[ str ] :
steps = [ step. strip( ) for step in trajectory. split( '.\n\n' ) if step. strip( ) ]
return steps
def dummy_sprm_score ( trajectory: str , problem: str ) - > float :
steps = step_tokenize( trajectory)
n = len ( steps)
def step_score ( step) :
s = 0.2
if any ( x in step. lower( ) for x in [ "therefore" , "thus" , "so" , "finally" , "conclude" ] ) : s += 0.15
if any ( sym in step for sym in [ "=" , "+" , "-" , "*" , "/" , "(" , ")" ] ) : s += 0.1
if len ( step. split( ) ) > 10 : s += 0.1
return min ( 1.0 , s)
step_scores = [ step_score( s) for s in steps] or [ 0.01 ]
geometric_mean = np. exp( np. mean( np. log( np. maximum( step_scores, 1e-3 ) ) ) )
return min ( 1.0 , geometric_mean + 0.05 * np. log1p( n) )
def best_of_n_selection ( candidates: List[ Dict] ) - > int :
best_idx = int ( np. argmax( [ c[ "sprm_score" ] for c in candidates] ) )
return best_idx技术支持
各函数的作用如下:
step_tokenize() 函数:将一条推理轨迹拆分为逻辑步骤或段落,便于逐步分析与评分。
dummy_sprm_score() 函数:为每个候选轨迹分配奖励分,鼓励多步骤、结构清晰且包含数学推理的回答。它充当论文中共享过程奖励模型(SPRM)的替代品,内部用于评估解答。
注意:该评分函数仅对原论文所述 SPRM 做近似。真正的 SPRM 是在大规模数据集上训练的学习型奖励模型,能提供细粒度的步骤级反馈,且需要大量资源与专有数据。
best_of_n_selection() 函数:针对一批候选答案,本函数基于最高 SPRM 分数选择单条最佳轨迹,类似论文中的反思式模型在测试时自动挑选最稳健的答案。
步骤 4:Streamlit 主应用流程
本步骤将各部分组合起来,借助 Streamlit 创建一个交互式推理演示。
st. markdown( """
<div class="main-header">
<h1> MetaStone XBai-o4 Reflective Reasoning Demo</h1>
</div>
""" , unsafe_allow_html= True )
st. sidebar. header( "Reasoning Mode" )
mode = st. sidebar. selectbox( "Reasoning effort (k candidates):" , list ( REASONING_MODES. keys( ) ) )
k = REASONING_MODES[ mode]
st. sidebar. header( "Problem Input" )
problem = st. sidebar. text_area( "Enter your math/logic problem:" , "Prove that the square root of 2 is irrational" )
if st. sidebar. button( "Run Reflective Reasoning" ) :
st. session_state. run = True
st. session_state. results = None
st. session_state. best_idx = None
if "run" not in st. session_state:
st. session_state. run = False
if st. session_state. run:
st. info( f"Generating { k} reasoning trajectories in parallel..." )
progress = st. progress( 0 )
def update_progress ( done, total) :
progress. progress( done / total)
try :
if supports_n_param( ) :
results = lm_studio_generate_multiple( problem, k, temperature= 0.7 )
for idx, res in enumerate ( results) :
res[ "trajectory_id" ] = idx + 1
else :
results = parallel_candidate_generation( problem, k, progress_cb= update_progress)
for res in results:
if res. get( "success" ) :
res[ "sprm_score" ] = dummy_sprm_score( res[ "content" ] , problem)
else :
res[ "sprm_score" ] = 0.0
best_idx = best_of_n_selection( results)
st. session_state. results = results
st. session_state. best_idx = best_idx
st. session_state. run = False
except Exception as e:
st. error( f"Failed to generate trajectories: { str ( e) } " )
st. session_state. run = False
if st. session_state. get( "results" ) :
results = st. session_state. results
best_idx = st. session_state. best_idx
st. success( f"Selected trajectory # { best_idx+ 1 } (highest SPRM score)" )
df = pd. DataFrame( {
"Trajectory" : [ f"T { i+ 1 } " for i in range ( len ( results) ) ] ,
"SPRM Score" : [ r[ "sprm_score" ] for r in results] ,
"Latency (s)" : [ r. get( "latency" , 0.0 ) for r in results] ,
"Success" : [ r. get( "success" , False ) for r in results]
} )
for i, res in enumerate ( results) :
is_best = ( i == best_idx)
st. markdown( f"### { '' if is_best else '' } Trajectory { i+ 1 } { '(SELECTED)' if is_best else '' } " )
if res. get( "success" ) :
st. info( f"SPRM Score: { res[ 'sprm_score' ] : .3f } | Latency: { res[ 'latency' ] : .1f } s" )
st. code( res[ "content" ] )
else :
st. error( f"Failed: { res. get( 'error' , 'Unknown error' ) } " )
fig = px. bar( df, x= "Trajectory" , y= "SPRM Score" , color= "Success" , title= "SPRM Scores for Each Trajectory" )
st. plotly_chart( fig, use_container_width= True )
st. dataframe( df) 技术支持
主应用流程实现了以下关键目标:
侧边栏配置: 侧边栏提供动态控件以设置 推理投入 (即每次查询采样的轨迹数),并允许用户提交自定义数学或逻辑问题。各模式(k=2、8、32)对应不同的测试时推理预算,使用户能够分析扩展对解的质量的影响。
执行触发: “ Run Reflective Reasoning ”按钮作为流水线入口,触发高效的服务器内多样本生成(n 参数),或在后端不支持时通过并发请求进行并行采样。
进度跟踪: 在生成轨迹时,进度条提供实时反馈,利用 Streamlit 的有状态响应能力。
后处理与评分: 完成后使用代理奖励模型(dummy_sprm_score)评估每条轨迹,模拟共享过程奖励模型(SPRM)。
选择与展示: 基于奖励分(best_of_n_selection)突出显示最佳轨迹。所有解及其对应的 SPRM 分数与生成时延均以文本与图形形式呈现,便于并排分析。
若您想亲自试用,将代码保存为 xbai_demo.py 并运行:
streamlit run xbai_demo.py技术支持
MetaStone AI 近期发布了XBai-o4,这是一款开源推理模型,引入了并行测试时扩展和反思式生成架构。XBai o4 具有 328 亿参数,并集成自评估头,可在本地运行的同时,在核心数学推理基准上优于 OpenAI 的 o3-mini(中等模式)。
本文将重点介绍 XBai o4 独特的反思式推理能力,演示它如何通过由 LM Studio 驱动的本地部署 Streamlit 界面,为数学问题生成并评估多条解题轨迹。
在本教程中,我将逐步讲解如何:
最后,您的应用将如下所示:
什么是 XBai-o4?
XBai-o4 是 MetaStone AI 的第四代开源推理模型,引入了反思式生成架构,力图重新定义 AI 处理复杂问题求解的方式。不同于将答案生成与答案评估视为两种独立过程的传统大模型,XBai o4 通过共享过程奖励模型(Shared Process Reward Model,SPRM)将两者融合为一个统一模型。该设计使模型能够并行生成、打分并选择多条推理路径。
来源:SPRM Head
从本质上说,XBai o4 将长链式思维(Long-CoT)强化学习与过程奖励学习融合进一条训练流水线。以下是该模型的一些关键创新:
来源:XBai-O4 文档
如何使用 LM Studio 在本地配置 XBai o4
您可以使用 LM Studio 在本地运行 XBai o4,它会在可用时自动利用您系统的 GPU 或 Apple Silicon(Metal/MLX)加速(无需手动设置)。为获得最佳性能与兼容性,建议使用该模型的 GGUF 量化版本。
为何使用 GGUF 量化版本?
GGUF(GPT-Generated Unified Format)标准通过降低模型权重精度,实现高效的本地推理。在本项目中,我们将使用广受欢迎的
Q3_K_S量化变体,其在质量与内存占用之间达成了出色平衡。Q3_K_S格式仅 14.39 GB,相比全精度模型几乎不损失质量,却能提供强劲的推理性能。下面我们通过分步流程,使用 LM Studio 配置量化 GGUF 模型,实现高效的本地推理。
步骤 1:安装 LM Studio
LM Studio 提供 GGUF 支持,并会根据您的硬件自动选择最优推理后端,无论是 Metal、GPU,还是 CPU。
如果您尚未安装 LM Studio,请从 lmstudio.ai 下载并按说明安装。
步骤 2:下载 XBai-o4 GGUF 模型
在 LM Studio 中:
mradermacher/XBai-o4-GGUFXBai-o4.Q3_K_S.gguf变体(14.39 GB)。步骤 3:加载并配置模型
安装好 LM Studio 后,加载并配置 XBai o4 模型以进行本地推理:
XBai-o4.Q3_K_S.gguf模型。运行后,您的系统即可使用 XBai o4 进行多轨迹推理。
演示:交互式 XBai-o4 反思式推理
接下来我们将构建一个 Streamlit 应用,实时展示 XBai o4 的反思式推理能力并进行性能对比。
步骤 1:安装依赖
首先安装依赖:
该命令确保您具备用于界面、数据处理、绘图与 API 请求的核心依赖。
步骤 2:导入库并设置页面
然后导入所需库,并配置您的 Streamlit 页面布局与基础设置。
该代码块导入了演示所需的核心库,包括用于 Web 界面的 Streamlit,以及 time、requests、numpy、pandas、plotly.express 和类型标注等基础库。
随后设置模型 API 端点
LM_STUDIO_URL,使应用知道请求发送位置,并定义推理模式(REASONING_MODES),便于用户选择要生成的解题分支数量。最后,我们使用
st.set_page_config()配置 Streamlit 界面,包括自定义标题、宽屏布局和带渐变样式的 CSS 头部。注意:
LM_STUDIO_URL是 LLM 服务器的基础 URL,您可从 LM Studio 复制。通常为 "http://localhost:1234/v1",但可能有所不同。同时,请根据服务器能力选择合适的推理模式。步骤 3:辅助函数
现在,我们来构建一组辅助函数,驱动应用的核心“反思式推理”逻辑。这些函数可便捷地处理多条轨迹、选择最佳解,并为每个答案打分。
步骤 3.1:检查模型是否支持多轨迹采样
本步骤提供一个简单的辅助函数,自动检查我们的 LM Studio 服务器是否支持多轨迹采样。部分服务器支持
n 参数,允许在一次 API 调用中请求多份独立补全,从而显著加速流程。该函数用于检测您的 LM Studio 服务器是否支持通过 n 参数在一次 API 调用中生成多个答案(“轨迹”)。它发送一个快速测试请求,若功能可用则返回 True,从而启用真正的“Best-of-N”采样,提升推理速度与可扩展性。
步骤 3.2:生成轨迹
在确认后端是否支持多轨迹采样后,下一步是针对给定问题生成多条推理路径。本节引入一组辅助函数:在可用时使用服务器端多样本采样,否则高效并行单次补全,确保应用依旧快速且可扩展。
每个函数在多轨迹流水线中的作用如下:
lm_studio_generate_multiple()函数:当 LM Studio 服务器支持 n 参数时,该函数发送一次 API 请求,即可一次性生成 k 个多样化解法。这是最高效模式,实现真正的测试时扩展。lm_studio_generate_single()函数:若服务器不支持多样本采样,该函数作为回退方案,每次请求生成一个解题轨迹,同时支持不同温度与通过种子重现实验。parallel_candidate_generation()函数:为保证回退模式的性能,该工具并行触发多次lm_studio_generate_single()调用,每次采用不同采样温度,并汇总所有响应。即便无法进行真正的多样本采样,也能快速得到多样解法。步骤 3.3:最佳轨迹
在生成多条推理路径后,我们需要一种结构化方式来识别最强解。本步骤引入评分与选择工具,模拟MetaStone 反思式推理论文中的奖励建模(SPRM)技术。
各函数的作用如下:
step_tokenize()函数:将一条推理轨迹拆分为逻辑步骤或段落,便于逐步分析与评分。dummy_sprm_score()函数:为每个候选轨迹分配奖励分,鼓励多步骤、结构清晰且包含数学推理的回答。它充当论文中共享过程奖励模型(SPRM)的替代品,内部用于评估解答。best_of_n_selection() 函数:针对一批候选答案,本函数基于最高 SPRM 分数选择单条最佳轨迹,类似论文中的反思式模型在测试时自动挑选最稳健的答案。步骤 4:Streamlit 主应用流程
本步骤将各部分组合起来,借助 Streamlit 创建一个交互式推理演示。
主应用流程实现了以下关键目标:
dummy_sprm_score)评估每条轨迹,模拟共享过程奖励模型(SPRM)。best_of_n_selection)突出显示最佳轨迹。所有解及其对应的 SPRM 分数与生成时延均以文本与图形形式呈现,便于并排分析。若您想亲自试用,将代码保存为
xbai_demo.py并运行: