跳到正文
原文
Hugging Face Blog·· 24 天前精选AI 评分78

Meta 开源 Muse Spark Open:约 816B 参数、42B 激活的多模态 MoE 模型

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

AI 摘要

Meta 发布开源权重多模态 MoE 模型 Muse Spark Open,总参数约 816B、每 token 激活约 42B,上下文窗口最高 1M token,可输入文本、图像、音频和视频,输出文本。

正文 · 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 总参数;~42B 每个token激活参数
专家路由 每个MoE层 256 个专家;每个token 选择 8 个
输入 文本、图像、音频和视频
输出 文本
上下文窗口 高达 1M tokens
检查点格式 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-归一化)。每个块通过学习的残差门组合其输入和输出,而不是通过简单的求和。

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 的块,并生成 4096 维度的特征。位置信息来自学习的绝对嵌入和 2D RoPE。每层的前馈网络使用 LayerNorm 和 GELU。每第四层和最后一层使用全注意力,其他层使用稀疏注意力。

image pipeline diagram

Muse Glimmer 30B 使用相同架构的编码器。设计遵循 Meta 的 感知编码器 工作。视频输入与图像通过相同的编码器处理。

音频编码器

audio diagram

Muse Spark Open 通过其音频编码器接受音频输入。音频分词器将音频转换为 token,聊天模板用 <|audio|> token 标记音频位置。编码器每 80 ms 发出一个音频 token,即每秒产生 12.5 个 token。因此,如果您有一个 10 秒的音频,输入音频 token 的数量将是 125。音频编码器本身是一个卷积金字塔,每个阶段由不同大小的块嵌入和两个 1d 卷积块(大小为 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,并解码新生成的标记,排除输入前缀。处理器有一个推理努力的杠杆,将符号级别(低/中/高/x高)映射到模型本身接受的整数(16、64、256、512)。请注意,使用Muse Spark Open时无法关闭推理,因此如果您想以较低的token消耗来解决一个较容易的任务,请将模型的推理保持在“低”级别。您也可以通过在系统提示中包含类似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处理器将每个图像标记扩展为处理图像所需的块标记数量,并用图像边界标记包围。这种扩展保持了文本位置与传递给模型的视觉特征的一致性。处理器还处理单个提示中的多个图像。

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。然而,也存在权衡,因为您将需要更多的内存,并增加prefill的延迟。帧与包含时间戳(例如“时间:3.5秒”)的文本输入交替出现。要启用传递包含音频的视频,请将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])

处理器在音频边界标记之间插入匹配数量的音频标记。它还返回一个掩码,用于识别真实样本,允许模型排除填充的音频嵌入。

工具调用

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解决更简单的任务,请将模型的推理级别保持在“低”。
我们在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

Muse Spark Open对SGLang的支持支持文本、图像、音频和视频输入。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 \
  --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的参考集成支持文本和图像输入,需要blackwell系列GPU的NVFP4检查点。

安装参考插件及其依赖项后,从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界面下载模型后,你可以在内置的聊天UI中与其聊天。从聊天UI中,你可以添加图像并动态调整推理工作,从低到xhigh。模型的推理显示为可折叠的思考块,与最终答案分开。

请注意,无法关闭推理,默认(Auto)使用xhigh。如果你想在更简单的任务上使用较少的token,请将其设置为“低”。 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的RAM。你也可以在多台计算机上运行分布式推理,详情请参阅文档。

使用推理端点部署Muse Spark Open

您可以使用针对NVFP4变体的预验证SGLang配方在推理端点上部署Muse Spark Open,该配方可以在8 × NVIDIA RTX Pro 6000 98 GB(上下文长度为131072)或8 x NVIDIA H200 141GB上运行,如果您想使用1048576的上下文长度,也可以选择后者。

要部署,请使用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 并选择创建端点。

该端点提供了一个与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进行微调

您可以使用TRL SFTTrainer对816B检查点进行微调。本节展示了我们在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将每个标记发送到持有其专家的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个标记的序列而不进行填充。一个块对角线掩码保持了示例的分离。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小时,每个步骤约8000个标记。平均标记准确率从72%提高到84%,损失从1.26降至0.57,这表明进行了良好的微调运行。

Loss

Acc

演示

Muse Spark Open是一个编码和代理模型。我们想亲自验证这一点,因此我们尝试了一组多模态和代理任务,这些任务使用模型的照片和音频输入。以下所有内容都可以运行或分支。

3D资源生成器

我们将2比特量化的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,并对性能感到惊讶,因此我们构建了一个精简的演示,它也用于教您计算机使用代理的工作原理。您还可以根据您的需要进行进一步自定义。这是一个教育示例,您也可以用几行代码运行。您可以在 这里 找到它。

Muse Spark NVFP4 浏览器代理与 OpenEnv 和 HF 沙盒

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

  1. Muse Spark Open 配备推理端点
  2. OpenEnv 用 helium 和 selenium 包装 WebDriver 操作(点击、输入、滚动等),定义浏览器环境的重置、步骤、观察、终止界面
  3. Chromium 网页浏览器

远程沙盒包含环境和浏览器,如下所示。

Diagram

您可以通过几个步骤轻松尝试此操作,示例中对此进行了描述。启动 Muse Spark Open 推理端点(NVFP4 也同样适用!),将您的端点 URL 添加为环境变量,在 Spaces 中发布您的 OpenEnv 服务器并提供该服务器,然后您就可以运行代理循环。 Muse Spark Open 看到先前的操作、系统提示、URL 以及浏览器截图来采取行动,除此之外什么也没有(没有 DOM,没有 HTML 代码,什么都没有),因此这是一个真正多模态的浏览器演示。

调用您的浏览器

最后,我们希望将 Spark 的代理多模态能力推向极限,因此我们设置了 这个空间,它将模型的音频、图像和代理属性组合成一个浏览器代理。我们给模型一个我们需要的东西的通用描述,它通过与集成的浏览器交互来在亚马逊上查找选项。

Muse Spark Open 接收语音输入,并推理出符合描述的产品类型,在亚马逊上搜索它,并根据标准选择最合适的产品。

总结

Muse Spark Open 是 Muse 系列的一个完整尺寸的开权模型。从 BF16 或 NVFP4 检查点开始,或者尝试其中一个很棒的 llama.cpp quants。如果您使用 Muse Spark Open 构建了某些东西,请分享它,并在 仓库的讨论区 中告诉我们。

来源:Hugging Face Blog · huggingface.co

00