How to fix torch.compile on Windows (※for WaveSpeed)
On August 20, 2025, I added a note regarding dynamic management of optimization cache files in combination with Task Scheduler.
For operation via the Inductor backend
At the time of writing the article below, the 'Compile Model+' node, which controls torch.compile, could not be made to work, but
(however, I have updated the article to reflect the current content)
On February 24, 2025, I finally succeeded in getting it to work in the Inductor backend mode, which is the officially recommended setting.


Now, all features of WaveSpeed can be used with the officially recommended settings.
(However, since the Inductor backend itself is not compatible with some nodes, you will need to set up a stability-focused configuration using the cudagraphs backend)
Just like with StableFast, this was quite difficult this time too...I get fired up by missions like this. It doesn't always succeed, though.
Also, this time it definitely won't work without triton.
Furthermore, installing the latest version 3.2.0 or later is mandatory. The Inductor backend cannot be used with 3.1.0 or earlier.
The following settings are for a modified environment built in consultation with Cursor-sensei, but there may be parts that 'can be trimmed and still work'.
Also, this is not necessarily the best configuration, and a setup closer to the official one might be possible.
I am writing this with that premise.
I. Create a global_config.py file in the custom_nodes folder
Since it is a global_config, it is a py file that theoretically affects all Custom nodes, but since the description is limited to torch.compile, I don't think it will affect other nodes... By the way, this code should be able to be implemented in other ways (it will have to be written somewhere), but I couldn't get it to work in any other way than 'this'.
Initially, Cursor-sensei instructed me to add this description to main.py, but if you do that, ComfyUI won't even start in the first place.
The meaning of this file is as follows.
Considering the impact this description has on torch.compile, the following changes in behavior may occur.
1. torch.compile errors are suppressed
When torch._dynamo.config.suppress_errors = True is set, torch.compile() will ignore compilation errors that occur internally and instead fall back to Eager Mode (normal PyTorch execution).
Normally, torch.compile() attempts PyTorch's graph-based compilation, but if optimization fails, it throws an error and stops execution. However, when this setting is enabled:
It does not crash even if an error occurs
The relevant model or function will not be compiled and will run in normal execution mode.
In other words, even if there is a node that fails to compile, it may still run without throwing an error. That is what this means.
2. Impact on ComfyUI
ComfyUI is a node-based system, and each node may potentially use torch.compile.
The following impacts can be expected from this setting.
✅ Pros
Prevents ComfyUI from crashing due to errors occurring in torch.compile.
Allows execution even with unsupported nodes (though they will not be optimized).
❌ Cons
You will no longer be able to explicitly see errors from torch.compile.
Processes that should have been optimized will run in Eager Mode instead.
Performance may unintentionally degrade (if you cannot benefit from torch.compile).
3. Impact of NODE_CLASS_MAPPINGS = {}
This part is the mapping for defining custom nodes in ComfyUI, but since it is set to an empty dictionary {}, it does not directly affect torch.compile.
However, if you place this file in ComfyUI's custom_nodes/ folder, no new nodes will be added to ComfyUI.
Conclusion
Errors in torch.compile are ignored, and it falls back to Eager Mode upon failure.
Nodes using torch.compile in ComfyUI may unintentionally fail to compile.
Since no errors occur during debugging, it becomes easier to overlook issues with compilation optimization.
If you use this setting, it is best to apply it while verifying the behavior of torch.compile, or use it temporarily for debugging purposes..
As of February 25, 2025, now that a method to successfully complete the Inductor backend has been established, it is not strictly necessary for my settings explained below, but having it will increase the program's completion rate.
Ⅱ Add environment variables (also assuming sage-attention)
set PYTORCH_CUDA_ALLOC_CONF=max_split_size_mb:32,garbage_collection_threshold:0.8
set TORCH_COMPILE_DEBUG=0
set TORCH_COMPILE_OPT_LEVEL=2
set TORCH_DYNAMO_CONFIG=force_parameter_static_shapes=false
set TRITON_CACHE_DIR=D:\USERFILES\triton (任意のフォルダ指定)
set TORCH_HOME=D:\USERFILES\torch (任意のフォルダ指定)
set TORCHINDUCTOR_CACHE_DIR=D:\USERFILES\Inductor (任意のフォルダ指定)
set TEMP=D:\USERFILES\Temp (任意のフォルダ指定)
set TEMP=D:\USERFILES\Temp (任意のフォルダ指定)Write this at the beginning of the startup batch file. I have also added settings in anticipation of using sage-attention, which is gaining attention as a new acceleration method. The meaning of each item is as follows.
1. PYTORCH_CUDA_ALLOC_CONF=max_split_size_mb:32,garbage_collection_threshold:0.8
max_split_size_mb:32 # CUDAメモリの断片化を防ぐための最大分割サイズ(MB)
garbage_collection_threshold:0.8 # メモリの80%使用時にGCを実行2. TORCH_COMPILE_OPT_LEVEL=2
0: 最小限の最適化
1: 標準的な最適化
2: 積極的な最適化(推奨)
3: 最大限の最適化(実験的)3. TORCH_LOGS=recompiles,dynamo,inductor
recompiles: 再コンパイルの理由を記録
dynamo: TorchDynamoの動作ログを記録
inductor: Inductorの最適化ログを記録4. TORCH_DYNAMO_CONFIG=force_parameter_static_shapes=false
モデルパラメータの動的な形状変更を許可
再コンパイルの回数を減らす可能性がある5. -
These settings force the specification of the storage location for cache files and temporary files generated during the torch.compile process. While it will work without these specifications, it is better to separate them into an arbitrary location when assuming the use of sage-attention, a new acceleration method, so they are set this way.
Also, please change the folder security settings so that the user has full access to the cache folder created at this time.
III. Using different node settings
1. Inductor backend on WaveSpeed
When using the torch.compile function, basically use it with the Inductor backend in the initial state where the Compile Model+ node by WaveSpeed is loaded, as shown in the figure below.

2. Inductor backend with max-autotune mode on KJNodes
However, currently, the max-autotune mode, which achieves maximum optimization with the Inductor backend, cannot be used with the Compile Model+ node by WaveSpeed. If you specify this mode, the program will error out and fail to complete.
The biggest advantage of using KJNodes is that, as shown in the figure below, the max-autotune function in the Inductor backend, which currently provides the maximum performance for torch.compile, works correctly.

Although max-autotune requires processing time for compilation during the initial load, it definitely shortens the inference time—that is, the sampler processing time.
This characteristic is effective for processing that exceeds the dedicated 12GB VRAM, such as when I perform generation with Flux1 on an RTX 4070 12GB class GPU.
I recently upgraded the core components from DDR4 to DDR5, which also provides benefits, but if you can shorten the subsequent inference time even if it takes time to compile, this max-autotune is effective for processing like Flux1 that exceeds the dedicated 12GB VRAM.
IV. Improving the line break error in the mode input window
The WaveSpeed version of the torch.compile node has a lack of code description that causes errors in its initial state; improving this will increase stability.
Please change the description on line 119 (may vary depending on the version) of "ComfyUI\custom_nodes\Comfy-WaveSpeed\misc_nodes.py" as follows.
mode = mode.strip() if mode else NoneBackground of the issue
If user input (especially values provided as default) contains line breaks or extra spaces, it may cause errors during parsing.
To prevent this, it is necessary to process the input values by removing (trimming) unnecessary whitespace and line breaks.
Meaning of the countermeasure
Here, we use .strip() on the mode variable to remove leading and trailing whitespace and line breaks.
This makes it less likely to cause errors even if the user includes line breaks or spaces in the mode input.
Regarding the decrease in superiority in video generation
In the official WaveSpeed settings, torch.compile is not used in workflows for video generation.
(However, since torch.compile nodes compatible with video generation models are available from KJNodes, it is better to use those)
Regarding the reason for this, according to Cursor's analysis, the following points can be cited.
...
Let's analyze the difference in the effectiveness of torch.compile between video generation models (such as hunyuanvideo) and Flux1:
Differences in model characteristics:
Flux1:
Static image generation
Consistent computational patterns
Predictable execution flow
→ Easier for torch.compile to optimize
Video generation models:
Time-series processing between frames
Dynamic computational patterns
Possibility of many conditional branches
Complex memory access patterns
→ Possibility that torch.compile optimization is difficult
Reasons why optimization effects are limited:
Inter-frame dependencies
Dynamic batch processing
Memory reuse patterns
High proportion of I/O processing
Results
I conducted a comparative test using the Flux1 base program published below, which uses Multi ControlNet and consumes about 13GB of VRAM.
It is definitely faster than without torch.compile. The speedup is particularly noticeable from the second run onwards. This is a very effective node for Flux1, which often exceeds dedicated VRAM and starts using shared VRAM, inevitably leading to performance drops.

With only First Block cache, the results are as follows. It takes nearly twice as long, especially for generation speeds from the second run onwards.

Advanced tips
MultiGPU
Also, using the MultiGPU node explained in the article below in combination is very effective. It is particularly effective for Flux1 and various video generation tasks.
Dynamic management of optimization cache files
torch.compile is a type of caching technology, and its size grows with usage frequency and time. In particular, the size related to triton can reach several tens of GB if used continuously for a long period.
However, if you delete all of this, the settings that torch.compile optimized for each model will be lost.
Therefore, I developed a logic that sets an upper limit on the size and automatically deletes old cache files along with the scheduler when the limit is reached.
First, create a ps1 file with the following content directly under the cache file folder for each model created above. In this case, the limit is set to 50GB, but please adjust it as appropriate. The file name is set to triton-lru-size-cleanup-50gb.ps1, but please change it as appropriate along with the code below.
Param(
[string]$Target = "D:\USERFILES\wan22vace\triton",
[int]$MaxSizeGB = 50, # 上限を 50GB に設定
[int]$KeepMinItems = 2, # 最低直下アイテム数(フォルダ/ファイルの合計)
[string[]]$WhitelistPatterns = @("WAN2.2","wan22","wan22vace"), # マッチした名前は削除対象外
[string]$LogFile = "D:\USERFILES\wan22vace\triton-lru-cleanup-50gb.log",
[switch]$DryRun # DryRun があれば削除は行わない(ログのみ)
)
function Write-Log($msg) {
$line = "[$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')] $msg"
$line | Out-File -FilePath $LogFile -Encoding utf8 -Append
Write-Output $line
}
Write-Log "=== triton-lru-size-cleanup start (Target=$Target MaxSizeGB=$MaxSizeGB KeepMinItems=$KeepMinItems DryRun=$DryRun) ==="
Write-Log "Whitelist patterns: $($WhitelistPatterns -join ',')"
# 1) 安全確認 - ComfyUI が動いていれば中止
try {
$comfy = Get-CimInstance Win32_Process -ErrorAction SilentlyContinue |
Where-Object { ($_.Name -ieq 'python.exe' -or $_.Name -ieq 'python3.exe') -and ($_.CommandLine -match 'ComfyUI') }
} catch {
$comfy = $null
}
if ($comfy) {
Write-Log "ComfyUI process detected. Cleanup aborted to avoid race conditions."
Write-Log "Processes: " + ($comfy | Select-Object ProcessId, CommandLine | Out-String)
exit 0
}
if (-not (Test-Path $Target)) {
Write-Log "Target path not found: $Target"
exit 0
}
# ヘルパー: フォルダ/ファイルのサイズをバイトで取得
function Get-ItemSizeBytes($item) {
if ($item.PSIsContainer) {
try {
$sum = Get-ChildItem -LiteralPath $item.FullName -Recurse -Force -ErrorAction SilentlyContinue |
Where-Object { -not $_.PSIsContainer } |
Measure-Object -Property Length -Sum
return [int64]($sum.Sum)
} catch {
return 0
}
} else {
return [int64]$item.Length
}
}
# 現在の合計サイズ(再帰)
function Get-SizeBytes($path) {
try {
$sum = Get-ChildItem -LiteralPath $path -Recurse -Force -ErrorAction SilentlyContinue |
Where-Object { -not $_.PSIsContainer } |
Measure-Object -Property Length -Sum
return [int64]$sum.Sum
} catch {
return 0
}
}
$maxBytes = [int64]$MaxSizeGB * 1GB
$currentBytes = Get-SizeBytes -path $Target
Write-Log ("Current size: {0:N0} bytes (~{1:N2} GB)" -f $currentBytes, ($currentBytes / 1GB))
if ($currentBytes -le $maxBytes) {
Write-Log "Size within limit. No action required."
Write-Log "=== triton-lru-size-cleanup finished ==="
exit 0
}
# 取得:triton直下の子要素(ファイルやサブフォルダ)
$children = Get-ChildItem -LiteralPath $Target -Force -ErrorAction SilentlyContinue
if (-not $children) {
Write-Log "No child items found under $Target"
exit 0
}
# 各要素に「アクセス時刻キー」とサイズを付与(LastAccessTime が使えない環境では LastWriteTime にフォールバック)
$items = @()
foreach ($c in $children) {
# ホワイトリスト判定(名前にパターンが含まれていれば除外)
$isWhitelisted = $false
foreach ($p in $WhitelistPatterns) {
if ($c.Name -match [regex]::Escape($p)) {
$isWhitelisted = $true
break
}
}
if ($isWhitelisted) {
Write-Log "Skipping whitelisted item: $($c.FullName)"
continue
}
$accessTime = $null
try {
$accessTime = $c.LastAccessTime
if ($accessTime -eq [datetime]::MinValue -or $accessTime -eq $null) {
$accessTime = $c.LastWriteTime
}
} catch {
$accessTime = $c.LastWriteTime
}
$sizeBytes = Get-ItemSizeBytes -item $c
$items += [PSCustomObject]@{
Item = $c
KeyTime = $accessTime
SizeBytes = $sizeBytes
}
}
# 古い順(KeyTime 小さい順)にソート
$items = $items | Sort-Object KeyTime
# 削除ループ(KeepMinItems を守りつつ削る)
foreach ($entry in $items) {
$remainingChildren = (Get-ChildItem -LiteralPath $Target -Force -ErrorAction SilentlyContinue | Where-Object {
# 残りカウントでもホワイトリストを除外してカウントする
$name = $_.Name
$skip = $false
foreach ($p in $WhitelistPatterns) { if ($name -match [regex]::Escape($p)) { $skip = $true; break } }
-not $skip
}).Count
if ($remainingChildren -le $KeepMinItems) {
Write-Log "Reached KeepMinItems ($KeepMinItems). Stop deleting further items."
break
}
if ($currentBytes -le $maxBytes) { break }
$itm = $entry.Item
$itemBytes = $entry.SizeBytes
$timeStr = $entry.KeyTime.ToString('yyyy-MM-dd HH:mm:ss')
Write-Log ("Candidate: {0} LastAccess/Write: {1} Size: {2:N0} bytes (~{3:N2} GB)" -f $itm.FullName, $timeStr, $itemBytes, ($itemBytes / 1GB))
if ($DryRun) {
# DryRun: 実削除しないがサイズを見積もる
$currentBytes -= $itemBytes
continue
}
try {
Remove-Item -LiteralPath $itm.FullName -Recurse -Force -ErrorAction Stop
Write-Log "Removed: $($itm.FullName) freed $itemBytes bytes"
$currentBytes -= $itemBytes
Write-Log ("New size estimate: {0:N0} bytes (~{1:N2} GB)" -f $currentBytes, ($currentBytes / 1GB))
} catch {
Write-Log "ERROR removing $($itm.FullName): $($_.Exception.Message)"
}
}
Write-Log ("Final estimated size: {0:N0} bytes (~{1:N2} GB)" -f $currentBytes, ($currentBytes / 1GB))
Write-Log "=== triton-lru-size-cleanup finished ==="
After creation, please perform a functional test using the following.
powershell.exe -ExecutionPolicy Bypass -File 設置フォルダ\triton-lru-size-cleanup-50gb.ps1" -DryRun
powershell.exe -ExecutionPolicy Bypass -File "D:\USERFILES\wan22vace\triton-lru-size-cleanup-50gb.ps1"
If it is displayed as follows, the test is successful.
[2025-08-20 13:49:45] === triton-lru-size-cleanup start (Target=D:\USERFILES\wan22vace\triton MaxSizeGB=50 KeepMinItems=2 DryRun=False) ===
[2025-08-20 13:49:45] Whitelist patterns: WAN2.2,wan22,wan22vace
[2025-08-20 13:49:46] Current size: 0 bytes (~0.00 GB)
[2025-08-20 13:49:46] Size within limit. No action required.
[2025-08-20 13:49:46] === triton-lru-size-cleanup finished ===
PS D:\USERFILES\wan22vace>Register it in the scheduler. The following is an example of execution every Sunday at 4:30 AM.
schtasks /Create /SC WEEKLY /D SUN /TN "ComfyUI_Triton_LRU_Cleanup_50GB" /TR "powershell.exe -ExecutionPolicy Bypass -File \"D:\USERFILES\wan22vace\triton-lru-size-cleanup-50gb.ps1\"" /ST 04:30 /RL HIGHEST /F
You can also check the registration details with the following command.
PS D:\USERFILES\wan22vace> schtasks /Query /TN "ComfyUI_Triton_LRU_Cleanup_50GB" /V /FO LIST
フォルダー\
ホスト名: USSOEWWIN
タスク名: \ComfyUI_Triton_LRU_Cleanup_50GB
次回の実行時刻: 2025/08/24 13:53:00
状態: 準備完了
ログオン モード: 対話型のみ
前回の実行時刻: 1999/11/30 0:00:00
前回の結果: 267011
作成者: ussoewwin\ussoewwin
実行するタスク: powershell.exe -ExecutionPolicy Bypass -File " D:\USERFILES\wan22vace\triton-lru-size-cleanup-50gb.ps1\ /ST 12:30 /RL HIGHEST /F
開始: N/A
コメント: N/A
スケジュールされたタスクの状態: 有効
アイドル時間: 無効
電源管理: バッテリ モードで停止, バッテリで開始しない
ユーザーとして実行: ussoewwin
再度スケジュールされない場合はタスクを削除する: 無効
タスクを停止するまでの時間: 72:00:00
スケジュール: スケジュール データをこの形式で使用することはできません。
スケジュールの種類: 毎週
開始時刻: 13:53:00
開始日: 2025/08/20
終了日: N/A
日: SUN
月: 1 週ごと
繰り返し: 間隔: 無効
繰り返し: 終了時刻: 無効
繰り返し: 期間: 無効
繰り返し: 実行中の場合は停止: 無効
PS D:\USERFILES\wan22vace>It can be managed or deleted from the Task Scheduler.

More directly, it is also possible to delete all related files. If you create a batch file with the following content and place it in the cache folder created for each model and execute it, you can delete all related files.
The following is for wan22vace.
@echo off
del /q /s "D:\USERFILES\wan22vace\Inductor\*"
del /q /s "D:\USERFILES\wan22vace\Temp\*"
del /q /s "D:\USERFILES\wan22vace\triton\*"