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 ,
@@ -455,6 +460,9 @@ def compile(
455460 engine_cache_dir : str = _defaults .ENGINE_CACHE_DIR ,
456461 engine_cache_size : int = _defaults .ENGINE_CACHE_SIZE ,
457462 custom_engine_cache : Optional [BaseEngineCache ] = _defaults .CUSTOM_ENGINE_CACHE ,
463+ cache_lowered_graphs : bool = _defaults .CACHE_LOWERED_GRAPHS ,
464+ reuse_cached_lowered_graphs : bool = _defaults .REUSE_CACHED_LOWERED_GRAPHS ,
465+ lowering_cache_dir : str = _defaults .LOWERING_CACHE_DIR ,
458466 use_fp32_acc : bool = _defaults .USE_FP32_ACC ,
459467 refit_identical_engine_weights : bool = _defaults .REFIT_IDENTICAL_ENGINE_WEIGHTS ,
460468 strip_engine_weights : bool = _defaults .STRIP_ENGINE_WEIGHTS ,
@@ -549,6 +557,9 @@ def compile(
549557 engine_cache_dir (str): Directory to store the cached TRT engines
550558 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
551559 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.
560+ cache_lowered_graphs (bool): Whether to save lowered and partitioned graphs for warm compilation
561+ reuse_cached_lowered_graphs (bool): Whether to reuse lowered and partitioned graphs before decomposition
562+ lowering_cache_dir (str): Directory used by the lowered graph cache
552563 use_fp32_acc (bool): Enable FP32 accumulation for FP16 matmul layers while retaining FP16
553564 inputs and outputs. When combined with ``decompose_attention=True``, the complete
554565 decomposed FP16 scaled dot product attention calculation runs in FP32 and only its
@@ -743,6 +754,8 @@ def compile(
743754 "lazy_engine_init" : lazy_engine_init ,
744755 "cache_built_engines" : cache_built_engines ,
745756 "reuse_cached_engines" : reuse_cached_engines ,
757+ "cache_lowered_graphs" : cache_lowered_graphs ,
758+ "reuse_cached_lowered_graphs" : reuse_cached_lowered_graphs ,
746759 "use_fp32_acc" : use_fp32_acc ,
747760 "refit_identical_engine_weights" : refit_identical_engine_weights ,
748761 "strip_engine_weights" : strip_engine_weights ,
@@ -772,25 +785,51 @@ def compile(
772785
773786 logger .info ("Compilation Settings: %s\n " , settings )
774787 exported_program = pre_export_lowering (exported_program , settings )
775- exported_program = exported_program .run_decompositions (
776- get_decompositions (
777- enable_experimental_decompositions ,
778- decompose_attention ,
779- use_distributed_mode_trace ,
780- use_fp32_acc = use_fp32_acc ,
788+ lowering_cache = None
789+ lowering_cache_key = None
790+ lowering_cache_entry = None
791+ if cache_lowered_graphs or reuse_cached_lowered_graphs :
792+ if not DiskLoweringCache .can_cache (settings ):
793+ logger .warning (
794+ "Lowering cache bypassed: the initial implementation requires "
795+ "require_full_compilation=True, use_fast_partitioner=True, dryrun=False, "
796+ "enable_autocast=False, and use_distributed_mode_trace=False"
797+ )
798+ else :
799+ lowering_cache = DiskLoweringCache (lowering_cache_dir )
800+ lowering_cache_key = lowering_cache .get_hash (
801+ exported_program , trt_arg_inputs , trt_kwarg_inputs , settings
802+ )
803+ if reuse_cached_lowered_graphs :
804+ lowering_cache_entry = lowering_cache .load (lowering_cache_key )
805+
806+ if lowering_cache_entry is not None :
807+ gm = lowering_cache_entry .lowered_module
808+ lifted_buffers = list (lowering_cache_entry .lifted_buffers )
809+ gm = repropagate_graph_metadata (
810+ gm , trt_arg_inputs , trt_kwarg_inputs , settings .device
811+ )
812+ logger .info (
813+ "Reusing cached lowered graph; skipping decomposition and post-lowering"
814+ )
815+ else :
816+ exported_program = exported_program .run_decompositions (
817+ get_decompositions (
818+ enable_experimental_decompositions ,
819+ decompose_attention ,
820+ use_distributed_mode_trace ,
821+ use_fp32_acc = use_fp32_acc ,
822+ )
781823 )
782- )
783824
784- gm = exported_program .module ()
785- # Move the weights in the state_dict to CPU
786- logger .debug ("Input graph: " + str (gm .graph ))
825+ gm = exported_program .module ()
826+ logger .debug ("Input graph: " + str (gm .graph ))
827+
828+ # Lift mutated buffers from get_attr to placeholders BEFORE post_lowering's
829+ # constant_fold runs, so the engine sees them as input bindings.
830+ gm , lifted_buffers = lift_mutated_buffers (gm )
831+ gm = post_lowering (gm , settings )
787832
788- # Lift mutated buffers from get_attr to placeholders BEFORE post_lowering's
789- # constant_fold runs, so the engine sees them as input bindings (a
790- # prerequisite for IKVCacheUpdateLayer / aliased I/O to fire on a
791- # module-held cache). Returns a fresh GraphModule whose forward signature
792- # reflects the new placeholders.
793- gm , lifted_buffers = lift_mutated_buffers (gm )
794833 if lifted_buffers :
795834 # Append each lifted buffer as an engine input AFTER the user inputs.
796835 # Buffer tensors live on the gm's state; prepare an Input spec for
@@ -804,9 +843,17 @@ def compile(
804843 [b for _ , b , _ in lifted_buffers ],
805844 )
806845
807- # Apply lowering on the graph module. Note: constant_fold runs inside post_lowering and requires
808- # module parameters to still be on GPU, so we must not deallocate before this call.
809- gm = post_lowering (gm , settings )
846+ if (
847+ lowering_cache_entry is None
848+ and cache_lowered_graphs
849+ and lowering_cache is not None
850+ and lowering_cache_key is not None
851+ ):
852+ gm = lowering_cache .save (
853+ lowering_cache_key ,
854+ LoweringCacheEntry (gm , tuple (lifted_buffers )),
855+ )
856+
810857 logger .debug (f"CPU memory usage after post_lowering: { get_cpu_memory_usage ()} MB" )
811858 logger .debug ("Lowered Input graph: " + str (gm .graph ))
812859
@@ -823,6 +870,7 @@ def compile(
823870 logger .warning (
824871 "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"
825872 )
873+
826874 trt_gm = compile_module (
827875 gm ,
828876 trt_arg_inputs ,
0 commit comments