2626)
2727from torch_tensorrt .dynamo ._engine_cache import BaseEngineCache , DiskEngineCache
2828from torch_tensorrt .dynamo ._exporter import replace_execute_engine_no_op_node
29+ from torch_tensorrt .dynamo ._lowering_cache import (
30+ DiskLoweringCache ,
31+ LoweringCacheEntry ,
32+ repropagate_graph_metadata ,
33+ )
2934from torch_tensorrt .dynamo .conversion import (
3035 CompilationSettings ,
3136 UnsupportedOperatorException ,
@@ -456,6 +461,9 @@ def compile(
456461 engine_cache_dir : str = _defaults .ENGINE_CACHE_DIR ,
457462 engine_cache_size : int = _defaults .ENGINE_CACHE_SIZE ,
458463 custom_engine_cache : Optional [BaseEngineCache ] = _defaults .CUSTOM_ENGINE_CACHE ,
464+ cache_lowered_graphs : bool = _defaults .CACHE_LOWERED_GRAPHS ,
465+ reuse_cached_lowered_graphs : bool = _defaults .REUSE_CACHED_LOWERED_GRAPHS ,
466+ lowering_cache_dir : str = _defaults .LOWERING_CACHE_DIR ,
459467 use_fp32_acc : bool = _defaults .USE_FP32_ACC ,
460468 refit_identical_engine_weights : bool = _defaults .REFIT_IDENTICAL_ENGINE_WEIGHTS ,
461469 strip_engine_weights : bool = _defaults .STRIP_ENGINE_WEIGHTS ,
@@ -550,6 +558,9 @@ def compile(
550558 engine_cache_dir (str): Directory to store the cached TRT engines
551559 engine_cache_size (int): Maximum hard-disk space (bytes) to use for the engine cache, default is 1GB. If the cache exceeds this size, the oldest engines will be removed by default
552560 custom_engine_cache (Optional[BaseEngineCache]): Engine cache instance to use for saving and loading engines. Users can provide their own engine cache by inheriting from BaseEngineCache. If used, engine_cache_dir and engine_cache_size will be ignored.
561+ cache_lowered_graphs (bool): Whether to save lowered and partitioned graphs for warm compilation
562+ reuse_cached_lowered_graphs (bool): Whether to reuse lowered and partitioned graphs before decomposition
563+ lowering_cache_dir (str): Directory used by the lowered graph cache
553564 use_fp32_acc (bool): Enable FP32 accumulation for FP16 matmul layers while retaining FP16
554565 inputs and outputs. When combined with ``decompose_attention=True``, the complete
555566 decomposed FP16 scaled dot product attention calculation runs in FP32 and only its
@@ -744,6 +755,8 @@ def compile(
744755 "lazy_engine_init" : lazy_engine_init ,
745756 "cache_built_engines" : cache_built_engines ,
746757 "reuse_cached_engines" : reuse_cached_engines ,
758+ "cache_lowered_graphs" : cache_lowered_graphs ,
759+ "reuse_cached_lowered_graphs" : reuse_cached_lowered_graphs ,
747760 "use_fp32_acc" : use_fp32_acc ,
748761 "refit_identical_engine_weights" : refit_identical_engine_weights ,
749762 "strip_engine_weights" : strip_engine_weights ,
@@ -773,25 +786,51 @@ def compile(
773786
774787 logger .info ("Compilation Settings: %s\n " , settings )
775788 exported_program = pre_export_lowering (exported_program , settings )
776- exported_program = exported_program .run_decompositions (
777- get_decompositions (
778- enable_experimental_decompositions ,
779- decompose_attention ,
780- use_distributed_mode_trace ,
781- use_fp32_acc = use_fp32_acc ,
789+ lowering_cache = None
790+ lowering_cache_key = None
791+ lowering_cache_entry = None
792+ if cache_lowered_graphs or reuse_cached_lowered_graphs :
793+ if not DiskLoweringCache .can_cache (settings ):
794+ logger .warning (
795+ "Lowering cache bypassed: the initial implementation requires "
796+ "require_full_compilation=True, use_fast_partitioner=True, dryrun=False, "
797+ "enable_autocast=False, and use_distributed_mode_trace=False"
798+ )
799+ else :
800+ lowering_cache = DiskLoweringCache (lowering_cache_dir )
801+ lowering_cache_key = lowering_cache .get_hash (
802+ exported_program , trt_arg_inputs , trt_kwarg_inputs , settings
803+ )
804+ if reuse_cached_lowered_graphs :
805+ lowering_cache_entry = lowering_cache .load (lowering_cache_key )
806+
807+ if lowering_cache_entry is not None :
808+ gm = lowering_cache_entry .lowered_module
809+ lifted_buffers = list (lowering_cache_entry .lifted_buffers )
810+ gm = repropagate_graph_metadata (
811+ gm , trt_arg_inputs , trt_kwarg_inputs , settings .device
812+ )
813+ logger .info (
814+ "Reusing cached lowered graph; skipping decomposition and post-lowering"
815+ )
816+ else :
817+ exported_program = exported_program .run_decompositions (
818+ get_decompositions (
819+ enable_experimental_decompositions ,
820+ decompose_attention ,
821+ use_distributed_mode_trace ,
822+ use_fp32_acc = use_fp32_acc ,
823+ )
782824 )
783- )
784825
785- gm = exported_program .module ()
786- # Move the weights in the state_dict to CPU
787- logger .debug ("Input graph: " + str (gm .graph ))
826+ gm = exported_program .module ()
827+ logger .debug ("Input graph: " + str (gm .graph ))
828+
829+ # Lift mutated buffers from get_attr to placeholders BEFORE post_lowering's
830+ # constant_fold runs, so the engine sees them as input bindings.
831+ gm , lifted_buffers = lift_mutated_buffers (gm )
832+ gm = post_lowering (gm , settings )
788833
789- # Lift mutated buffers from get_attr to placeholders BEFORE post_lowering's
790- # constant_fold runs, so the engine sees them as input bindings (a
791- # prerequisite for IKVCacheUpdateLayer / aliased I/O to fire on a
792- # module-held cache). Returns a fresh GraphModule whose forward signature
793- # reflects the new placeholders.
794- gm , lifted_buffers = lift_mutated_buffers (gm )
795834 if lifted_buffers :
796835 # Append each lifted buffer as an engine input AFTER the user inputs.
797836 # Buffer tensors live on the gm's state; prepare an Input spec for
@@ -805,9 +844,17 @@ def compile(
805844 [b for _ , b , _ in lifted_buffers ],
806845 )
807846
808- # Apply lowering on the graph module. Note: constant_fold runs inside post_lowering and requires
809- # module parameters to still be on GPU, so we must not deallocate before this call.
810- gm = post_lowering (gm , settings )
847+ if (
848+ lowering_cache_entry is None
849+ and cache_lowered_graphs
850+ and lowering_cache is not None
851+ and lowering_cache_key is not None
852+ ):
853+ gm = lowering_cache .save (
854+ lowering_cache_key ,
855+ LoweringCacheEntry (gm , tuple (lifted_buffers )),
856+ )
857+
811858 logger .debug (f"CPU memory usage after post_lowering: { get_cpu_memory_usage ()} MB" )
812859 logger .debug ("Lowered Input graph: " + str (gm .graph ))
813860
@@ -824,6 +871,7 @@ def compile(
824871 logger .warning (
825872 "Remaining GPU memory may not be enough to compile the TensorRT engine for this model resulting in an OOM error, Consider setting offload_module_to_cpu=True"
826873 )
874+
827875 trt_gm = compile_module (
828876 gm ,
829877 trt_arg_inputs ,
0 commit comments