欢迎 Muse Spark Open:Meta 发布开放权重的前沿多模态 MoE 模型
Muse Spark Open 是 Meta 推出的开放权重模型。该混合专家(Mixture of Experts, MoE)架构支持文本、图像、音频和视频输入,模型总参数量约 8160 亿,每个 token 激活约 420 亿参数,上下文窗口最大支持 100 万 tokens。该模型可生成文本,为开发者提供统一的接口来处理各类输入。
继 Muse Glimmer 之后,Muse Spark Open 在更大规模上引入了混合专家架构,是迄今能力最强的美国开放权重模型。
Meta 针对“代理式编程”(agentic coding)训练了 Muse Spark Open,使其具备读取代码库、编写与调试代码、调用工具的能力。由于该模型支持图像、音频和视频输入,它可以在处理代码时同时查看截图、收听语音留言或观看屏幕录屏。本文演示如何运行该模型、如何微调以及基于其构建的应用。所有模型文件见此处。
综合能力与架构
Meta 将 Muse Spark Open 定义为一个针对编码优化的模型,基于多文件重构、长时间调试会话等真实开发工作流进行训练。这是一个面向代理任务的模型,能够在长任务中执行规划、行动、观察及自我纠正,甚至支持带图像的网页浏览。
| 特性 | Muse Spark Open |
|---|---|
| 模型规模 | 总参数约 8160 亿;每个 token 激活约 420 亿 |
| 专家路由 | 每个 MoE 层含 256 个专家;每个 token 激活 8 个 |
| 输入类型 | 文本、图像、音频、视频 |
| 输出类型 | 文本 |
| 上下文窗口 | 最大 100 万 tokens |
| 检查点格式 | BF16 和 NVFP4 |
检查点仓库为 Muse-Spark-Open-816B-A42B 和 Muse-Spark-Open-816B-A42B-NVFP4。
Muse Spark Open 是 Muse 系列中的全尺寸模型。Meta 于八月份发布的 Muse Glimmer 则是同系列的小型稠密模型,非常适合本地运行。两者共用同一套 Tokenizer 和词表。对话模板沿袭了 Muse Glimmer 的设计,并针对新增模态进行了补充。在 Muse Spark Open 中,输入嵌入层和输出层是两块独立的矩阵,各自拥有约 1.66B 个参数。
专家混合机制(Mixture of Experts)
该语言模型包含 62 层,隐藏层维度为 8192。每一层配备 128 个 Query 头和 16 个 Key-Value 头(采用分组查询注意力 Grouped-Query Attention),每个头维度为 64。注意力模块包含输出门控和输出归一化层。模型同时对 Query 和 Key 应用归一化(QK-norm)。每个 Block 通过可学习的残差门控(learned residual gate)而非简单的加法来组合输入与输出。
Muse Glimmer 在每一层使用单一的稠密前馈网络(Feed-Forward Network)。Muse Spark Open 则用专家混合(Mixture-of-Experts, MoE)模块取代了这一稠密网络。每个 MoE 模块包含 256 个专家,路由器为每个 Token 动态选择其中的 8 个。每个专家是一个前馈网络,将维度从 8192 投影至 4096 再映射回 8192,随后对其输出应用专属归一化。专家模块承载了模型总参数量的约 97%。
由于每个 Token 仅激活 8 个专家,模型实际计算每个 Token 时约使用 42B 参数。尽管全部 256 个专家都需驻留内存,部署所需的显存相当于一个 816B 参数的模型,但运行速度却能达到 42B 模型的极高速度。BF16 检查点在 Safetensors 格式下体积约为 1.5 TB。NVFP4 检查点以 4-bit 精度存储参数,精度损失微乎其微,专为 NVIDIA Blackwell GPU 设计。使用 Transformers 框架时,BF16 检查点需在 4 节点共 32 张 H200 GPU 上以张量并行(TP=32)运行,而 NVFP4 检查点仅需单节点 B200 即可支持。如需部署 Muse Spark Open,请参阅下文提供的 llama.cpp、vLLM 和 SGLang 配置方案。
感知编码器(Perception Encoder)
感知编码器(perception encoder)负责把图像和视频帧转换成 token,供语言模型使用,这一点与 Muse Glimmer 相同。该编码器有 1.8B 参数、50 层、隐藏维度 1536、16 个注意力头。每张图像被切分成 14×14 的 patch,输出 4096 维特征。位置信息来自可学习的绝对位置嵌入和 2D RoPE。每层的前馈网络使用 LayerNorm 和 GELU。每四层中的第一层以及最后一层使用全注意力,其余层使用稀疏注意力。
Muse Glimmer 30B 使用的编码器采用同样的架构,设计源自 Meta 的 Perception Encoder 工作。视频输入与图像共用同一个编码器。
音频编码器
Muse Spark Open 通过音频编码器接收音频输入。音频分词器将音频转换成 token,聊天模板用 <|audio|> token 标记音频的位置。编码器每 80 毫秒输出一个音频 token,即每秒 12.5 个。也就是说,一段 10 秒的音频会产生 125 个输入音频 token。
编码器本身是一个卷积金字塔:每个阶段由一个不同 patch 大小的 patch 嵌入器和两个一维卷积块(卷积核大小为 7、步长为 1)组成。这些阶段依次处理 [16, 6, 5, 4] 的 patch 大小。最后一个阶段结束后,时间帧会经过一个由 RMSNorm → 线性投影 → RMSNorm 组成的最终模块。
长上下文
推理时的上下文窗口为 1M token,配置中 max_position_embeddings 设为 1,048,576。图像、视频和音频 token 与文本共享同一个窗口。
分组查询注意力机制(Grouped-Query Attention)有效控制了该规模模型的KV缓存体积。每个Token会增加 2 × 16 个头 × 64 维 × 62 层 = 126,976 个值至缓存。在BF16精度下,这相当于每个Token约 250 KB,处理完整的 100 万 Token上下文则需约 266 GB。
推理支持
Transformers
Muse Spark Open 实现提供了 MuseSparkForConditionalGeneration,用于处理多模态输入的文本生成任务,并提供 MuseSparkProcessor 用于准备对话数据。该处理器集成了分词器、图像和视频处理器、音频特征提取器及聊天模板。
使用 DistributedConfig 配置并行设置。tp_size 指定稠密层进行分片所使用的设备数量,ep_size 指定专家进行分布所使用的设备数量。
以下是初始化模型和处理器的方式。
import os
from transformers import AutoModelForMultimodalLM, AutoTokenizer, DistributedConfig
distributed_config = DistributedConfig(
tp_size=int(os.environ["WORLD_SIZE"]),
ep_size=int(os.environ["WORLD_SIZE"]),
)
tokenizer = AutoTokenizer.from_pretrained("meta-models/Muse-Spark-Open-816B-A42B
")
model = AutoModelForMultimodalLM.from_pretrained(
"meta-models/Muse-Spark-Open-816B-A42B",
distributed_config=distributed_config,
)
messages = [
{"role": "user", "content": "Explain in one sentence why the sky is usually blue."},
]
inputs = tokenizer.apply_chat_template(
messages,
reasoning_effort="medium", # default: xhigh, options: low/medium/high/xhigh
add_generation_prompt=True,
tokenize=True,
return_dict=True,
return_tensors="pt",
).to(model.device).to(model.dtype)
input_len = inputs["input_ids"].shape[-1]
outputs = model.generate(**inputs, max_new_tokens=2000)
纯文本推理
先构建对话,再将消息传入 processor.apply_chat_template,并启用 add_generation_prompt=True、tokenize=True、return_dict=True 和 return_tensors="pt"。将处理器的输出传给 model.generate,解码新生成的 token,并排除输入前缀部分。该处理器提供了一个调节推理强度的开关,将符号级别(low/medium/high/xhigh)映射为模型接受的整数(16, 64, 256, 512)。需要注意的是,Muse Spark Open 无法完全关闭推理功能,因此如果任务较简单且希望消耗更少的 token,建议将推理强度设为“low”。你也可以通过在系统提示词中加入类似 Reasoning strength: 1 的行来设置数值化的推理强度。
messages = [
{"role": "system", "content": "You should only answer with a number."},
{"role": "user", "content": "What is 17 * 23?"},
]
inputs = processor.apply_chat_template(
messages,
add_generation_prompt=True,
tokenize=True,
return_dict=True,
return_tensors="pt",
reasoning_effort="high", # options:low/medium/high/xhigh
).to(model.device).to(model.dtype)
output = model.generate(**inputs, max_new_tokens=2000)
generated_tokens = output[0][inputs["input_ids"].shape[1] :]
print(processor.decode(generated_tokens, skip_special_tokens=False))
图像与文本
Muse Spark Open 的处理器会将每个图像标记扩展为处理后图像所需的 patch token 数量,并用图像边界 token 包裹。这种扩展方式确保了文本位置与传入模型的视觉特征保持一致。该处理器还能处理单个提示词中的多张图像。
image_url = (
"https://huggingface.co/datasets/merve/vl-test-suite/"
"resolve/main/pills.jpg"
)
messages = [
{
"role": "user",
"content": [
{
"type": "image",
"image": image_url,
},
{
"type": "text",
"text": "Do any of the components in this supplement interact?",
},
],
},
]
inputs = processor.apply_chat_template(
messages,
tokenize=True,
add_generation_prompt=True,
reasoning_effort="medium",
return_dict=True,
return_tensors="pt",
).to(model.device).to(model.dtype)
input_len = inputs["input_ids"].shape[-1]
outputs = model.generate(**inputs, max_new_tokens=2000)
response = processor.decode(outputs[0][input_len:], skip_special_tokens=False)
processor.parse_response(response)
视频推理
视频 prompt 除了画面内容外还包含时间信息。processor 可以处理带音频的视频(相比 Muse Glimmer 是一个升级,得益于其中的音频编码器)。processor 会对视频帧和音频做下采样,使二者对齐。默认按 2 FPS 采样,最多 96 帧。可以通过设置 video processor 的 fps 来调整:
processor.video_processor.fps = 4.0
一般经验是:视频本质上是时间上连续的帧,下采样越狠,特定事件之间的帧丢失就越多,所以想要更准确的输出就要保持较高的 fps。但这也有代价——内存占用更高,prefill 延迟也会增加。帧会与标注时间戳的文本输入交错(如 "Time: 3.5s")。要传入带音频的视频,需给 apply_chat_template 传 load_audio_from_video=True。
在准备输入时用 return_metadata=True 保留视频的元数据,这样 processor 才能分配正确的帧率。
import torch
messages = [
{
"role": "user",
"content": [
{
"type": "text",
"text": (
"Describe what happens in this video. "
"Use timestamps and include relevant speech or sounds."
),
},
{
"type": "video",
"url": "https://huggingface.co/datasets/merve/vlm_test_images/resolve/main/ramen.mp4"
},
],
}
]
inputs = processor.apply_chat_template(
messages,
add_generation_prompt=True,
tokenize=True,
return_dict=True,
return_tensors="pt",
load_audio_from_video=True,
return_metadata=True,
).to(model.device).to(model.dtype)
with torch.inference_mode():
output_ids = model.generate(
**inputs,
max_new_tokens=256,
do_sample=False,
)
generated_ids = output_ids[:, inputs["input_ids"].shape[1] :]
response = processor.batch_decode(
generated_ids,
skip_special_tokens=True,
)[0]
print(response)
音频推理
Muse Spark Open 的音频塔直接接收原始波形。processor 要求输入为 24 kHz 的单声道音频,并将波形填充到 1,920 个采样点的整数倍,即每 80 毫秒对应一个音频 embedding。如果直接传给 processor 的音频采样率不同,需要先重采样,可以用 transformers 提供的 load_audio 工具来完成。load_audio 依赖 torchcodec、librosa 或 torchaudio 后端,运行推理前请确保本地至少安装了其中之一。
如果你只是想配合消息列表直接使用 apply_chat_template,那么这些处理都会在底层自动完成:
import torch
from transformers import AutoProcessor, AutoModelForMultimodalLM
model_id = "meta-models/Muse-Spark-Open-816B-A42B"
processor = AutoProcessor.from_pretrained(model_id)
model = AutoModelForMultimodalLM.from_pretrained(model_id).eval()
messages = [
{
"role": "user",
"content": [
{
"type": "audio",
"url": "https://huggingface.co/buckets/huggingface/audio-samples/resolve/bbaudio_question_39.mp3",
},
{
"type": "text",
"text": "Answer the question.",
},
],
}
]
# 下载音频、解码为单声道、重采样到 24 kHz、填充,生成 input_values_mask,并展开音频占位符。
inputs = processor.apply_chat_template(
messages,
add_generation_prompt=True,
tokenize=True,
return_dict=True,
return_tensors="pt",
load_audio_backend="auto",
).to(model.device).to(model.dtype)
with torch.inference_mode():
output_ids = model.generate(
**inputs,
max_new_tokens=128,
do_sample=False,
)
# 只解码新生成的 token
prompt_length = inputs["input_ids"].shape[1]
generated_text = processor.batch_decode(
output_ids[:, prompt_length:],
skip_special_tokens=True,
)
print(generated_text[0])
processor 会在音频边界标记之间插入数量匹配的音频 token,同时返回一个掩码来标识真实采样点,让模型能够排除被填充的音频 embedding。
工具调用
Muse Spark Open 支持纯文本和多模态两种工具调用。可以按如下方式让模型调用工具。
from transformers import AutoProcessor, AutoModelForMultimodalLM
MODEL_ID = "meta-models/Muse-Spark-Open-816B-A42B"
# Load model
processor = AutoProcessor.from_pretrained(MODEL_ID)
model = AutoModelForMultimodalLM.from_pretrained(
MODEL_ID,
dtype="auto",
device_map="auto"
)
tools = [
{
"type": "function",
"function": {
"name": "weather.get",
"description": "Get the current weather for a city.",
"parameters": {
"type": "object",
"properties": {
"city": {"type": "string"},
},
"required": ["city"],
},
},
}
]
messages = [
{
"role": "user",
"content": [
{"type": "image", "image": "https://huggingface.co/datasets/merve/vl-test-suite/resolve/main/SF.png"},
{"type": "text", "text": "I'm going to the city in this picture. What clothes should I wear?"},
],
},
]
inputs = processor.apply_chat_template(
messages,
tools=tools,
tokenize=True,
return_dict=True,
return_tensors="pt",
add_generation_prompt=True,
reasoning_strength="high"
).to(model.device).to(model.dtype)
input_len = inputs["input_ids"].shape[-1]
outputs = model.generate(**inputs)
response = processor.parse_response(
completion,
prefix=inputs["input_ids"][0],
tools=tools,
)
print(response)
Muse Spark Open 使用基于通道(channel)的聊天模板(Harmony,最早由 gpt-oss 引入)。你不必了解其内部机制,但了解模型路由到的通道会很有帮助,尤其是在输出质量不佳时方便排查。以下面的输入消息为例:
<|begin_of_text|>
<|start|>system<|message|>
You are a helpful AI assistant.
Knowledge cutoff: 2026-01-04.
Current date: ...
...
<|eot|>
<|start|>user<|message|>...
<|eot|>
<|start|>assistant
<|start|>assistant 是刻意留空的,由模型通过 to= 来选择接收方。模型有不同的接收方,例如 self 表示让模型进行推理:
to=self<|message|>the model reasons here<|eom|> # reasoning
<|start|>assistant to=user<|message|>final answer<|eot|> # final answer
self 用于推理,commentary 是工具调用前和调用之间对最终用户可见的评论,user 是最终回复。
工具调用的路由解析格式如下(假设你已经把 tools 传给了 apply_chat_template):
<|start|>assistant to=weather.get<|message|>
<atem:function_calls>
<atem:invoke name="weather.get">
<atem:parameter name="city">San Francisco</atem:parameter>
</atem:invoke>
</atem:function_calls>
<|eot|>
Llama.cpp
2-bit 量化的 Muse Spark 运行在 Llama Server 上
Muse Spark Open 已集成到 llama.cpp 中,随预编译二进制文件一起发布。可以用以下命令安装:
curl -LsSf https://llama.app/install.sh | sh
启动服务时,在模型 ID 后面加上量化后缀即可:
llama serve -hf ggml-org/Muse-Spark-Open-816B-A42B-GGUF:Q2_K
包含各量化版本的仓库在这里。服务启动后,访问 localhost:9931 即可通过内置 WebUI 对话。在 WebUI 中可以添加音频和图片进行推理,还能调节推理强度。
注意 Muse Spark Open 无法完全关闭推理,如果想让模型在简单任务上少消耗一些 token,把推理强度调到“low”即可。
我们在 Mac M3 Ultra(512GB)上测试了量化版本:经 imatrix 校准的 2-bit 量化可以达到 18 tokens/s,且还有充足内存留给 KV cache(模型占用 304 GB)。
你也可以按如下方式请求服务。多模态、工具调用等更多用法请查阅API 文档。
## 纯文本推理
curl http://localhost:8080/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"messages": [
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "Write a limerick about python exceptions"}
]
}'
## 图文推理
curl -s http://127.0.0.1:8080/v1/chat/completions \
-H "Content-Type: application/json" -H "Authorization: Bearer <your-key>" \
-d '{"model":"muse-spark-open","messages":[{"role":"user","content":[
{"type":"text","text":"What is in this image?"},
{"type":"image_url","image_url":{"url":"data:image/png;base64,..."}}
]}],"temperature":0}'
## 音频推理
curl -s http://127.0.0.1:8080/v1/chat/completions \
-H "Content-Type: application/json" -H "Authorization: Bearer <your-key>" \
-d '{"model":"muse-spark-open","messages":[{"role":"user","content":[
{"type":"text","text":"Transcribe this audio."},
{"type":"input_audio","input_audio":{"data":"data:audio/wav;base64,..."}}
]}],"temperature":0}'
llama.cpp 团队提供了多种量化版本。我们在 Apple Silicon 芯片上测试了 Q2_K、Q4_K_S 和 Q_8。运行某个量化版本时,只需在命令后加上对应的量化 ID 作为后缀,例如 llama serve -hf ggml-org/Muse-Spark-Open-816B-A42B:Q2_K。
SGLang
SGLang 对 Muse Spark Open 的集成支持文本、图像、音频和视频输入。NVFP4 参考配置可在四块 GB300 GPU 上运行。
在 SGLang 集成环境中,从 Hugging Face Hub 下载 checkpoint 并启动服务器:
export MODEL_ID=meta-models/Muse-Spark-Open-816B-A42B-NVFP4
export CKPT="$(hf download "$MODEL_ID")"
SGLANG_FLASHINFER_NVFP4_PER_TOKEN_ACTIVATION=1 \
uv run sglang_meta serve \
--model-path "$CKPT" \
--served-model-name "$MODEL_ID" \
--quantization modelopt_fp4 \
--moe-runner-backend flashinfer_trtllm \
--tp-size 4 \
--ep-size 4 \
--port 30000
该 checkpoint 包含聊天模板,启动时会显式传入。启动器还会配置 Muse 的推理和工具调用解析器。
通过 OpenAI 兼容 API 发送请求:
curl http://localhost:30000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "meta-models/Muse-Spark-Open-816B-A42B-NVFP4",
"messages": [{
"role": "user",
"content": "Explain how a mixture-of-experts model works."
}],
"max_tokens": 2048
}'
返回结果中,推理过程会单独放在 reasoning_content 字段,与 content 中的最终答案分开。
vLLM
Muse Spark Open 官方提供的 vLLM 集成支持文本和图像输入,使用 NVFP4 检查点时需要 Blackwell 系列 GPU。
安装参考插件及其依赖后,从 Hugging Face Hub 下载检查点并启动服务:
export MODEL_ID=meta-models/Muse-Spark-Open-816B-A42B-NVFP4
export CKPT="$(hf download "$MODEL_ID")"
VLLM_ALLOW_LONG_MAX_MODEL_LEN=1 \
VLLM_PLUGINS=musespark1x_models,ptq_nvfp4 \
vllm serve "$CKPT" \
--served-model-name "$MODEL_ID" \
--tokenizer-mode musespark1x \
--config-format auto \
--load-format internal_safetensor \
--tensor-parallel-size 4 \
--enable-expert-parallel \
--max-model-len 131072 \
--gpu-memory-utilization 0.92 \
--reasoning-parser musespark1x \
--tool-call-parser musespark1x \
--enable-auto-tool-choice \
--port 8000
该配置提供服务时使用 128K token 的上下文长度。插件负责提供模型实现、检查点加载器,以及推理和工具调用解析器。
使用相同的 Hub 模型 ID 发送请求:
curl http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "meta-models/Muse-Spark-Open-816B-A42B-NVFP4",
"messages": [{
"role": "user",
"content": "Explain how a mixture-of-experts model works."
}],
"max_tokens": 2048
}'
MLX
Muse Spark Open 现已支持 oMLX 和 mlx-lm。针对 oMLX 优化的 oQ 量化版本有 3-bit 和 4-bit 可选,下载即用。
我们在一台 M3 Ultra(512 GB)上测试了 oQ3e 量化版本。模型约占 344 GB,还留有 KV cache 的空间。在 1024 token 的提示词、生成 128 token 的条件下,prefill 速度约为 225 tok/s,生成速度约为 21 tok/s。
通过 oMLX 界面下载模型后,就可以在内置的聊天 UI 中直接对话。聊天界面支持添加图片,还能实时调整推理力度(从 low 到 xhigh)。模型的推理过程会以一个可折叠的思考块形式呈现,与最终答案分开。
注意:推理无法关闭,默认模式(Auto)使用的是 xhigh。如果想在一些简单任务上少消耗 token,可以把它设为 "low"。
语言模型也已进入官方 mlx-lm 仓库的 这个 PR。你可以像下面这样运行同样的高质量 oQ3e 量化版本:
mlx_lm.generate --model mlx-community/Muse-Spark-Open-816B-A42B-oQ3e \
--prompt "Explain convolutional networks like I am 5" \
--max-tokens 5000
这是个很大的模型,即使 3-bit 量化也需要超过 256 GB 内存(如上所述)。你也可以在多台电脑上跑分布式推理,详情请参考文档。
用 Inference Endpoints 部署 Muse Spark Open
你可以在 Inference Endpoints 上部署 Muse Spark Open,官方提供了经过预验证的 SGLang 方案,适用于 NVFP4 版本:既可以跑在 8 × NVIDIA RTX Pro 6000 98 GB 上(上下文长度 131072),如果想达到 1048576 的上下文长度,也可以跑在 8 × NVIDIA H200 141GB 上。
部署只需用 Hugging Face CLI 执行一条命令:
hf endpoints catalog deploy --repo meta-models/Muse-Spark-Open-816B-A42B-NVFP4 --name muse-spark
或者打开 endpoints.huggingface.co/new/meta-models/Muse-Spark-Open-816B-A42B-NVFP4,点击 Create Endpoint。
Endpoint 提供 OpenAI 兼容的 API,包括位于 /v1/chat/completions 的 Chat Completions API 和位于 /v1/responses 的 Responses API。
curl "https://<your-endpoint>.endpoints.huggingface.cloud/v1/chat/completions" \
-H "Authorization: Bearer $HF_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"model": "meta-models/Muse-Spark-Open-816B-A42B-NVFP4",
"messages": [{
"role": "user",
"content": [
{"type": "image_url", "image_url": {"url": "https://huggingface.co/datasets/merve/vl-test-suite/resolve/main/pills.jpg"}},
{"type": "text", "text": "Do any of the components in this supplement interact?"}
]
}],
"chat_template_kwargs": {"enable_thinking": false}
}'
任何兼容 OpenAI 的客户端都能使用同一个 URL,并把你的 Hugging Face token 作为 API key。
使用 TRL 进行微调
你可以用 TRL 的 SFTTrainer 对 816B 的 checkpoint 进行微调。本节将展示我们如何在 8 个节点(每节点 8 张 H100 GPU)上用 TRL 完成微调。该方案在注意力层上训练 LoRA adapter,专家模型保持冻结。完整脚本见 TRL examples。
首先,需要把模型切分到 64 张 GPU 上。由于模型体量很大,必须从多个维度进行并行。我们用 FSDP 对模型分片,并用 DistributedConfig 将专家分配到各张 GPU 上——它会告诉 transformers 在加载时如何切分模型:
from transformers.distributed import DistributedConfig
distributed_config = DistributedConfig(fsdp_size=64, ep_size=8)
在上面的代码中,fsdp_size=64 表示用 FSDP2 把模型分片到全部 64 张 GPU 上,ep_size=8 表示把每层的 256 个专家分成 8 组。Transformers 会把每个 token 发送到持有其专家的那张 GPU 上,因此每张 GPU 只在各自的 batch 分片上训练。
接下来,我们就可以为训练配置 SFTConfig。这里我们用一个开源数据集对模型的 chat template 做了简单适配,你也可以应用到自己的使用场景中。
import torch
from datasets import load_dataset
from peft import LoraConfig
from transformers.distributed import DistributedConfig
from trl import SFTConfig, SFTTrainer
train_dataset = load_dataset("allenai/tulu-3-sft-mixture", split="train[:500000]")
training_args = SFTConfig(
output_dir="muse-spark-lora-sft",
model_init_kwargs={"dtype": torch.bfloat16, "distributed_config": DistributedConfig(fsdp_size=64, ep_size=8)},
per_device_train_batch_size=1,
max_steps=500,
max_length=2048,
packing=True,
save_only_model=True,
logging_steps=1,
report_to="trackio",
)
trainer = SFTTrainer(
model="meta-models/Muse-Spark-Open-816B-A42B",
args=training_args,
train_dataset=train_dataset,
peft_config=LoraConfig(r=16, lora_alpha=32, target_modules=["q_proj", "k_proj", "v_proj", "o_proj"]),
)
trainer.train()
这里的核心是 packing=True,它把多条样本拼接成 2048 token 的序列,无需填充,同时用块对角掩码保证样本之间互不干扰。save_only_model=True 只保存 adapter 而不保存优化器状态,因为 trainer 无法恢复加载时已分片的模型。LoraConfig 只作用于四个注意力投影,每层的 256 个专家保持冻结。
然后在每个节点上运行这条命令:
torchrun --nnodes 8 --nproc_per_node 8 --rdzv_backend c10d --rdzv_endpoint "$MASTER_IP:29700" sft_muse_spark_open.py
我们训练了 500 步,在 64 张 H100 上耗时约 2 小时,吞吐约每秒 8,000 token。平均 token 准确率从 72% 提升到 84%,损失从 1.26 降到 0.57,说明这次微调效果不错。
演示示例
Muse Spark Open 是一个面向编程和智能体场景的模型。我们想亲自验证一下,所以尝试了一系列多模态和智能体任务,用到了它的图像和音频输入能力。下面所有内容你都可以直接运行或 fork。
3D 资产生成器
我们把 2-bit 量化的 Muse Spark Open(通过 llama.cpp 部署)与 Pi 编程智能体结合,在 Three.js 中生成并迭代优化 3D 素材。提示词见这里;由于模型做了量化,需要稍微多引导几次。在 Mac Ultra 上通过 llama.cpp 运行,速度可达 18 TPS。
流程是这样的:先描述想要的素材,Pi 用模型生成对应的 Three.js 代码,在浏览器中渲染结果,并从多个角度截图,然后把截图发回 llama server 上的同一个模型获取视觉反馈。Pi 根据反馈修改代码,如此循环往复。
基于 OpenEnv 和 Hugging Face Sandbox 的浏览器交互
我们在计算机操作(computer use)任务上测试了 Spark,性能令人惊喜,于是我们做了一个精简的演示,同时也能帮你理解计算机操作智能体是如何工作的。你还可以按自己的需求进一步定制。它既是教学示例,也只需几行代码就能跑起来,地址见这里。
结合 OpenEnv 和 HF Sandboxes 的 Muse Spark NVFP4 浏览器智能体
Hugging Face Sandboxes 是基于 Hugging Face Jobs 构建的沙箱,方便执行代码。这个演示由三个部分组成:
- 通过 Inference Endpoints 部署的 Muse Spark Open,
- OpenEnv 用 helium 和 selenium 封装浏览器操作(点击、输入、滚动等),并定义浏览器环境的 reset、step、observation、termination 接口,
- Chromium 浏览器
远程沙箱中包含环境和浏览器,如下图所示。
只需几步就能上手体验,示例中有详细说明:用 Muse Spark Open 启动 Inference Endpoint(NVFP4 也没问题!),把 endpoint URL 设为环境变量,在 Spaces 上发布你的 OpenEnv 服务器并同样提供地址,然后就可以跑 agent 循环了。Muse Spark Open 只能看到历史操作、系统提示词、URL 和浏览器截图来决定下一步动作,其他一概不知(没有 DOM、没有 HTML 代码),所以这是一个真正多模态的浏览器演示。
让模型操控你的浏览器
最后,我们想把 Spark 的多模态 agent 能力推到极限,于是搭建了这个 Space,把模型的音频、图像和 agent 能力结合成一个浏览器 agent。我们只需给模型一段大致的需求描述,它就会与内置浏览器交互,去 Amazon 上找相关商品。
Muse Spark Open 接收语音输入,推理出符合描述的商品类型,在 Amazon 上搜索,并根据条件选出最合适的一个。
结语
Muse Spark Open 是 Muse 系列的全尺寸 open-weight 模型。可以从 BF16 或 NVFP4 checkpoint 开始,也可以试试优秀的 llama.cpp quants。如果你用 Muse Spark Open 做出了什么作品,欢迎分享,并在仓库讨论区告诉我们。






