Files
wildminder-ComfyUI-VibeVoice/example_workflows/VibeVoice_external_model_example.json
T
WildAi e20b4fd9d8 feat: external model input via VibeVoiceLoadExternalModel node (v2.2.0)
Add a dedicated loader node that loads VibeVoice checkpoints from user-provided .safetensors/.pt files in models/diffusion_models, since ComfyUI's stock Load Diffusion Model cannot detect VibeVoice architecture. The loader emits a VIBEVOICE_MODEL custom type bundle (model/processor/config/state_dict) consumed by an optional external_model input on the TTS, Realtime, and ASR nodes.

- modules/custom_types.py: VibeVoiceModel = io.Custom("VIBEVOICE_MODEL")

- modules/external_loader.py: sidecar config/preprocessor/tokenizer resolution + load_external_vibevoice_model() (TTS/streaming) and load_external_vibevoice_asr_model() (ASR); CPU-first load, in-memory state-dict injection, dtype cast, optional 4-bit quant (TTS only), SageAttention

- nodes/external_loader_node.py: VibeVoiceLoadExternalModel node

- modules/generation.py: ExternalVibeVoiceModelHandler + load_vibevoice_from_external()

- modules/asr_generation.py: ExternalVibeVoiceASRModelHandler + load_asr_from_external()

- nodes/tts_node.py, realtime_node.py, asr_node.py: optional external_model input with kind guards (streaming/ASR/TTS mismatch rejection)

- README: Loading External Models section + v2.2.0 changelog

- example_workflows/VibeVoice_external_model_example.json

- docs/plans/2026-08-16-external-model-input.md (status: COMPLETED)

Tests: +122 new/extended (test_custom_types, test_external_loader, test_external_loader_node, plus extensions to node_schema, generation, asr_generation, realtime_node, asr_node, patcher_behavioral, integration, docs_consistency, workflow, imports, extension). Full suite: 687 passed, 5 pre-existing failures, 4 skipped.
2026-08-16 23:59:04 +03:00

184 lines
3.3 KiB
JSON

{
"id": "a1c2e3f4-5b6d-4e7f-8a9b-0c1d2e3f4a5b",
"revision": 0,
"last_node_id": 3,
"last_link_id": 2,
"nodes": [
{
"id": 1,
"type": "VibeVoiceLoadExternalModel",
"pos": [
-2100,
-1130
],
"size": [
340,
180
],
"flags": {},
"order": 0,
"mode": 0,
"inputs": [],
"outputs": [
{
"name": "VibeVoice Model",
"type": "VIBEVOICE_MODEL",
"links": [
1
]
}
],
"properties": {
"Node name for S&R": "VibeVoiceLoadExternalModel",
"cnr_id": "ComfyUI-VibeVoice"
},
"widgets_values": [
"vibevoice-1.5b.safetensors",
"VibeVoice-1.5B",
"sdpa",
false,
"auto"
],
"color": "#223",
"bgcolor": "#335"
},
{
"id": 2,
"type": "VibeVoiceTTS",
"pos": [
-1570,
-1130
],
"size": [
475,
662
],
"flags": {},
"order": 1,
"mode": 0,
"inputs": [
{
"name": "external_model",
"shape": 7,
"type": "VIBEVOICE_MODEL",
"link": 1
},
{
"name": "speaker_1_voice",
"shape": 7,
"type": "AUDIO",
"link": null
},
{
"name": "speaker_2_voice",
"shape": 7,
"type": "AUDIO",
"link": null
},
{
"name": "speaker_3_voice",
"shape": 7,
"type": "AUDIO",
"link": null
},
{
"name": "speaker_4_voice",
"shape": 7,
"type": "AUDIO",
"link": null
}
],
"outputs": [
{
"name": "AUDIO",
"type": "AUDIO",
"links": [
2
]
}
],
"properties": {
"Node name for S&R": "VibeVoiceTTS",
"cnr_id": "ComfyUI-VibeVoice"
},
"widgets_values": [
"VibeVoice-1.5B",
"[1] This workflow loads an external VibeVoice weight file via the Load VibeVoice Model node and feeds it into the TTS node through the external_model input, overriding the model_name dropdown.",
false,
"sdpa",
1.3,
10,
42,
"fixed",
true,
0.95,
0.95,
0,
false
],
"color": "#232",
"bgcolor": "#353"
},
{
"id": 3,
"type": "SaveAudio",
"pos": [
-1040,
-1130
],
"size": [
270,
112
],
"flags": {},
"order": 2,
"mode": 0,
"inputs": [
{
"name": "audio",
"type": "AUDIO",
"link": 2
}
],
"outputs": [],
"properties": {
"Node name for S&R": "SaveAudio",
"cnr_id": "comfy-core"
},
"widgets_values": [
"audio/VibeVoice_external"
]
}
],
"links": [
[
1,
1,
0,
2,
0,
"VIBEVOICE_MODEL"
],
[
2,
2,
0,
3,
0,
"AUDIO"
]
],
"groups": [],
"config": {},
"extra": {
"ds": {
"scale": 0.9,
"offset": [
2200,
1300
]
}
},
"version": 0.4
}