Muse Spark Open 是 Meta 推出的开源权重模型。这个混合专家模型将文本、图像、音频和视频整合进一个约 8160 亿参数的模型中,每 token 约 420 亿活跃参数,上下文窗口最高可达 100 万 token。它生成文本,为开发者提供了一个统一的接口,可就不同类型的输入提问。
继 Muse Glimmer 之后,Muse Spark Open 以更大规模引入了混合专家架构,是迄今为止能力最强的美国开源权重模型。
Meta 针对智能体编程训练了 Muse Spark Open:读取代码库、编写和调试代码,以及调用工具。它还能接收图像、音频和视频作为输入,因此同一个模型在处理你的代码时,可以读取截图、收听语音备忘,或观看屏幕录制。本文介绍如何运行它、如何微调它,以及我们用它构建了什么。查看所有模型此处。
整体能力与架构
Meta 将 Muse Spark Open 描述为一个针对编码优化的模型,基于真实开发者工作流训练,例如多文件重构和长时间调试会话。Muse Spark Open 是一个以智能体为核心的模型,能在长任务中进行规划、行动、观察和自我纠正,包括带图像浏览网页。
| 特性 | Muse Spark Open |
|---|---|
| 模型规模 | 总参数约 816B;每 token 约 42B 活跃参数 |
| 专家路由 | 每个 MoE 层 256 个专家;每 token 选择 8 个 |
| 输入 | 文本、图像、音频和视频 |
| 输出 | 文本 |
| 上下文窗口 | 最高 100 万 token |
| 检查点格式 | BF16 和 NVFP4 |
检查点仓库为 Muse-Spark-Open-816B-A42B 和 Muse-Spark-Open-816B-A42B-NVFP4。
Muse Spark Open 是 Muse 系列模型中的全尺寸模型。Meta 于 8 月发布的 Muse Glimmer 是同一系列中的小型稠密模型,适合在本地运行。两个模型使用相同的分词器和词表。聊天模板沿用 Muse Glimmer 模板,并为新模态做了补充。在 Muse Spark Open 中,输入嵌入和输出层是各自约 16.6 亿参数的独立矩阵。
混合专家
该语言模型有 62 层,隐藏维度为 8192。每层有 128 个查询头和 16 个键值头(分组查询注意力)。每个头有 64 维。注意力块有一个输出门和一个输出归一化层。模型还对查询和键应用归一化(QK-norm)。每个块通过一个学习到的残差门将其输入和输出结合,而不是通过简单的求和。
Muse Glimmer 在每一层使用一个稠密前馈网络。Muse Spark Open 将这个稠密网络替换为混合专家(MoE)块。每个 MoE 块有 256 个专家,路由器为每个 token 选择 8 个专家。每个专家是一个前馈网络,从 8192 维投影到 4096 维再回到 8192 维,然后对其输出应用自己的归一化。专家持有约 97% 的模型总参数。
每个 token 只运行 8 个专家,因此模型用约 42B 参数计算每个 token。全部 256 个专家都保留在内存中,所以部署需要 816B 参数模型的内存,但以 42B 模型快得多的速度运行。BF16 检查点采用 safetensors 格式,约 1.5 TB。NVFP4 检查点以 4 位精度存储参数,精度损失可忽略不计,专为 NVIDIA Blackwell GPU 设计。在 transformers 中,BF16 检查点跨 4 个节点、每节点 8 块 H200 GPU 以张量并行(TP=32)运行,NVFP4 则在单个 B200 节点上运行。如果你想部署 Muse Spark Open,请查看下面的llama.cpp、vLLM 和 SGLang 配方。
感知编码器
感知编码器将图像和视频帧转换为语言模型的 token,就像 Muse Glimmer 一样。该编码器有 1.8B 参数、50 层、隐藏维度 1536、16 个注意力头。它将每张图像分割为 14×14 的 patch,并生成 4096 维的特征。位置信息来自学习到的绝对嵌入和 2D RoPE。每一层的前馈网络使用 LayerNorm 和 GELU。每第四层和最后一层使用全注意力,其他层使用稀疏注意力。
Muse Glimmer 30B 使用相同架构的编码器。该设计遵循感知编码器来自 Meta 的工作。视频输入经过与图像相同的编码器。
音频编码器
Muse Spark Open 通过其音频编码器接受音频作为输入。音频分词器将音频转换为 token,聊天模板用以下内容标记音频位置:<|audio|>token。编码器每 80 ms 输出一个音频 token,即每秒 12.5 个 token。所以,假设你有一段 10 秒的音频,输入的音频 token 数量将是 125。
编码器本身是一个卷积金字塔,其中每个阶段由一个不同 patch 大小的 patch embedder 和 2 个卷积块组成,卷积块使用大小为 7、步长为 1 的一维卷积核。这些阶段按 patch 大小 [16, 6, 5, 4] 重复。在最后阶段结束时,时间帧被送入最后一个块:RMSNorm → 线性投影 → RMSNorm。
长上下文
推理时的上下文窗口为 1M token。配置将max_position_embeddings设置为 1,048,576。这包括与文本处于同一窗口中的图像、视频和音频 token。
分组查询注意力使这种规模模型的 KV 缓存保持较小。每个 token 向缓存添加 2 × 16 个头 × 64 维 × 62 层 = 126,976 个值。在 BF16 下,这大约是每个 token 250 KB,完整 1M 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": "用一句话解释为什么天空通常是蓝色的。"},
]
inputs = tokenizer.apply_chat_template(
messages,
reasoning_effort="medium", # 默认值:xhigh,选项: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": "你应当只用一个数字回答。"},
{"role": "user", "content": "17 * 23 等于多少?"},
]
inputs = processor.apply_chat_template(
messages,
add_generation_prompt=True,
tokenize=True,
return_dict=True,
return_tensors="pt",
reasoning_effort="high", # 选项: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://hf-mirror.com/datasets/merve/vl-test-suite/"
"resolve/main/pills.jpg"
)
messages = [
{
"role": "user",
"content": [
{
"type": "image",
"image": image_url,
},
{
"type": "text",
"text": "这种补充剂中的任何成分会相互作用吗?",
},
],
},
]
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)
视频推理
视频提示包含帧时间信息以及视觉内容。该处理器能处理带音频的视频(得益于音频编码器,这是相较 Muse Glimmer 的升级)。处理器会对视频帧和音频进行下采样,以将帧对齐在一起。默认情况下,视频以 2 FPS 采样,最多 96 帧。你可以通过设置视频处理器的 fps 来修改这一点:
processor.video_processor.fps = 4.0
一般经验法则是,视频是按时间顺序排列的帧,下采样越多,特定事件之间丢失的帧就越多,因此如果想要更准确的生成结果,就需要保持较高的 fps。但这也是一种权衡,因为会需要更多内存并增加预填充的延迟。帧会与标明时间戳的文本输入交错(例如 "Time: 3.5s")。要传入带音频的视频,请将load_audio_from_video=True传给apply_chat_template。
在使用以下方式准备输入时保留视频的元数据return_metadata=True以便处理器能分配正确的帧率。
import torch
messages = [
{
"role": "user",
content: [
{
type: text,
text: (
描述这个视频中发生了什么。
使用时间戳,并包含相关的语音或声音。
),
},
{
type: video,
url: https://hf-mirror.com/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 音频塔接收原始波形。处理器期望 24 kHz 的单声道音频,并将波形填充到 1,920 个采样点的倍数,对应每 80 毫秒一个音频嵌入。以其他采样率直接提供给处理器的音频必须先重采样。你可以使用load_audiotransformers 的 util 来完成。load_audio使用 torchcodec、librosa 或 torchaudio 后端,因此请确保在运行推理前本地已安装其中之一。
如果你只想简单地使用apply_chat_template配合 messages,这一切都会在底层为你处理:
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://hf-mirror.com/buckets/huggingface/audio-samples/resolve/bbaudio_question_39.mp3",
},
{
"type": "text",
"text": "回答这个问题。",
},
],
}
]
# 下载音频,将其解码为单声道,重采样到 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])
处理器会在音频边界标记之间插入匹配数量的音频 token。它还会返回一个标识真实采样点的掩码,使模型能够排除填充的音频嵌入。
工具调用
Muse Spark Open 可以执行纯文本和多模态工具调用。你可以按如下方式让模型调用工具。
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,
dtype="auto",
device_map="auto"
)
tools = [
{
"type": "function",
"function": {
"name": "weather.get",
"description": "获取某个城市的当前天气。",
"parameters": {
"type": "object",
"properties": {
"city": {"type": "string"},
},
"required": ["city"],
},
},
}
]
messages = [
{
"role": "user",
"content": [
{"type": "image", "image": "https://hf-mirror.com/datasets/merve/vl-test-suite/resolve/main/SF.png"},
{"type": "text", "text": "我要去这张图片里的城市。我应该穿什么衣服?"},
],
},
]
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 使用基于通道的聊天模板(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被有意留空,由模型来选择 recipient,使用to=。模型有不同的 recipient,例如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
在 Llama Server 上运行的 Muse Spark 2-bit
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 进行聊天。在 Web UI 中你可以添加音频和图像进行推理,并调整推理档位。
注意,Muse Spark Open 无法关闭推理,因此如果你想用更少的 token 解决较简单的任务,请将模型推理保持在“low”。
我们在 Mac M3 Ultra(512GB)上测试了量化版本。经过 imatrix 校准的 2-bit 量化版本运行速度为 18 tokens/s,并且还有充足的空间留给 KV 缓存(模型占用 304 GB)。
你也可以按如下方式查询服务器。欢迎查看API 参考文档了解多模态、工具调用等更多内容。
## Text-only inference
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"}
]
}'
## Image-text inference
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}'
## Audio-text inference
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 集成环境中,从 HF Mirror Hub 下载检查点并启动服务器:
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
检查点包含聊天模板,我们显式传入它。启动器会配置 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。
安装参考插件及其依赖后,从 HF Mirror 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 缓存留出了空间,在 1024 token 提示和生成 128 token 的情况下,预填充速度约为 225 tok/s,生成速度约为 21 tok/s。
通过 oMLX 界面下载模型后,你可以在内置聊天 UI 中与其对话。在聊天 UI 中,你可以添加图像并即时调整推理强度,从 low 到 xhigh。模型的推理过程会显示为可折叠的思考块,与最终答案分开。
请注意,无法关闭推理,默认(Auto)使用 xhigh。如果你想在较简单的任务上使用更少的 token,请将其设置为“low”。
该语言模型也可在此 PR中使用,属于官方 mlx-lm 仓库。你可以像这样在同样高质量的 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 的 RAM。你也可以跨多台计算机进行分布式推理,详情请参阅文档。
使用 Inference Endpoints 部署 Muse Spark Open
你可以在 Inference Endpoints 上使用经过预验证的 SGLang 配方部署 Muse Spark Open 的 NVFP4 变体,该变体可运行在 8 × NVIDIA RTX Pro 6000 98 GB(上下文长度 131072)上,或者如果你需要 1048576 的上下文长度,可运行在 8 × NVIDIA H200 141GB 上。
要部署,请使用 HF Mirror CLI 运行一条命令:
hf endpoints catalog deploy --repo meta-models/Muse-Spark-Open-816B-A42B-NVFP4 --name muse-spark
或者打开endpoints.hf-mirror.com/new/meta-models/Muse-Spark-Open-816B-A42B-NVFP4并选择 Create Endpoint。
该端点暴露一个 OpenAI 兼容 API,包括 Chat Completions API,位于/v1/chat/completions以及 Responses API,位于/v1/responses。
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://hf-mirror.com/datasets/merve/vl-test-suite/resolve/main/pills.jpg"}},
{"type": "text", "text": "这个补充剂中的任何成分会相互作用吗?"}
]
}],
"chat_template_kwargs": {"enable_thinking": false}
}'
任何兼容 OpenAI 的客户端都可以使用相同的 URL 和你的 HF Mirror token 作为 API key。
使用 TRL 进行微调
你可以使用 TRL 对 816B 检查点进行微调SFTTrainer。本节展示我们如何在 8 个节点、每个节点 8 块 H100 GPU 上用 TRL 对它进行微调。该方案在注意力层上训练 LoRA 适配器。专家保持冻结。完整脚本位于TRL 示例。
首先,我们需要将模型拆分到 64 块 GPU 设备上。鉴于模型规模庞大,我们需要跨多个维度对它进行并行化。我们用 FSDP 对模型进行分片,并将专家拆分到各 GPU 上,使用DistributedConfig,它告诉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 都在自己那部分批次上训练。
现在,我们可以为训练运行配置SFTConfig。我们在这里执行了一个简单任务,在开源数据集上适配模型的聊天模板,但你可以将其应用到自己的用例中。
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保存适配器而不保存优化器状态,因为训练器无法恢复在加载时已被分片的模型。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%,loss 从 1.26 降至 0.57,这表明这是一次不错的微调运行。
演示
Muse Spark Open 是一个编码与智能体模型。我们想亲自验证这一点,于是尝试了一系列多模态与智能体任务,用到了该模型的图像和音频输入。下面所有内容都是你可以运行或 fork 的。
3D 资产生成器
我们将 2-bit 量化的 Muse Spark open(部署在 llama.cpp 上)与 Pi 编码智能体结合,用于生成并迭代改进 3D 资产,基于Three.js。你可以在这里找到提示词这里,由于模型经过量化,需要更多的引导。在 Mac Ultra 上,我们在 llama.cpp 上获得 18 TPS。
我们首先描述资产,Pi 使用该模型为资产生成 Three.js 代码,在浏览器中渲染结果,并从多个角度截取屏幕截图。然后它将这些图像发回 llama server 上的同一模型以获取视觉反馈。Pi 利用该反馈来修改代码,并重复这一过程。
使用 OpenEnv 和 HF Mirror Sandbox 进行浏览器交互
我们在 computer use 任务上测试了 Spark,其表现令我们惊叹,因此我们构建了一个精简的演示,同时也能教你 computer use 智能体是如何工作的。你还可以根据自己的需求进一步定制。这既是一个教学示例,也是几行代码就能运行的东西。你可以在这里找到它这里。
使用 OpenEnv 和 HF Sandboxes 的 Muse Spark NVFP4 浏览器智能体
HF Mirror Sandboxes是基于 HF Mirror Jobs 构建的沙箱,用于便捷的代码执行。该演示由三个组件组成:
- 通过 Inference Endpoints 部署的 Muse Spark Open,
- OpenEnv 使用 helium 和 selenium 封装 Web 驱动操作(点击、输入、滚动等),定义浏览器环境的 reset、step、observation、termination 接口,
- Chromium 网页浏览器
其中远程沙箱包含环境与浏览器,如下图所示。
你可以通过几个步骤轻松尝试,示例中已有说明。用 Muse Spark Open 启动推理端点(NVFP4 也可以很好地工作!),将你的端点 URL 添加为环境变量,在 Spaces 中发布你的 OpenEnv 服务器并提供该地址,然后就可以运行智能体循环了。Muse Spark Open 会查看之前的操作、系统提示、URL 以及浏览器截图来采取行动,除此之外不看任何其他内容(没有 DOM、没有 HTML 代码、什么都没有),因此这是一个真正的多模态浏览器演示。
调用你的浏览器
最后,我们想将 Spark 的智能体多模态能力推向极限,因此我们搭建了这个 space它将模型的音频、图像和智能体特性结合成一个浏览器智能体。我们给模型一个所需物品的概括性描述,它会与集成的浏览器交互,在 Amazon 上寻找选项。
Muse Spark Open 接收语音输入,推理出符合描述的产品类型,在 Amazon 上搜索它,并根据标准选出最合适的一个。
总结
Muse Spark Open 是 Muse 系列中的一个全尺寸开源权重模型。从BF16或NVFP4检查点开始,或者试试那些出色的llama.cpp quants。如果你用 Muse Spark Open 构建了什么,请分享出来,并在仓库的讨论区告诉我们。






