Replace Comfy YuE with standalone YuEGP profile 1
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
import workflowAceStep from '../assets/workflow_ace_step.json'
|
||||
import workflowAceStep15 from '../assets/workflow_ace_step_15.json'
|
||||
import workflowYue from '../assets/workflow_yue.json'
|
||||
import type { MusicEngine } from '~/utils/music'
|
||||
import { parseMusicBpm } from '~/utils/music'
|
||||
|
||||
@@ -26,22 +25,10 @@ type WorkflowGraph = Record<string, WorkflowNode>
|
||||
|
||||
const ACE_V1_CKPT = 'ace_step_v1_3.5b.safetensors'
|
||||
const ACE_15_CKPT = 'ace_step_1.5_turbo_aio.safetensors'
|
||||
const YUE_S1_DEFAULT = 'C:\\Users\\ianjm\\AppData\\Local\\Comfy-Desktop\\ComfyUI-Shared\\models\\yue\\YuE-s1-7B-anneal-en-cot'
|
||||
const YUE_S2_DEFAULT = 'C:\\Users\\ianjm\\AppData\\Local\\Comfy-Desktop\\ComfyUI-Shared\\models\\yue\\YuE-s2-1B-general'
|
||||
const YUE_NODE = 'YUE_Stage_A_Loader'
|
||||
|
||||
export function musicFilenamePrefix() {
|
||||
return String(useRuntimeConfig().comfyAudioPrefix || process.env.COMFY_AUDIO_PREFIX || 'audio/AIGen')
|
||||
}
|
||||
|
||||
function yueStageARepo() {
|
||||
return String(process.env.YUE_STAGE_A || useRuntimeConfig().yueStageA || YUE_S1_DEFAULT)
|
||||
}
|
||||
|
||||
function yueStageBRepo() {
|
||||
return String(process.env.YUE_STAGE_B || useRuntimeConfig().yueStageB || YUE_S2_DEFAULT)
|
||||
}
|
||||
|
||||
function applyPrefix(graph: WorkflowGraph, prefix: string) {
|
||||
for (const node of Object.values(graph)) {
|
||||
if ((node.class_type === 'SaveAudio' || node.class_type === 'SaveAudioMP3') && 'filename_prefix' in node.inputs) {
|
||||
@@ -111,68 +98,16 @@ function buildAce15Workflow(params: MusicWorkflowParams): WorkflowGraph {
|
||||
return graph
|
||||
}
|
||||
|
||||
function buildYueWorkflow(params: MusicWorkflowParams): WorkflowGraph {
|
||||
const graph = structuredClone(workflowYue as WorkflowGraph)
|
||||
const prefix = params.filenamePrefix || musicFilenamePrefix()
|
||||
const tags = params.tags
|
||||
const lyrics = params.lyrics || '[Instrumental]\n'
|
||||
// Beast 5080 16GB recipe (keep in sync with workflow_yue.json):
|
||||
// - mmgp profile 2 only (3–5 enable quanto and crash under Comfy InferenceMode)
|
||||
// - exactly 1 Stage-A lyric section (2+ still OOMs beside xcodec)
|
||||
// - max_new_tokens floor is 2944 (node min); do not go lower
|
||||
// - Triton/torch.compile off on Windows
|
||||
// - xcodec stays on CPU during Stage A (node patch)
|
||||
const segments = 1
|
||||
for (const node of Object.values(graph)) {
|
||||
if (node.class_type === 'YUE_Stage_A_Loader') {
|
||||
node.inputs.stage_A_repo = yueStageARepo()
|
||||
node.inputs.quantization_model = 'fp16'
|
||||
node.inputs.use_mmgp = true
|
||||
node.inputs.stage1_cache_size = 8192
|
||||
node.inputs.mmgp_profile = 2
|
||||
}
|
||||
if (node.class_type === 'YUE_Stage_B_Loader') {
|
||||
node.inputs.stage_B_repo = yueStageBRepo()
|
||||
node.inputs.use_mmgp = true
|
||||
node.inputs.stage2_cache_size = 4096
|
||||
node.inputs.stage2_batch_size = 1
|
||||
}
|
||||
if (node.class_type === 'YUE_Stage_A_Sampler') {
|
||||
// Genres go to the model prompt only. Stage-A npy filenames are short (Windows MAX_PATH).
|
||||
node.inputs.genres_prompt = tags.replace(/,/g, ' ').replace(/\s+/g, ' ').trim().slice(0, 400)
|
||||
node.inputs.lyrics_prompt = lyrics
|
||||
node.inputs.seed = params.seed
|
||||
node.inputs.prompt_end_time = Math.min(params.duration, 30)
|
||||
node.inputs.run_n_segment = segments
|
||||
node.inputs.max_new_tokens = 2944
|
||||
node.inputs.use_dual_tracks_prompt = false
|
||||
node.inputs.use_audio_prompt = false
|
||||
node.inputs.offload_model = true
|
||||
node.inputs.stage1_no_guidance = true
|
||||
}
|
||||
}
|
||||
applyPrefix(graph, prefix)
|
||||
return graph
|
||||
}
|
||||
|
||||
export function buildMusicWorkflow(params: MusicWorkflowParams): WorkflowGraph {
|
||||
const engine = params.engine || 'ace-step'
|
||||
if (engine === 'yue') return buildYueWorkflow(params)
|
||||
if (engine === 'yue') throw new Error('YuE requires the standalone YuEGP backend.')
|
||||
if (engine === 'ace-step-1.5') return buildAce15Workflow(params)
|
||||
return buildAceV1Workflow(params)
|
||||
}
|
||||
|
||||
export async function assertMusicEngineNodes(engine: MusicEngine | undefined) {
|
||||
const { comfyHasClassType } = await import('~/server/utils/comfy')
|
||||
if (engine === 'yue') {
|
||||
const present = await comfyHasClassType(YUE_NODE)
|
||||
if (present === false) {
|
||||
throw createError({
|
||||
statusCode: 400,
|
||||
statusMessage: 'YuE is not installed on Beast. Clone ComfyUI_YuE into custom_nodes and restart Comfy, then try again.'
|
||||
})
|
||||
}
|
||||
}
|
||||
if (engine === 'yue') throw new Error('YuE cannot run on Comfy.')
|
||||
if (engine === 'ace-step-1.5') {
|
||||
const present = await comfyHasClassType('TextEncodeAceStepAudio1.5')
|
||||
if (present === false) {
|
||||
@@ -186,6 +121,5 @@ export async function assertMusicEngineNodes(engine: MusicEngine | undefined) {
|
||||
|
||||
export const MUSIC_NODE_LABELS: Record<string, string> = Object.fromEntries([
|
||||
...Object.entries(workflowAceStep as WorkflowGraph).map(([id, node]) => [id, node._meta?.title || `Node ${id}`]),
|
||||
...Object.entries(workflowAceStep15 as WorkflowGraph).map(([id, node]) => [id, node._meta?.title || `Node ${id}`]),
|
||||
...Object.entries(workflowYue as WorkflowGraph).map(([id, node]) => [id, node._meta?.title || `Node ${id}`])
|
||||
...Object.entries(workflowAceStep15 as WorkflowGraph).map(([id, node]) => [id, node._meta?.title || `Node ${id}`])
|
||||
])
|
||||
|
||||
Reference in New Issue
Block a user