Repository navigation
0.5.0
oidn-web 0.5.0 simplifies device setup, makes tiled execution always settle, and switches FP16 convolutions to implicit GEMM. It contains breaking changes for TypeScript callers that pass adapterInfo, for code that constructs UNet directly, and for code that relies on square tiles or per-frame tile pacing.
Performance
Measured with npm run benchmark -- --direct-gemm-only in headless Chrome, using the Clean Aux Large model with FP16. Times are medians. Performance depends on the browser, GPU, model, and tile size. Devices without shader-f16 use FP32, which already used implicit GEMM in 0.4.0, so their gains are expected to be smaller.
| GPU | Input | 0.4.0 | 0.5.0 | Speedup |
|---|---|---|---|---|
| Apple GPU (macOS) | 512 x 512, one tile | 27.2 ms | 19.1 ms | 1.42x |
| Apple GPU (macOS) | 1920 x 1080, 512 px tiles (12 tiles) | 742 ms | 369 ms | 2.01x |
| NVIDIA RTX 4060 Laptop (Windows 11, Chrome 153) | 512 x 512, one tile | 339 ms | 39.7 ms | 8.55x |
| NVIDIA RTX 4060 Laptop (Windows 11, Chrome 153) | 1920 x 1080, 512 px tiles (12 tiles) | 8844 ms | 555 ms | 15.94x |
- Implicit GEMM is now the default for FP16. The 0.4.0 direct FP16 kernel was especially slow on the tested NVIDIA GPU. Network GPU time for a 512 x 512 tile drops from 26.8 ms to 18.5 ms on the Apple GPU, and from 360 ms to 38.5 ms on the RTX 4060.
- Overlap only on shared tile edges reduces the input each tile computes. With the direct kernel alone, the 1920 x 1080 case is about 1.5x faster than 0.4.0 on both GPUs.
Breaking changes
initUNetFromURLandinitUNetFromBuffertake{ device }as the second argument.adapterInfowas only needed by the removed TensorFlow.js backend and is no longer accepted by the type. Extra properties are ignored at runtime, but TypeScript rejects an object literal that still containsadapterInfo.new UNet(tensors, device, options)takes aGPUDeviceinstead of a{ device, adapterInfo }object.tileExecutenow continues on the event loop between tiles by default instead of waiting forrequestAnimationFrame. Passscheduling: 'animation-frame'to keep pacing tiles to display frames.- Tiles are balanced rectangles with overlap only on edges shared with another tile, instead of fixed-size squares. Tile count, position, and size reported to
progressdiffer from 0.4.0. The defaultdynamicTile.initialTileSizeis now 432. UNetExecutionStatsno longer hastileWidthandtileHeight. UsetileColumns,tileRows,tileOverlap,inputPixelCount, andinputShapeCountinstead.- FP16 convolutions use implicit GEMM by default. Output differs slightly from 0.4.0 because accumulation order changed. Set
kernel: 'direct'to reproduce the 0.4.0 FP16 path.
Added
hdrTransfer: 'log'for RTLightmap HDR models, alongside the default PU transfer.errorcallback ontileExecutefor asynchronous failures, WebGPU device loss, and exceptions thrown byprogressordone.progressanddonemay return promises.scheduling: 'event-loop' | 'animation-frame',tileOverlap, andwholeImageoptions ontileExecute.prepareForImage(width, height)to create per-shape GPU resources before the first denoise.planTileGridand itsTilePlan,PlannedTile, andTileRecttypes.- Experimental
gemmtuning options. These are intended for benchmarking and are not covered by semver. hdrTransferandactiveExecutionCountingetRuntimeInfo(), and the active GEMM configuration underkernel.gemm.
Changed
- Implicit GEMM tiles are selected by output alignment and GPU limits, with optimized addressing, weight layout, register tiles, shared-memory layout, and pooling access.
- The final RGB convolution uses an adaptive shared-memory cache.
- Adaptive tile sizing uses the smoothed P75 tile GPU time, excludes the cold first tile, ignores cancelled and single-tile work, and buckets input shapes to at most two sizes.
animation-framescheduling falls back to a 100 ms timer so execution still completes in hidden tabs.
Fixed
- Tiled execution always settles with
doneorerror, or stops silently after abort, including whenrequestAnimationFramenever fires or the device is lost. - Completed executions release their device-loss listeners.
- Edge tiles whose size is not a multiple of 16 replicate edge pixels into the padded model input.
- The npm package no longer includes benchmark results, tests, and scripts.
- Renamed
examples/aux.*toexamples/auxiliary.*so the repository can be checked out on Windows, whereAUXis a reserved file name.
Migration notes
- Replace
{ device, adapterInfo }with{ device }. - Replace
new UNet(tensors, { device, adapterInfo }, options)withnew UNet(tensors, device, options). - Interactive renderers that share the GPU with OIDN should pass
scheduling: 'animation-frame'. - Pass an
errorcallback to handle failures. Without one, failures are logged to the console.