[AI] Add neural restore lighttable module for AI denoise and upscale#20523
[AI] Add neural restore lighttable module for AI denoise and upscale#20523andriiryzhkov wants to merge 10 commits intodarktable-org:masterfrom
Conversation
|
Excellent! I was looking forward to it :) |
|
How do these models fit in with the "acceptable" model conversation? If we merge a module that requires a model that's not "acceptable", then darktable is "endorsing"/requiring the non acceptable model. |
These models easily meet criteria for open-source AI. Please, see details here: |
|
@esq4: Good point about disk usage. The current approach (import as grouped image) is intentional — it gives you a denoised/upscaled source that you can further develop in darkroom and compare via grouping. This is conceptually different from export, which is a final output step. More flexibility would definitely be helpful here. What I think can be added as extra parameters:
As for export-time denoising (like nind-denoise) — that's a different use case but a valid one. It could be added to the export module down the road as a complementary feature. |
|
BSRGAN only meets open source tooling and in the limitations it says If I look at some of the other models (SAM) they require data destruction in 3 months. Does that mean I have to destroy my edits? It also says no commercial use, so if I sell one of my images am I in violation? I'm sorry, but this is a minefield. Somehow we need to decide a quick way to determine if a model is acceptable. Do we use the OSAID, and if so what MOF? It seems Class I, Open Science, is fine. However Class II, Open Tooling, seems to come with lots of limitations/questions. If we decide to use Class II, how are we going to communicate the limitations to the users? Don't expect them to read, we already know how well that works. |
You are referring to clause 7 of SA-1B DATASET RESEARCH LICENSE. But that is a requirement for the training dataset, not the model. You can use that dataset for your research, for training your own model, but you can't keep it indefinitely. What's the problem?
Absolutely not. This is a conclusion from your statement above that is not true.
Also no. The user is using the model and not the training dataset.
I'm also sorry, but this is NOT a minefield. Wanna see photos of what a minefield actually is? :)
Too vague. What is "acceptable"? Why should we decide what is acceptable for users and not the users themselves? |
|
Thank you for this PR. It works for me. The denoise and upscale functions work. I use the nind and bsrgan models from preferences -> AI after downloading them. If I test this PR on top of git master branch I get fallback to CPU and can not activate NVIDIA CUDA. The denose and, even more so, upscale, are very heavy using CPU and I would say that a GPU is essential (not so for AI masks). Workaround: I found a couple of preliminary issues:
|
|
I'm getting:
when running this on my RX 6700 XT with HSA_OVERRIDE_GFX_VERSION=10.3.0 also bsrgan model won't download throwing an error about a missing integrity check as it couldn't download the chksum |
I guess you have recognized that there is some problem within the dt dev community about exactly this point. And yes, if we as devs decide - we don't want something for whatever reason that may be - it's not a user decision at all. Maybe minefield was not the perfect wording. But you just should accept that for some of the long time devs the "who did and how a model was made" is absolutely critical. For me personally a razor-sharp yes-or-no. |
|
CPU seems to work. But I think it should export to the default export folder. And will it in future also be possible to integrate it right into the normal export workflow? Also without the override and AI set to off in the setting it crashes darktable: I think it should just disable AI and make the checkbox grey or only allow CPU |
|
Note that as for the AI masking there is no models installed and downloaded automatically. All this stays in the hand of the end-users, so everyone can decide depending on its sensibility. I recognize that we have different perception about AI and I would never allow any model installed and/or delivered by default. Even the default build from source has no AI support, one need to pass a specific option to enable this. I really think the current state is respecting everyone choice. |
|
@piratenpanda: thank you for testing and feedback. Regarding error you got. When running neural restore with MIGraphX provider on RX 6700 XT, the model compilation fails because MIGraphX can't handle dynamic shapes in concat operations with
That's interesting. It works on my side. Thinking of possible causes - can you double-check that in
Agree on disabling AI preferences when AI is disabled. This feature along with with proper AI actions block when AI is disabled implemented in PR #20534. It also should fix startup crash when AI is disabled. I would really appreciate your help testing it further. |
😢
If the dev specifies a model necessary to run the module, it's not a user choice, it's a dev/darktable choice. For example I could take the GIMP lua script and replace gimp with photoshop and then add it to the lua-scripts repository and put the "blame" on the user for running it. The open source community would see that as darktable endorsing/requiring/encouraging the use of photoshop. But... Someone could build a script that lets you specify the external executable, such as ext_editor.lua, and you can decide for yourself what executables you want to run even if it's photoshop, capture one, dxo, etc, etc, etc. That is a user choice and darktable has no say in the user's decision. The ONLY way the model can be a user choice is if darktable has NO SAY in the decision. |
Indeed it was the old one still. Changing to the right one it works fine
with the mentioned PR it does not crash anymore |
Fixed - output TIFF now embeds linear Rec.709 ICC profile and source EXIF.
Added collapsible "output parameters" section: bit depth (8/16/32, default 16), catalog toggle, and output directory with darktable variable support (e.g. |
|
Windows CI failing with: |
Are we going to give the user any information about the model's licensing or are we putting that all on the user? Or are we expecting them to go digging to find out for themselves? If we don't at least point them at the information how are they supposed to make an informed choice. Perhaps we include the OSAID rating and the MOF rating with a brief explanation (MOF I - conforms, MOF 2 - some exceptions, etc) and links? |
Probably a good idea, yes! |
So we are expecting this as the last edit step so done after all processing made to the image? |
Currently for me it was totally unclear how to proceed. Now I seem to understand it better. In RawRefinerey I get a nice DNG file I can open and edit because it is creating CFA data at the end. Here I get a tiff file without any further explanation that is was a) created somewhere b) the info we need to reimport the folder again. Which is what I gather now from this? |
|
I suppose we want the created file (denoised or upscaled) to be reimported into lighttable and NOT exported. It should probably be created next to the original file to be part of the same filmstrip. |
749eabc to
89a3829
Compare
|
Fixed Windows (MSYS2/MinGW) build failure: Root cause: Fix: moved PS: I will do similar refactoring for AI mask tool for consistency and better maintainability. |
|
@piratenpanda: This module takes a different approach from RawRefinery - it works on processed images, not raw sensor data. The pipeline exports fully developed linear RGB through darktable's processing pipeline, runs AI inference on that, and saves the result. The typical workflow is:
By default, the module handles everything - export, inference, file saving, import, and grouping so the user just clicks "process" and gets a new image in the filmstrip ready to work with. I welcome ideas on how to improve the UX and make it more obvious what is happening at each step. As for the RawRefinery approach - it is fundamentally different. RawRefinery operates directly on raw CFA data using models trained on raw sensor noise pairs (e.g. NAFNet trained on RNIND). The denoised output is a valid CFA DNG that can be edited through the full raw processing pipeline. This is a powerful approach, but these raw-domain models are typically camera-sensor-specific and may not generalize across all cameras without calibration. There are several promising open-source raw-domain models (LED, PMRID) that could potentially be integrated as a separate feature in the future - but that would be a different module operating before demosaic, not a replacement for this one. |
Thanks @andriiryzhkov. Works for me.
What does this mean for a wide gamut workflow? Is AI denose and upscale confined to Rec.709 (sRGB) gamut? Wide gamut monitors and some print media can do better than that. I have not tested this, but will AI denose and upscale limit out of gamut colors, relative to Rec.709? If it confines output to Rec.709, what is the rendering intent when doing so? The working profile in darktable is linear Rec2020. Will it be possible to keep a wider gamut when AI denoise and upscale is used, like the selected darktable working profile (default linear Rec2020)? Rec.709 and sRGB are smart gamuts, I mean they are highly relevant and enough for many environments and it is good to cover with a color space that is as small as possible, but flowers, insects, artwork and artificial lights frequently go out of gamut relative to Rec.709 and sRGB . |
|
@wpferguson : Do you have an idea to where the model licensing should be documented? I would propose to put this at least in the RELEASE_NOTES for 5.6 but maybe you have also another place in mind? @andriiryzhkov : Can you please add notes about licensing about the different models that can be installed in Darktable? Basically at least all those that are presented by default in the interface but possibly also including all present in darktable-ai? |
@andriiryzhkov, I can confirm that AI denoise limits gamut to Rec.709, which it should based on the statement in details: "...Pixel pipeline: linear Rec.709 → sRGB before inference, sRGB → linear after; planar NCHW layout for ONNX models" I have a wide gamut monitor EIZO CG 279X. I execute gamut check in darkroom on a CR3 raw file to verify that it is out of gamut relative to sRGB (Rec.709). I then export the same image twice:
I can verify, inspecting the exported output visually and with darkroom gamut check, that gamut is indeed restricted to Rec.709 (sRGB) when AI denoise is used to produce its TIFF output result. Again, this is expected and works as stated in 'details'. The default working profile in darktable pipeline is linear Rec2020, which is much bigger than Rec.709 (sRGB) gamut. I use Linear Pro Photo RGB as darktable working profile which is even bigger than Rec2020. If the typical workflow is:
Then we restrict gamut at step 3 to Rec.709 (sRGB) and continued editing towards step 4 has clipped everything out of gamut relative to Rec.709. It would be very helpful if AI denoise and AI upscale functions could make use of the same profiles and rendering intents as the export module, or use the same profile as the user selectable darktable working profile (default linear Rec2020). EDIT: 16-bits output should be used for linear Rec2020 and linear ProPhoto RGB color profiles. |
First thought is maybe include it with the models and have a license link to open it in a browser in the model preferences? |
|
With the two tabs, isn't this going the way of color calibration? Same algorithm, different purposes (I mean how CC uses matrices, but from a user's point of view, white balancing, channel mixing and BW conversion are very different things). Neutral networks could be used for denoising, upscaling, but also highlight reconstruction, and many other things. Wouldn't it be better to have dedicated lighttable modules denoise (NN), upscale, highlight reconstruction (NN), and so on? |
I may agree with you, but that's kind of trade-off. I wanted preview generation to be fast, so it's just a patch in the middle of the image. I was thinking to have possibility to move preview area on the screen, but it turned out to be a bit complex for utility module. |
Thank you so much for putting so much work on all the AI modules! I have a question, because although I like the idea to have an additional denoising algorithm next to the old one, I do not like the workflow of exporting twice, once after the basic edit and then another export for the denoised TIF image, it also somehow contradicts the basic "non-destructive" darktable workflow. So please forgive my naive question: |
89a3829 to
5d2fa34
Compare
Thanks @KarlMagnusLarsson for the detailed analysis. You're right that the pipeline was clipping wide-gamut colors. Fixed in the latest push. The changes:
For upscale, the excess restoration is not possible (input/output resolutions differ), so wide-gamut values pass through the model directly. Residual-learning models (BSRGAN) handle this reasonably well. You can verify with darkroom gamut check: out-of-gamut areas in the original should remain out-of-gamut in the denoised output. |
…ath to neural restore
e99afda to
57bee18
Compare
AI denoising and upscaling are destructive actions. Technically, it produces new image. Because of this it does not fit IOP module concept. |
I was thinking about something more simple, just a cairo scaling to help see the noisy pixels. But maybe this won't be good enough... just a wild idea. |
|
fails with for me |
|
@piratenpanda: I wasn't able to reproduce the error on both Linux and macOS, but my best guess is that comments in that enum might be the root cause. Removed them. Pleach check again. Thank you. |
|
using this pr as a patch it created this for whatever reason: after removing all the copies it worked fine. |
Thank you @andriiryzhkov. Your latest changes work for me. I have tested denoise and upscale in the same way I tested before and the wide gamut color is preserved. I understand the complexity of working around the fact that training used sRGB input. I noticed some very slight changes, but they partly originate from the intended operation (like denoise), when you compare.
What does this mean in practice? Is the wide gamut portion denoised to a lesser degree, or not at all? |
In this implementation the wide gamut portion (values > 1.0) are not denoised at all, because models are not trained to understand them. This is a trade-off I had to come up. |
|
@KarlMagnusLarsson : Actually, let's try and test direct pass-through approach without excess separation. With last commit, model sees everything including > 1.0 values. The risk I am worried about (model producing artifacts on > 1.0) should be minimal with residual-learning models (NIND, BSRGAN) since they output I would appreciate if you test it with wide-gamut images. |
Hello @andriiryzhkov. I have tested with latest b0441b5. The wide gamut is preserved. I have not yet compared with or without b0441b5 in an accurate side by side way. EDIT: I will do that tomorrow Sunday. I got some strange AI-denoise preview error. I do not know if it is related.
|
Did you try to process it? Just curious if final result will have the same artefacts. |
Hello @andriiryzhkov. Yes I did process it and like before gamut is preserved. What I have not yet done is to compare with our without b0441b5 carefully. I tested with slightly different color saturation and sharpness settings for the with and without b0441b5 cases. => I would like to redo test, more carefully. But no obvious artifacts running b0441b5. |
|
Hello @andriiryzhkov, The commit b0441b5 works for me. My tests with and without b0441b5
Result:
|
|
@KarlMagnusLarsson : Thank you! I think we can keep it as is if it works and does not produce artifacts. |

This is a third and improved part of the original PR #20322.
Summary
neural_restore) that provides AI-based image restoration using ONNX backend modelsai_models.json)Details
USE_AI=ON(cmake option, default OFF)Fixes: #19310