feat: Implement unified memory management for ONNX model inference
- Introduced a new memory management policy for ONNX Runtime to release temporary GPU memory after inference completion. - Established a shared inference entry point for all ONNX models, differentiating between long-lived sessions and temporary memory arenas. - Updated CUDA sessions to utilize a shrinkable memory arena, reclaiming GPU memory post-inference. - Ensured consistent memory release semantics across BEN2, DA3, MoGe-2, and Upscale models while reusing existing sessions. - Added lifecycle tests to validate temporary memory release and session reuse. - Modified model adapters to integrate the new memory management features, ensuring backward compatibility with existing inference behavior. - Enhanced unit tests to cover new memory release scenarios and verify correct behavior across different execution providers.
This commit is contained in:
@@ -2,6 +2,7 @@ import sys
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
from types import SimpleNamespace
|
||||
from unittest.mock import patch
|
||||
|
||||
import numpy as np
|
||||
from PIL import Image
|
||||
@@ -20,6 +21,9 @@ import onnx_upscale
|
||||
|
||||
|
||||
class FakeSession:
|
||||
def get_providers(self):
|
||||
return ["CPUExecutionProvider"]
|
||||
|
||||
def get_inputs(self):
|
||||
return [SimpleNamespace(name="input")]
|
||||
|
||||
@@ -121,6 +125,40 @@ class UpscaleOnnxTest(unittest.TestCase):
|
||||
self.assertEqual(session.calls, 6)
|
||||
self.assertEqual(session.feeds["input"].shape, (1, 3, 256, 256))
|
||||
|
||||
def test_only_final_tile_releases_memory(self):
|
||||
releases = []
|
||||
session = FakeSession()
|
||||
|
||||
def run(model, output_names, feeds, *, release_memory):
|
||||
releases.append(release_memory)
|
||||
return model.run(output_names, feeds)
|
||||
|
||||
with patch.object(onnx_upscale, "run_session", side_effect=run):
|
||||
result = onnx_upscale.infer(
|
||||
session,
|
||||
Image.new("RGB", (449, 225), (1, 2, 3)),
|
||||
)
|
||||
|
||||
self.assertEqual(result.size, (1796, 900))
|
||||
self.assertEqual(releases, [False, False, False, False, False, True])
|
||||
|
||||
def test_non_final_image_does_not_release_its_final_tile(self):
|
||||
releases = []
|
||||
session = FakeSession()
|
||||
|
||||
def run(model, output_names, feeds, *, release_memory):
|
||||
releases.append(release_memory)
|
||||
return model.run(output_names, feeds)
|
||||
|
||||
with patch.object(onnx_upscale, "run_session", side_effect=run):
|
||||
onnx_upscale.infer(
|
||||
session,
|
||||
Image.new("RGB", (449, 225), (1, 2, 3)),
|
||||
release_memory=False,
|
||||
)
|
||||
|
||||
self.assertEqual(releases, [False] * 6)
|
||||
|
||||
def test_provider_unicode_error_is_presented_as_resource_error(self):
|
||||
class InvalidProviderSession(FakeSession):
|
||||
def run(self, _output_names, _feeds):
|
||||
|
||||
Reference in New Issue
Block a user