Skip to content

Fix RVM inference on GPU execution providers - #923

Draft
burneikis wants to merge 1 commit into
royshil:mainfrom
burneikis:fix-759-gpu-inference-rvm-onnx
Draft

Fix RVM inference on GPU execution providers#923
burneikis wants to merge 1 commit into
royshil:mainfrom
burneikis:fix-759-gpu-inference-rvm-onnx

Conversation

@burneikis

Copy link
Copy Markdown

Fix RVM inference on GPU execution providers

Preface: This change was written with claude fable, I am not a C++ Systems developer. I have manually tested this change. I hope to get this issue fixed, and maybe this helps. I will not be offended if it's rejected.

To be clear, I have read contributing.md I understand to a very basic level whats happening here.
I am keeping this a draft while I try and understand this fully.

Summary

Fixes #759 (RVM / GPU inference producing a single frame then freezing or crashing).

Two changes:

  1. Use the original .onnx model for RVM instead of the pre-optimized
    .with_runtime_opt.ort variant, which is serialized with CPU-EP-specific
    optimizations and breaks GPU execution providers (CUDA, TensorRT, etc.).
  2. Let ORT allocate output tensors in runNetworkInference() and copy
    results back into the pre-allocated CPU buffers with bounds checking.
    Pre-binding CPU output tensors misbehaves on GPU EPs for stateful
    multi-output models like RVM. (Same root cause Fix GPU inference freezing after first frame #760 attempted; this goes
    further by also replacing the CPU-targeted .ort model.)

Notes for reviewers:

  • CPU inference results are unchanged for all models. Overhead is one output
    tensor allocation + copy per frame (negligible). Output shape mismatches are
    now a logged warning with truncation instead of an ORT error.
  • For RVM on CPU, session creation is slightly slower (graph optimization now
    happens at load instead of being pre-baked); inference speed is unchanged.
  • Only RVM's model file changes; all other models keep their .ort files.
  • required_operators_and_types.with_runtime_opt.config may need regenerating
    since the CI ORT build uses --include_ops_by_config (it is not a
    --minimal_build, so loading ONNX-format models is supported).

Test Plan

Automated

  • CI builds pass on all platforms (Linux, Windows, macOS), including the
    custom reduced-ops ORT build loading the .onnx model.
  • clang-format check passes.
  • REUSE compliance check passes (new .onnx.license added, old .ort
    and license removed).

Manual - GPU (the fix)

On a machine with an NVIDIA GPU (Linux CUDA build, and Windows GPU build if
available):

  • Add Background Removal filter, select RVM model, set inference device
    to CUDA: background is removed continuously (not frozen after 1 frame),
    no crash, no ORT errors in the OBS log.
  • Repeat with TensorRT if available.
  • Toggle CPU -> CUDA -> CPU at runtime: filter keeps working after each
    switch.
  • Run for 10+ minutes to check stability and for memory growth
    (watch RSS / GPU memory).

Manual - CPU

  • RVM on CPU still works (temporal consistency intact - matting should
    remain stable across frames, confirming recurrent state passing works).
  • Compare CPU frame time before/after this change for RVM (expect no
    measurable regression from the added copy).
  • First filter load with RVM: slightly longer session creation is
    expected (graph optimization now happens at load); confirm it is
    acceptable (< ~1 s).

Regression - other models

The inference change affects all models, so spot-check each on CPU:

  • SINet, MediaPipe, Selfie Segmentation, Selfie Multiclass, PPHumanSeg
    (segmentation models) produce correct masks.
  • TBEFN / URetinex / SGLLIE (enhancement) and TCMonoDepth (depth) still
    produce correct output.
  • No new "Output size mismatch" warnings in the OBS log for any model.
  • Packaging: installed plugin data contains rvm_mobilenetv3_fp32.onnx
    and no stale rvm_mobilenetv3_fp32.with_runtime_opt.ort.

Pull Request Checklist

Please read our latest CONTRIBUTING.md.

  • I have read the latest CONTRIBUTING.md.
  • I have acknowledged the licensing and patent grant policy.
  • I have included the required license headers.
  • I am confident with my code integrity.
  • I have signed off and verified all my commits.

Use the original ONNX model for RVM instead of the pre-optimized .ort
variant, which is CPU-EP-targeted and crashes GPU execution providers
such as CUDA.

Also let ONNX Runtime allocate output tensors during inference and copy
the results back into the pre-allocated CPU buffers with bounds
checking. Pre-binding CPU output tensors can misbehave on GPU execution
providers for stateful multi-output models like RVM.

Relates to royshil#759

Signed-off-by: Alex Burneikis <alexburneikis@gmail.com>
@umireon

umireon commented Jul 18, 2026

Copy link
Copy Markdown
Collaborator

This change was written with claude fable, I am not a C++ Systems developer.

Not acceptable at all. Closing. Please open an issue instead of PR.

@umireon umireon closed this Jul 18, 2026
@umireon

umireon commented Jul 18, 2026

Copy link
Copy Markdown
Collaborator

We accept Gen-AI based PRs only if we can assume the author has ability to verify their code safely. This is the meaning of the policy on CONTRIBUTING.md.

@burneikis

Copy link
Copy Markdown
Author

No problem, hope this code can still be used for reference / resolving the issue. 👍

@umireon

umireon commented Aug 4, 2026

Copy link
Copy Markdown
Collaborator

Thanks. We plan to remove the RVM model because it is too large and this problem will be removed.

@burneikis

burneikis commented Aug 4, 2026

Copy link
Copy Markdown
Author

Thanks. We plan to remove the RVM model because it is too large and this problem will be removed.

Oh really? I've found this model to be the most useful, and personally, it's the only one I use, (with GPU, using my patch).

Is this decision final? Is there a better suggested option? I appreciate the development effort/cost required to maintain this sort of thing.

@umireon

umireon commented Aug 4, 2026

Copy link
Copy Markdown
Collaborator

@burneikis The computational load of RVM is too large for many users and they have reported issues frequently. The large footprint of RVM is related to its inference cost. Of course, I know the quality of RVM matte is quite good. Therefore, I'm considering generating fine mask from coarse matte like the approach implemented in LBRL. If you want us to keep RVM within our plugin, please tell us why you need to use RVM and what is the key difference from every other model. We are always open but need evidences from users because we don't have telemetry in our plugin. Thank you for asking us about the current situation!

@burneikis

Copy link
Copy Markdown
Author

@burneikis The computational load of RVM is too large for many users and they have reported issues frequently. The large footprint of RVM is related to its inference cost. Of course, I know the quality of RVM matte is quite good. Therefore, I'm considering generating fine mask from coarse matte like the approach implemented in LBRL. If you want us to keep RVM within our plugin, please tell us why you need to use RVM and what is the key difference from every other model. We are always open but need evidences from users because we don't have telemetry in our plugin. Thank you for asking us about the current situation!

I will test this and put together a better explanation / reasoning and get back to you 👍

@burneikis

Copy link
Copy Markdown
Author

I did a quick test running the models side-by-side with my webcam to best showcase my preference.
this was run directly in Python, outside of OBS, RTX 4080, Logitech BRIO, 1280x720.

RVM GPU vs CPU:

  • RVM on CUDA: 5.9 ms
  • RVM on CPU: 20.4 ms

I also emulated the LBRL pipeline to test the coarse-matte idea (MediaPipe 256x144, fast guided filter, temporal smoothing, motion gate).

headshot

As you can see, the RVM is much more accurate / less transparent-spill

IMO, the key difference is the sharp/hard line

compare_hands motion

So my request is to keep RVM, but only offer it when a GPU execution provider is active.
That being said, I understand the maintenance and implementation cost, so if you want to remove it, idm using my fork.
Thanks for your time and consideration.

@umireon

umireon commented Aug 8, 2026

Copy link
Copy Markdown
Collaborator

I agree with keeping RVM for large-sized portrait. The missing key from our plugin is clarifying the situation for which models are suited. Are you good with this conclusion?

@umireon umireon reopened this Aug 8, 2026
@burneikis

Copy link
Copy Markdown
Author

I agree with keeping RVM for large-sized portrait. The missing key from our plugin is clarifying the situation for which models are suited. Are you good with this conclusion?

Yeah, the main thing is that the model is slow (especially without GPU), I would only recommend for GPU use.

@umireon

umireon commented Aug 9, 2026

Copy link
Copy Markdown
Collaborator

I don't believe we can recommend RVM because GPU on many systems doesn't have enough resources for this model.

@burneikis

Copy link
Copy Markdown
Author

I don't believe we can recommend RVM because GPU on many systems doesn't have enough resources for this model.

Oh I see, so even for average GPU it's still to much?
Could you detect available resources, or just put a noticeable disclaimer, requiring a strong GPU?

@umireon

umireon commented Aug 9, 2026

Copy link
Copy Markdown
Collaborator

Such an intelligent detection is so great for users. However, it is hell for developers because it enlarges our responsibilities to resolve errors on every specific equipment. So, my answer is no.

@burneikis

Copy link
Copy Markdown
Author

Fair. Perhaps just a disclaimer on the Model Selection, or in this project's README.

@umireon

umireon commented Aug 9, 2026

Copy link
Copy Markdown
Collaborator

My point of view is to add a model guide we have. I'd like to tell users that the only recommended model is MediaPipe and they can choose another model like RVM at their own based on the knowledge of models.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Windows and GPU version: Inference device only works on CPU, the other options only processes one frame and then stops

2 participants