Tighten YuE for 16GB VRAM and stop the false Waiting status.
Cap Stage-A segments and use a heavier mmgp profile so long lyrics stop OOMing mid-run, and show that Comfy is actually working. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+22
-1
@@ -411,14 +411,35 @@ async function refreshStudioQueue() {
|
|||||||
if (queued.value && !jobId.value) {
|
if (queued.value && !jobId.value) {
|
||||||
queued.value = false
|
queued.value = false
|
||||||
}
|
}
|
||||||
|
if (jobId.value && /waiting in the job queue/i.test(status.value)) {
|
||||||
|
status.value = selectedEngine.value === 'yue'
|
||||||
|
? 'YuE running on Comfy — Stage A can take 10–20+ minutes'
|
||||||
|
: 'Generating…'
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (row.status === 'waiting' || (row.status === 'held' && !row.liveJobId)) {
|
if (row.status === 'waiting' || (row.status === 'held' && !row.liveJobId)) {
|
||||||
queued.value = true
|
queued.value = true
|
||||||
busy.value = true
|
busy.value = true
|
||||||
status.value = row.status === 'held' ? 'Paused in the job queue' : 'Waiting in the job queue…'
|
status.value = row.status === 'held'
|
||||||
|
? 'Paused in the job queue'
|
||||||
|
: (selectedEngine.value === 'yue'
|
||||||
|
? 'Waiting for GPU… YuE is heavy; do not spam Generate'
|
||||||
|
: 'Waiting in the job queue…')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if (row.status === 'running' && row.liveJobId) {
|
||||||
|
queued.value = false
|
||||||
|
if (!jobId.value || jobId.value !== row.liveJobId) {
|
||||||
|
jobId.value = row.liveJobId
|
||||||
|
listen(row.liveJobId)
|
||||||
|
}
|
||||||
|
if (/waiting/i.test(status.value)) {
|
||||||
|
status.value = selectedEngine.value === 'yue'
|
||||||
|
? 'YuE running on Comfy — Stage A can take 10–20+ minutes'
|
||||||
|
: 'Generating…'
|
||||||
|
}
|
||||||
|
}
|
||||||
if (row.status === 'error') {
|
if (row.status === 'error') {
|
||||||
queued.value = false
|
queued.value = false
|
||||||
busy.value = false
|
busy.value = false
|
||||||
|
|||||||
@@ -5,9 +5,9 @@
|
|||||||
"xcodec_ckpt": "ckpt_00360000.pth",
|
"xcodec_ckpt": "ckpt_00360000.pth",
|
||||||
"quantization_model": "fp16",
|
"quantization_model": "fp16",
|
||||||
"use_mmgp": true,
|
"use_mmgp": true,
|
||||||
"stage1_cache_size": 16384,
|
"stage1_cache_size": 8192,
|
||||||
"exllamav2_cache_mode": "FP16",
|
"exllamav2_cache_mode": "FP16",
|
||||||
"mmgp_profile": 2
|
"mmgp_profile": 4
|
||||||
},
|
},
|
||||||
"class_type": "YUE_Stage_A_Loader",
|
"class_type": "YUE_Stage_A_Loader",
|
||||||
"_meta": {
|
"_meta": {
|
||||||
@@ -23,7 +23,7 @@
|
|||||||
"repetition_penalty": 1.1,
|
"repetition_penalty": 1.1,
|
||||||
"prompt_start_time": 0,
|
"prompt_start_time": 0,
|
||||||
"prompt_end_time": 30,
|
"prompt_end_time": 30,
|
||||||
"max_new_tokens": 3000,
|
"max_new_tokens": 2000,
|
||||||
"use_dual_tracks_prompt": false,
|
"use_dual_tracks_prompt": false,
|
||||||
"use_audio_prompt": false,
|
"use_audio_prompt": false,
|
||||||
"offload_model": true,
|
"offload_model": true,
|
||||||
@@ -38,8 +38,8 @@
|
|||||||
"16": {
|
"16": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"stage_B_repo": "m-a-p/YuE-s2-1B-general",
|
"stage_B_repo": "m-a-p/YuE-s2-1B-general",
|
||||||
"stage2_cache_size": 8192,
|
"stage2_cache_size": 4096,
|
||||||
"stage2_batch_size": 2,
|
"stage2_batch_size": 1,
|
||||||
"exllamav2_cache_mode": "FP16",
|
"exllamav2_cache_mode": "FP16",
|
||||||
"use_mmgp": true,
|
"use_mmgp": true,
|
||||||
"info": ["8", 1]
|
"info": ["8", 1]
|
||||||
|
|||||||
@@ -32,8 +32,8 @@ function sleep(ms: number) {
|
|||||||
|
|
||||||
function classifyError(message: string) {
|
function classifyError(message: string) {
|
||||||
const lower = message.toLowerCase()
|
const lower = message.toLowerCase()
|
||||||
if (lower.includes('out of memory') || (lower.includes('cuda') && lower.includes('alloc')) || lower.includes('vram')) {
|
if (lower.includes('out of memory') || lower.includes('exceed allowed memory') || (lower.includes('cuda') && lower.includes('alloc')) || lower.includes('vram')) {
|
||||||
return 'ComfyUI VRAM allocation failed. Try fewer steps or a shorter duration.'
|
return 'ComfyUI ran out of VRAM. For YuE use shorter lyrics (fewer sections) or ACE-Step instead.'
|
||||||
}
|
}
|
||||||
if (lower.includes('econnrefused') || lower.includes('unreachable') || lower.includes('fetch failed')) {
|
if (lower.includes('econnrefused') || lower.includes('unreachable') || lower.includes('fetch failed')) {
|
||||||
return 'ComfyUI host connection dropped. Confirm the desktop instance is running.'
|
return 'ComfyUI host connection dropped. Confirm the desktop instance is running.'
|
||||||
@@ -245,11 +245,18 @@ function watchMusicJob(job: Job): Promise<void> {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
const entry = (job.promptId ? history?.[job.promptId] : undefined) as {
|
const entry = (job.promptId ? history?.[job.promptId] : undefined) as {
|
||||||
status?: { status_str?: string; completed?: boolean }
|
status?: {
|
||||||
|
status_str?: string
|
||||||
|
completed?: boolean
|
||||||
|
messages?: Array<[string, Record<string, unknown>]>
|
||||||
|
}
|
||||||
} | undefined
|
} | undefined
|
||||||
const status = entry?.status?.status_str
|
const status = entry?.status?.status_str
|
||||||
if (status === 'error') await fail('ComfyUI reported an execution error')
|
if (status === 'error') {
|
||||||
else if (status === 'interrupted') await fail('Job interrupted.')
|
const err = entry?.status?.messages?.find(([type]) => type === 'execution_error')?.[1]
|
||||||
|
const detail = String(err?.exception_message || err?.message || '').trim()
|
||||||
|
await fail(detail || 'ComfyUI reported an execution error')
|
||||||
|
} else if (status === 'interrupted') await fail('Job interrupted.')
|
||||||
} catch {
|
} catch {
|
||||||
// history can miss while the graph is still running
|
// history can miss while the graph is still running
|
||||||
}
|
}
|
||||||
@@ -382,14 +389,19 @@ export async function startMusicJob(params: MusicJobParams) {
|
|||||||
try {
|
try {
|
||||||
const queued = await queuePrompt(graph, job.clientId, { timeoutMs: 25_000 })
|
const queued = await queuePrompt(graph, job.clientId, { timeoutMs: 25_000 })
|
||||||
if (queued?.prompt_id) job.promptId = queued.prompt_id
|
if (queued?.prompt_id) job.promptId = queued.prompt_id
|
||||||
emitJob(job, { type: 'status', message: 'Job queued on ComfyUI', progress: 8 })
|
const runningMessage = params.engine === 'yue'
|
||||||
|
? 'YuE Stage A on Comfy — 16GB job, often 10–20+ minutes. Leave it alone.'
|
||||||
|
: 'Job queued on ComfyUI'
|
||||||
|
emitJob(job, { type: 'status', message: runningMessage, progress: 8 })
|
||||||
} catch (queueError: unknown) {
|
} catch (queueError: unknown) {
|
||||||
const statusCode = Number((queueError as { statusCode?: number; status?: number })?.statusCode
|
const statusCode = Number((queueError as { statusCode?: number; status?: number })?.statusCode
|
||||||
|| (queueError as { status?: number })?.status || 0)
|
|| (queueError as { status?: number })?.status || 0)
|
||||||
if (statusCode >= 400) throw queueError
|
if (statusCode >= 400) throw queueError
|
||||||
emitJob(job, {
|
emitJob(job, {
|
||||||
type: 'status',
|
type: 'status',
|
||||||
message: 'Waiting for ComfyUI to pick up the job...',
|
message: params.engine === 'yue'
|
||||||
|
? 'YuE submitted — waiting for Comfy to start Stage A…'
|
||||||
|
: 'Waiting for ComfyUI to pick up the job...',
|
||||||
progress: 8
|
progress: 8
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -116,7 +116,9 @@ function buildYueWorkflow(params: MusicWorkflowParams): WorkflowGraph {
|
|||||||
const prefix = params.filenamePrefix || musicFilenamePrefix()
|
const prefix = params.filenamePrefix || musicFilenamePrefix()
|
||||||
const tags = params.tags
|
const tags = params.tags
|
||||||
const lyrics = params.lyrics || '[instrumental]\n'
|
const lyrics = params.lyrics || '[instrumental]\n'
|
||||||
const segments = Math.max(1, Math.min(10, lyrics.split(/\[[^\]]+\]/g).filter(part => part.trim()).length || 2))
|
// 5080 16GB OOMs past ~3 long Stage-A segments on fp16+mmgp. Cap hard.
|
||||||
|
const sections = lyrics.split(/\[[^\]]+\]/g).filter(part => part.trim()).length || 2
|
||||||
|
const segments = Math.max(1, Math.min(2, sections))
|
||||||
for (const node of Object.values(graph)) {
|
for (const node of Object.values(graph)) {
|
||||||
if (node.class_type === 'YUE_Stage_A_Loader') {
|
if (node.class_type === 'YUE_Stage_A_Loader') {
|
||||||
node.inputs.stage_A_repo = yueStageARepo()
|
node.inputs.stage_A_repo = yueStageARepo()
|
||||||
@@ -128,8 +130,9 @@ function buildYueWorkflow(params: MusicWorkflowParams): WorkflowGraph {
|
|||||||
node.inputs.genres_prompt = tags.replace(/,/g, ' ').replace(/\s+/g, ' ').trim()
|
node.inputs.genres_prompt = tags.replace(/,/g, ' ').replace(/\s+/g, ' ').trim()
|
||||||
node.inputs.lyrics_prompt = lyrics
|
node.inputs.lyrics_prompt = lyrics
|
||||||
node.inputs.seed = params.seed
|
node.inputs.seed = params.seed
|
||||||
node.inputs.prompt_end_time = params.duration
|
node.inputs.prompt_end_time = Math.min(params.duration, 45)
|
||||||
node.inputs.run_n_segment = segments
|
node.inputs.run_n_segment = segments
|
||||||
|
node.inputs.max_new_tokens = 2000
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
applyPrefix(graph, prefix)
|
applyPrefix(graph, prefix)
|
||||||
|
|||||||
Reference in New Issue
Block a user