Meta 发布开放权重多模态 MoE 模型 Muse Spark Open
Welcome Muse Spark Open: open-weight frontier multimodal mixture-of-experts model from Meta
Meta 发布开放权重模型 Muse Spark Open,采用 MoE 架构,约有 816B 参数、每 token 激活约 42B 参数,支持文本、图像、音频和视频输入,输出文本,最大上下文窗口为 1M tokens。该模型面向智能体编码训练,支持读取代码库、编写和调试代码及调用工具;文章介绍了运行、部署和微调方法,并提供多个演示。
文章把模型架构、部署配置与微调示例放在一起,尤其呈现了 816B 总参数与 42B 每 token 激活参数之间的部署取舍。
Muse Spark Open 是 Meta 推出的开放权重模型。这款混合专家模型将文本、图像、音频和视频整合到一个模型中,总参数量约为 816 billion,每个 token 激活约 42 billion 个参数,上下文窗口最长可达 one million tokens。它生成文本,为开发者提供了一个通用接口,用于针对不同类型的输入提问。
继 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 个 |
| 输入 | 文本、图像、音频和视频 |
| 输出 | 文本 |
| 上下文窗口 | 最长 1M tokens |
| 检查点格式 | 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 中,输入嵌入层和输出层是相互独立的矩阵,各约有 1.66B 个参数。
混合专家
该语言模型有 62 层,隐藏维度为 8192。每层有 128 个查询头和 16 个键值头(分组查询注意力)。每个头的维度为 64。注意力块包含一个输出门控和一个输出归一化层。模型还会对查询和键进行归一化(QK-norm)。每个块通过一个学习得到的残差门控来组合其输入和输出,而不是简单相加。
Muse Glimmer 在每一层使用一个稠密前馈网络。Muse Spark Open 则用混合专家(MoE)块取代了这个稠密网络。每个 MoE 块有 256 个专家,路由器会为每个 token 选择 8 个专家。每个专家都是一个前馈网络,将维度从 8192 投影到 4096,再投影回 8192,随后对其输出单独进行归一化。专家约占模型总参数量的 97%。
每个 token 只运行 8 个专家,因此模型计算每个 token 时使用约 42B 个参数。全部 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 个图像块,并生成 4096 维特征。位置信息来自学习得到的绝对位置嵌入和 2D RoPE。每一层中的前馈网络使用 LayerNorm 和 GELU。每四层以及最后一层使用全注意力,其余层使用稀疏注意力。
Muse Glimmer 30B 使用的编码器架构相同。这一设计借鉴了 Meta 的 感知编码器研究成果。视频输入与图像一样,都会经过同一个编码器。
音频编码器
Muse Spark Open 通过音频编码器接受音频输入。音频分词器会将音频转换为 token,聊天模板则使用 <|audio|> token 标记音频的位置。编码器每 80 毫秒输出一个音频 token,即每秒 12.5 个 token。比如,假设音频时长为 10 秒,那么输入音频 token 的数量就是 125 个。
编码器本身是一个卷积金字塔,每个阶段都包含一个采用不同图像块尺寸的图像块嵌入器,以及 2 个一维卷积块,卷积核大小为 7,步幅为 1。这些阶段分别采用 [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": "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 处理器会将每个图像标记扩展为处理图像所需数量的图像块 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)
视频推理
视频提示包含帧时间信息和视觉内容。该处理器可处理包含音频的视频(得益于音频编码器,这是相较于 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": (
"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 音频塔会处理原始波形。处理器要求单声道、24 kHz 的音频,并将波形填充到 1,920 个样本的倍数,对应每 80 毫秒一个音频嵌入。直接提供给处理器的音频若采样率不同,必须先重新采样。你可以使用 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.",
},
],
}
]
# Downloads the audio, decodes it as mono, resamples it to 24 kHz, pads it, creates input_values_mask, and expands the audio placeholders.
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,
)
# Decode only newly generated tokens
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"
# 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 使用基于通道的聊天模板(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
在 Llama Server 上运行的 2-bit Muse Spark
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 集成环境中,从 Hugging Face 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 \
--chat-template "$CKPT/muse_spark_1_2_oss.jinja" \
--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。
安装参考插件及其依赖项后,从 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 缓存留有空间;在提示词为 1024 个 token、生成 128 个 token 时,预填充速度约为 225 tok/s,生成速度约为 21 tok/s。
通过 oMLX 界面下载模型后,你可以在内置聊天界面中与它对话。你可以在聊天界面中添加图像,并随时将推理强度从 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 的 RAM。你也可以在多台计算机上运行分布式推理,详情请参阅文档。
使用 Inference Endpoints 部署 Muse Spark Open
你可以使用经过预验证的 SGLang 配方,在 Inference Endpoints 上部署 Muse Spark Open 的 NVFP4 变体。该变体可运行于 8 × NVIDIA RTX Pro 6000 98 GB,支持 131072 的上下文长度;如果需要 1048576 的上下文长度,也可运行于 8 x 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。
该端点提供兼容 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 令牌用作 API 密钥。
使用 TRL 微调 Quentin Gallouédec Ben Burtenshaw
你可以使用 TRL SFTTrainer 对完整的 816B 检查点进行微调。本节介绍我们如何在 8 个节点(每个节点配备 8 块 H100 GPU)上使用 TRL 对完整的 816B 检查点进行微调。该方案在注意力层上训练 LoRA 适配器,专家层保持冻结。完整脚本位于 TRL 示例中
首先,我们需要将模型拆分到 64 个 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 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": distributed_config},
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.py
我们训练了 500 步,在 64 块 H100 上耗时约 2 小时,速度约为每秒 8,000 个 token。平均 token 准确率从 72% 提高到 84%,损失从 1.26 降至 0.57,表明这次微调效果良好。
演示
Muse Spark Open 是一款编程与智能体模型。我们想亲自验证这一点,因此尝试了多种多模态和智能体任务,使用该模型的图像和音频输入。下面的所有内容都可以运行或派生。
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 进行浏览器交互
我们在计算机操作任务中测试了 Spark,其表现令我们惊叹,因此我们构建了一个精简演示,既能展示计算机操作智能体的工作原理,也能让你了解相关知识。你还可以根据自己的需求进一步定制它。这既是一个教学示例,也是一个只需几行代码即可运行的项目。你可以在这里找到它。
使用 OpenEnv 和 HF Sandboxes 的 Muse Spark NVFP4 浏览器智能体
Hugging Face Sandboxes 是基于 Hugging Face Jobs 构建的沙盒,便于执行代码。该演示由三个部分组成:
- 通过 Inference Endpoints 提供服务的 Muse Spark Open,
- 使用 helium 和 selenium 封装 WebDriver 操作(点击、输入、滚动等)的 OpenEnv,定义浏览器环境的重置、步骤、观测和终止接口,
- Chromium 网页浏览器
如下图所示,远程沙盒包含环境和浏览器。
你可以按照示例中介绍的几个步骤轻松试用。启动提供 Muse Spark Open 的 Inference Endpoint(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 构建了什么,请分享出来,并在代码库的讨论区告诉我们。
来源:Hugging Face Blog · huggingface.co






