跳到正文
Hugging Face:Blog·· 1 天前精选AI 评分83

Meta 发布开源权重多模态 MoE 模型 Muse Spark Open:816B 参数、1M 上下文

Welcome Muse Spark Open: open-weight frontier multimodal mixture-of-experts model from Meta

AI 导读

Meta 发布开源权重模型 Muse Spark Open,总参数约 816B、每 token 激活约 42B,支持文本、图像、音频和视频输入,上下文窗口最高 1M token,主打 agentic coding,被称为迄今最强的美国开源权重模型。

推荐理由

原文给出架构细节、各平台部署配方和实测吞吐数据,读者可以据此评估部署成本与多模态编码用法。

正文 · AI 翻译

Muse Spark Open 是 Meta 推出的开放权重模型。这个混合专家模型将文本、图像、音频和视频整合到一个约 8160 亿参数的模型中,每个 token 约激活 420 亿参数,上下文窗口最高可达一百万个 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 个
输入 文本、图像、音频和视频
输出 文本
上下文窗口 最高 1M token
检查点格式 BF16 和 NVFP4

检查点仓库为 Muse-Spark-Open-816B-A42B 和 Muse-Spark-Open-816B-A42B-NVFP4。

model diagram

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 个专家,因此模型用约 42B 参数计算每个 token。全部 256 个专家都常驻内存,所以部署需要 816B 参数模型的内存,但运行时拥有 42B 模型快得多的速度。BF16 checkpoint 以 safetensors 格式存储时约为 1.5 TB。NVFP4 checkpoint 以 4-bit 精度存储参数,精度损失可忽略不计,专为 NVIDIA Blackwell GPU 设计。在 transformers 中,BF16 checkpoint 运行在 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。每第四层和最后一层使用全注意力,其他层使用稀疏注意力。

image pipeline diagram

Muse Glimmer 30B 使用相同架构的编码器。该设计遵循 Meta 的 Perception Encoder 工作。视频输入经过与图像相同的编码器。

音频编码器

audio diagram

Muse Spark Open 通过其音频编码器接受音频作为输入。音频 tokenizer 将音频转换为 token,聊天模板用 <|audio|> 个 token 标记音频位置。编码器每 80 ms 输出一个音频 token,即每秒 12.5 个 token。所以,假设你有一段 10 秒的音频,输入的音频 token 数量将是 125。 编码器本身是一个卷积金字塔,其中每个阶段由一个不同 patch 大小的 patch embedder 和 2 个卷积块组成,这些卷积块使用大小为 7、步长为 1 的 1d 卷积核。这些阶段按 patch 大小 [16, 6, 5, 4] 重复。在最后阶段的末尾,时间帧被送入最终块 RMSNorm → 线性投影 → RMSNorm。

长上下文

推理时的上下文窗口为 1M token。配置将 max_position_embeddings 设置为 1,048,576。这包括与文本在同一窗口中的图像、视频和音频 token。

分组查询注意力使这种规模的模型的 KV cache 保持较小。每个 token 向 cache 增加 2 × 16 heads × 64 dimensions × 62 layers = 126,976 个值。在 BF16 中,这约为每 token 250 KB,完整 1M token 上下文约为 266 GB。

推理支持

Transformers

Muse Spark Open 实现提供了 MuseSparkForConditionalGeneration 用于从多模态输入生成文本,以及 MuseSparkProcessor 用于准备对话。该 processor 结合了 tokenizer、图像和视频 processor、音频特征提取器以及聊天模板。

使用 DistributedConfig 配置并行设置。tp_size 是稠密层分片所跨的设备数,ep_size 是专家分布所跨的设备数。

你可以按如下方式初始化模型和 processor。

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)

视频推理

视频提示既包含帧时间信息,也包含视觉内容。处理器能处理带有音频的视频(得益于音频编码器,这是对 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 上运行的 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 cache(模型占用 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 下载 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 \
  --chat-template "$CKPT/muse_spark_1_2_oss.jinja" \
  --port 30000

该 checkpoint 包含 chat template,我们会显式传入。启动器会配置 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

vLLM 的 Muse Spark Open 参考集成支持文本和图像输入,使用需要 Blackwell 系列 GPU 的 NVFP4 checkpoint。

安装参考插件及其依赖项后,从 Hugging Face Hub 下载 checkpoint 并启动服务器:

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 的服务上下文。该插件提供模型实现、checkpoint 加载器以及推理和工具调用解析器。

使用相同的 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 tokens 的情况下,prefill 速度约为 225 tok/s,生成速度约为 21 tok/s。

通过 oMLX 界面下载模型后,你可以在内置聊天 UI 中与其聊天。在聊天 UI 中,你可以添加图像并即时调整推理强度,从 low 到 xhigh。模型的推理会显示为可折叠的思考块,与最终答案分开。

请注意,无法关闭推理,默认(Auto)使用 xhigh。如果你想在较简单的任务上使用更少的 token,请将其设置为“low”。 omlx

该语言模型也可在官方 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 位量化,也需要超过 256 GB 的内存,如上所述。你也可以跨多台计算机进行分布式推理,详情请参阅文档。

使用 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,其中 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://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 密钥来工作。

使用 TRL 进行微调 Quentin Gallouédec Ben Burtenshaw

你可以使用 TRL SFTTrainer 对完整的 816B checkpoint 进行微调。本节展示我们如何使用 TRL 在 8 个节点、每个节点 8 块 H100 GPU 上对完整的 816B checkpoint 进行微调。该配方在注意力层上训练 LoRA 适配器。专家保持冻结。完整脚本在 TRL examples 中

首先,我们需要将模型拆分到 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 只训练自己那部分 batch

现在,我们可以为训练运行配置 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,这表明微调运行良好。

Loss

Acc

演示

Muse Spark Open 是一个编码和智能体模型。我们想亲自验证一下,因此尝试了使用该模型图像和音频输入的多模态与智能体任务组合。下面的一切都是你可以运行或 fork 的内容。

3D 资产生成器

我们将 2-bit 量化的 Muse Spark open(在 llama.cpp 上提供服务)与 Pi 编码智能体结合,在 Three.js 中生成并迭代改进 3D 资产。你可以在此处找到提示词,由于模型经过量化,因此需要稍多一些引导。我们在 Mac Ultra 上通过 llama.cpp 获得 18 TPS。

Pi demo

我们首先描述该资产,Pi 使用模型为该资产生成 Three.js 代码,在浏览器中渲染结果,并从多个角度捕获截图。然后,它将这些图像发送回 llama 服务器上的同一模型以获取视觉反馈。Pi 利用该反馈来编辑代码并重复该过程。

使用 OpenEnv 和 Hugging Face Sandbox 进行浏览器交互

我们在计算机使用任务上测试了 Spark,其性能让我们惊叹不已,因此我们构建了一个精简的演示,同时也可用于教你计算机使用智能体是如何工作的。你还可以根据自己的需求进一步定制它。这既是一个教学示例,也是只需几行代码即可运行的东西。你可以在这里找到它。

使用 OpenEnv 和 HF Sandboxes 的 Muse Spark NVFP4 浏览器智能体

Hugging Face Sandboxes 是基于 Hugging Face Jobs 构建的沙箱,用于轻松执行代码。该演示由三个组件组成:

  1. 通过 Inference Endpoints 提供的 Muse Spark Open,
  2. OpenEnv 使用 helium 和 selenium 封装 Web 驱动程序操作(点击、输入、滚动等),定义浏览器环境的 reset、step、observation、termination 接口,
  3. Chromium 网页浏览器

其中远程沙箱包含环境和浏览器,如下图所示。

Diagram

你可以按照示例中描述的几步轻松尝试。使用 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