Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
7464a15
Add weightless support for all initializers (API surface)
chilo-ms Jul 1, 2026
fcc0a8d
Update GetWeightlessSupport comment: KernelContext is current path
chilo-ms Jul 2, 2026
966a441
Fix comment: initializers provided at session creation, not inference…
chilo-ms Jul 2, 2026
8729eac
Update session option comments: current JIT path and session creation…
chilo-ms Jul 2, 2026
cc481da
Add C APIs for weightless source model (file path and byte buffer)
chilo-ms Jul 6, 2026
b586726
Implement weightless source model and compilation APIs
chilo-ms Jul 6, 2026
ce87089
Auto-set drop_constant_initializers=false when weightless is enabled
chilo-ms Jul 6, 2026
4a10750
Merge branch 'main' into chilo-ms/weightless-all-initializers
chilo-ms Jul 7, 2026
5cf4612
Add weightless_support EpDevice metadata key and update to version 1.29
chilo-ms Jul 8, 2026
580216a
Merge branch 'main' into chilo-ms/weightless-all-initializers
chilo-ms Jul 8, 2026
e54cc91
lintrunner -a
chilo-ms Jul 8, 2026
c5ca19b
address reviewer's comments
chilo-ms Jul 9, 2026
c69081c
Merge branch 'main' into chilo-ms/weightless-all-initializers
chilo-ms Jul 9, 2026
4ca3f30
remove empty line
chilo-ms Jul 9, 2026
218dba4
address reviewer's comment
chilo-ms Jul 9, 2026
2966bb8
Add OrtEpApi getters for weightless source model path and buffer
chilo-ms Jul 27, 2026
976808f
Remove unused weightless_enabled_ member and constructor query
chilo-ms Jul 27, 2026
d448547
Remove SessionOptionsSetWeightlessSourceModelPath and its getter
chilo-ms Jul 27, 2026
b2efda1
Add cross-references in API docs and unit tests for weightless APIs
chilo-ms Jul 27, 2026
39c93f2
Add cross-reference to kOrtSessionOptionEpContextSourceModelPath in G…
chilo-ms Jul 27, 2026
d461060
add check for plugin ep weightless support
chilo-ms Jul 28, 2026
4842c93
update the check
chilo-ms Jul 28, 2026
41ad01f
add example ep's GetWeightlessSuppor
chilo-ms Jul 28, 2026
6e3fde7
lintrunner -a
chilo-ms Jul 28, 2026
fbe8fe4
address reviewer's comments
chilo-ms Jul 28, 2026
0dcf174
address reviewer's comments
chilo-ms Jul 28, 2026
95025ed
address reviewer's comments
chilo-ms Jul 29, 2026
c2d1832
address reviewer's comments
chilo-ms Jul 29, 2026
c0985fa
update test
chilo-ms Jul 29, 2026
523526f
Rename SetWeightlessMode to SetWeightlessEnabled for consistency with…
chilo-ms Jul 31, 2026
bfce65c
Use NOT_IMPLEMENTED instead of EP_FAIL when GetWeightlessSupport is m…
chilo-ms Jul 31, 2026
e62d1bd
lintrunner -a
chilo-ms Jul 31, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 51 additions & 0 deletions include/onnxruntime/core/session/onnxruntime_c_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -7517,6 +7517,32 @@ struct OrtApi {
*/
ORT_API2_STATUS(KernelContext_GetSyncStream, _In_ const OrtKernelContext* context,
_Outptr_result_maybenull_ OrtSyncStream** out);

/** \brief Set the source ONNX model as a byte buffer for weightless EPContext sessions.
*
* When creating a session from a weightless EPContext model, the EP may need access to the source model's
* initializer data. This function provides the source model as an in-memory byte buffer, for scenarios
* where the source model is not available as a file on disk (e.g., loaded from a package or downloaded).
*
* The caller retains ownership of the buffer and must ensure it remains valid for the lifetime of the session.
*
* \note If the source model is available as a file on disk, use the session config entry
* "ep.context_source_model_path" (kOrtSessionOptionEpContextSourceModelPath) instead.
Comment thread
edgchen1 marked this conversation as resolved.
*
* \note If both a buffer (via this function) and a file path (via "ep.context_source_model_path") are
* provided, the EP should prefer the buffer. The recommended EP precedence is:
* buffer > file path > "onnx_model_filename" EPContext node attribute.
*
* \param[in] options The OrtSessionOptions instance.
* \param[in] source_model_data Pointer to the source model byte buffer.
* \param[in] source_model_data_length Size of the byte buffer in bytes.
*
* \snippet{doc} snippets.dox OrtStatus Return Value
*
* \since Version 1.29.
*/
ORT_API2_STATUS(SessionOptionsSetWeightlessSourceModelBuffer, _Inout_ OrtSessionOptions* options,
Comment thread
chilo-ms marked this conversation as resolved.
_In_ const void* source_model_data, _In_ size_t source_model_data_length);
};

/*
Expand Down Expand Up @@ -8362,6 +8388,31 @@ struct OrtCompileApi {
ORT_API2_STATUS(ModelCompilationOptions_SetInputModel,
_In_ OrtModelCompilationOptions* model_compile_options,
_In_ const OrtModel* model);

/** \brief Enable or disable weightless mode for model compilation.
*
* When enabled, the compiled EPContext model will not embed constant initializer data in the EP's
* compiled binary. Instead, the initializer data must be provided when creating a session from the
* compiled model, either from the source model (via the "onnx_model_filename" EPContext node attribute
* or the "ep.context_source_model_path" session option) or from externalized weights.
*
* This enables smaller compiled models and allows sharing initializer data across multiple compiled
* model variants (e.g., multi-platform caches for different hardware generations).
*
* ORT verifies that the target EP supports weightless mode during CompileModel() by calling
* OrtEp::GetWeightlessSupport(). If the EP does not support weightless mode, CompileModel()
* returns an error.
*
* \param[in] model_compile_options The OrtModelCompilationOptions instance.
* \param[in] use_weightless If true, enable weightless mode. If false, disable (default behavior).
*
* \snippet{doc} snippets.dox OrtStatus Return Value
*
* \since Version 1.29.
*/
ORT_API2_STATUS(ModelCompilationOptions_SetWeightlessEnabled,
_In_ OrtModelCompilationOptions* model_compile_options,
_In_ bool use_weightless);
};

/**
Expand Down
3 changes: 2 additions & 1 deletion include/onnxruntime/core/session/onnxruntime_cxx_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -1775,7 +1775,8 @@ struct ModelCompilationOptions : detail::Base<OrtModelCompilationOptions> {

ModelCompilationOptions& SetGraphOptimizationLevel(GraphOptimizationLevel graph_optimization_level); ///< Wraps OrtApi::ModelCompilationOptions_SetGraphOptimizationLevel

ModelCompilationOptions& SetInputModel(const OrtModel* model); ///< Wraps OrtCompileApi::ModelCompilationOptions_SetInputModel
ModelCompilationOptions& SetInputModel(const OrtModel* model); ///< Wraps OrtCompileApi::ModelCompilationOptions_SetInputModel
ModelCompilationOptions& SetWeightlessEnabled(bool use_weightless); ///< Wraps OrtCompileApi::ModelCompilationOptions_SetWeightlessEnabled
};

/** \brief Compiles an input model to generate a model with EPContext nodes that execute EP-specific kernels. Wraps OrtApi::CompileModels.
Expand Down
5 changes: 5 additions & 0 deletions include/onnxruntime/core/session/onnxruntime_cxx_inline.h
Original file line number Diff line number Diff line change
Expand Up @@ -1360,6 +1360,11 @@ inline ModelCompilationOptions& ModelCompilationOptions::SetInputModel(const Ort
return *this;
}

inline ModelCompilationOptions& ModelCompilationOptions::SetWeightlessEnabled(bool use_weightless) {
Ort::ThrowOnError(GetCompileApi().ModelCompilationOptions_SetWeightlessEnabled(this->p_, use_weightless));
return *this;
}

namespace detail {

template <typename T>
Expand Down
78 changes: 78 additions & 0 deletions include/onnxruntime/core/session/onnxruntime_ep_c_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -2077,6 +2077,32 @@ struct OrtEpApi {
ORT_API2_STATUS(ProfilingEventsContainer_AddEvents, _In_ OrtProfilingEventsContainer* events_container,
_In_reads_(num_events) const OrtProfilingEvent* const* events,
_In_ size_t num_events);

/** \brief Get the weightless source model byte buffer from session options.
*
* Returns the buffer and size set by SessionOptionsSetWeightlessSourceModelBuffer, or NULL/0 if not set.
* The EP can use this during CreateEp or Compile to access the source model for weightless
* EPContext model sessions.
*
* \note If the source model is provided as a file path, the EP should read the
* "ep.context_source_model_path" (kOrtSessionOptionEpContextSourceModelPath) session config entry
* via GetSessionConfigEntry instead.
*
* \note Recommended EP precedence for locating the source model:
* buffer (this API) > file path ("ep.context_source_model_path") > "onnx_model_filename" EPContext
* node attribute.
*
* \param[in] session_options The OrtSessionOptions instance.
* \param[out] source_model_data Output parameter set to the source model buffer, or NULL if not set.
* \param[out] source_model_data_length Output parameter set to the buffer size, or 0 if not set.
*
* \snippet{doc} snippets.dox OrtStatus Return Value
*
* \since Version 1.29.
*/
ORT_API2_STATUS(SessionOptionsGetWeightlessSourceModelBuffer, _In_ const OrtSessionOptions* session_options,
_Outptr_result_maybenull_ const void** source_model_data,
_Out_ size_t* source_model_data_length);
};

/**
Expand Down Expand Up @@ -2111,6 +2137,26 @@ typedef enum OrtGraphCaptureNodeAssignmentPolicy {
OrtGraphCaptureNodeAssignmentPolicy_ALLOW_CPU_FOR_SHAPES = 1,
} OrtGraphCaptureNodeAssignmentPolicy;

/**
* \brief Describes the scope of an EP's weightless mode support.
*
* Returned by OrtEp::GetWeightlessSupport() to indicate which types of initializers
* the EP can operate on without copying.
*
* \since Version 1.29.
*/
typedef enum OrtWeightlessSupport {
/** EP does not support weightless mode. */
OrtWeightlessSupport_NONE = 0,

/** EP supports weightless mode for external initializers only.
* Internal initializers are still copied by the EP during compilation. */
OrtWeightlessSupport_EXTERNAL_ONLY = 1,

/** EP supports weightless mode for all initializers (internal and external). */
OrtWeightlessSupport_ALL = 2,
} OrtWeightlessSupport;

/**
* \brief The OrtEp struct provides functions to implement for an execution provider.
* \since Version 1.22.
Expand Down Expand Up @@ -2630,6 +2676,38 @@ struct OrtEp {
* \since Version 1.27.
*/
ORT_API2_STATUS(ReleaseCapturedGraph, _In_ OrtEp* this_ptr, _In_ int graph_annotation_id);

/** \brief Query the execution provider's weightless mode support.
*
* When weightless mode is enabled (via the "ep.enable_weightless" session option), ORT calls this function
* to determine the scope of the EP's weightless support. The EP returns an OrtWeightlessSupport value
* indicating whether it supports weightless mode for all initializers, external initializers only, or not
* at all.
*
* The EP's response may depend on the underlying hardware or driver capabilities. For example, an EP may
* support weightless mode for all initializers on newer hardware but only for external initializers on
* older hardware that requires weight transformation.
*
* EPs that support weightless mode should set drop_constant_initializers to false in OrtNodeFusionOptions
* so that ORT provides the initializer data as inputs to the compiled/fused node. The EP can then access
* these initializers at Compute() time via KernelContext_GetInput().
*
* \note Extending the lifetime of initializer data obtained via ValueInfo_GetInitializerValue() during
* Compile() so that the EP can cache and reuse data pointers directly (without going through
* KernelContext) is planned but not yet implemented. Until then, KernelContext_GetInput() is the
* only supported way to access initializer data at Compute() time.
*
* \param[in] this_ptr The OrtEp instance.
* \param[out] support Output parameter set to the EP's weightless support scope.
*
* \snippet{doc} snippets.dox OrtStatus Return Value
*
* \note Implementation of this function is optional. If set to NULL, ORT assumes the EP does not
* support weightless mode (equivalent to OrtWeightlessSupport_NONE).
*
* \since Version 1.29.
*/
ORT_API2_STATUS(GetWeightlessSupport, _In_ const OrtEp* this_ptr, _Out_ OrtWeightlessSupport* support);
};

/** \brief The function signature that ORT will call to create OrtEpFactory instances.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,18 @@ static const char* const kOrtEpDevice_EpMetadataKey_LibraryPath = "library_path"
// if this metadata key is not present.
// - "1": OrtHardwareDevice is virtual.
static const char* const kOrtHardwareDevice_MetadataKey_IsVirtual = "is_virtual";

// Key for the execution provider's weightless mode support on a specific device.
Comment thread
chilo-ms marked this conversation as resolved.
// Set by the EP during GetSupportedDevices() via CreateEpDevice() metadata.
// The app can read it via EpDevice_EpMetadata() to check device-specific weightless capability
// before calling ModelCompilationOptions_SetWeightlessEnabled().
//
// Possible values:
// - "none": EP does not support weightless mode on this device. This is the assumed default value
// if this metadata key is not present.
// - "external_only": EP supports weightless mode for external initializers only (e.g., older
// hardware/driver that must transform internal constants).
// - "all": EP supports weightless mode for all initializers (internal and external).
//
// \since Version 1.29.
static const char* const kOrtEpDevice_EpMetadataKey_WeightlessSupport = "weightless_support";
Original file line number Diff line number Diff line change
Expand Up @@ -583,8 +583,53 @@ static const char* const kOrtSessionOptionsRecordEpGraphAssignmentInfo = "sessio
// Option values:
// - "0": disable. (default)
// - "1": enable.
//
// \deprecated Since version 1.29. Use "ep.enable_weightless" instead, which covers all initializers
// (internal and external) and works in both JIT and AOT flows.
static const char* const kOrtSessionOptionEpEnableWeightlessEpContextNodes = "ep.enable_weightless_ep_context_nodes";

// Enable weightless mode for all initializers (internal and external).
//
// When enabled, ONNX Runtime requests that the execution provider operate without embedding or copying
// constant initializers.
//
// This option works in both JIT (non-cached) and AOT (EPContext model) flows:
// - JIT: The EP should set drop_constant_initializers to false in OrtNodeFusionOptions so that ORT
// provides the initializer data as inputs to the compiled/fused node. The EP can then access these
// initializers at Compute() time via KernelContext_GetInput().
// NOTE: Extending the lifetime of initializer data obtained via ValueInfo_GetInitializerValue() during
// Compile() so that the EP can cache and reuse data pointers directly is planned but not yet implemented.
// - AOT: ORT generates EPContext models with weightless EPContext nodes. The EP should use the
// "onnx_model_filename" EPContext node attribute or the "ep.context_source_model_path" session option
// to locate the source model's initializer data when creating a session from the compiled model.
//
// ORT checks that the EP supports weightless mode by calling OrtEpApi::GetWeightlessSupport().
// If the EP does not support it, ORT returns an error.
//
// Option values:
// - "0": disable. (default)
// - "1": enable.
//
// \since Version 1.29.
static const char* const kOrtSessionOptionEpEnableWeightless = "ep.enable_weightless";

// Specifies the file path to the original (source) ONNX model when creating a session with a weightless
// EPContext model.
//
// When an EPContext model is generated with weightless mode ("ep.enable_weightless" = "1"), the compiled
// model may not contain the original initializer data. When creating a session from the compiled model,
// the EP needs to load the initializer data from the source model. This session option provides the
// runtime location of the source model, which may differ from the path used at compile time (stored in
// the EPContext node's "onnx_model_filename" attribute).
//
// If not set, the EP falls back to the "onnx_model_filename" attribute in the EPContext node.
//
// If the source model is available as a byte buffer rather than a file path, use
// OrtApi::SessionOptionsSetWeightlessSourceModelBuffer() instead.
//
// \since Version 1.29.
static const char* const kOrtSessionOptionEpContextSourceModelPath = "ep.context_source_model_path";
Comment thread
jambayk marked this conversation as resolved.

// Controls the intra-op thread pool size for a session.
// Value should be a base-10 int32 string.
// Equivalent to OrtApi::SetIntraOpNumThreads.
Expand Down
5 changes: 5 additions & 0 deletions onnxruntime/core/session/abi_session_options_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,9 @@ struct OrtSessionOptions {
// with GetProviderOptionPrefix returning 'ep.myep.'
// CUDAExecutionProvider uses the stable short prefix 'ep.cuda.'.
static std::string GetProviderOptionPrefix(const char* provider_name);

// Weightless source model buffer for EPContext sessions.
// Set via SessionOptionsSetWeightlessSourceModelBuffer.
const void* weightless_source_model_data = nullptr;
size_t weightless_source_model_data_size = 0;
};
18 changes: 18 additions & 0 deletions onnxruntime/core/session/compile_api.cc
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,22 @@ ORT_API_STATUS_IMPL(OrtCompileAPI::ModelCompilationOptions_SetInputModel,
API_IMPL_END
}

ORT_API_STATUS_IMPL(OrtCompileAPI::ModelCompilationOptions_SetWeightlessEnabled,
_In_ OrtModelCompilationOptions* ort_model_compile_options,
_In_ bool use_weightless) {
API_IMPL_BEGIN
#if !defined(ORT_MINIMAL_BUILD)
auto model_compile_options = reinterpret_cast<onnxruntime::ModelCompilationOptions*>(ort_model_compile_options);
ORT_API_RETURN_IF_STATUS_NOT_OK(model_compile_options->SetWeightlessEnabled(use_weightless));
return nullptr;
#else
ORT_UNUSED_PARAMETER(ort_model_compile_options);
ORT_UNUSED_PARAMETER(use_weightless);
return OrtApis::CreateStatus(ORT_NOT_IMPLEMENTED, "Compile API is not supported in this build");
#endif // !defined(ORT_MINIMAL_BUILD)
API_IMPL_END
}

ORT_API_STATUS_IMPL(OrtCompileAPI::CompileModel, _In_ const OrtEnv* env,
_In_ const OrtModelCompilationOptions* ort_model_compile_options) {
API_IMPL_BEGIN
Expand Down Expand Up @@ -367,6 +383,8 @@ static constexpr OrtCompileApi ort_compile_api = {

&OrtCompileAPI::ModelCompilationOptions_SetInputModel,
// End of Version 24 - DO NOT MODIFY ABOVE

&OrtCompileAPI::ModelCompilationOptions_SetWeightlessEnabled,
};

// checks that we don't violate the rule that the functions must remain in the slots they were originally assigned
Expand Down
4 changes: 4 additions & 0 deletions onnxruntime/core/session/compile_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,8 @@ ORT_API_STATUS_IMPL(ModelCompilationOptions_SetInputModel,
_In_ OrtModelCompilationOptions* model_compile_options,
_In_ const OrtModel* model);

ORT_API_STATUS_IMPL(ModelCompilationOptions_SetWeightlessEnabled,
_In_ OrtModelCompilationOptions* model_compile_options,
_In_ bool use_weightless);

} // namespace OrtCompileAPI
7 changes: 7 additions & 0 deletions onnxruntime/core/session/model_compilation_options.cc
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,13 @@ Status ModelCompilationOptions::SetGraphOptimizationLevel(GraphOptimizationLevel
return Status::OK();
}

Status ModelCompilationOptions::SetWeightlessEnabled(bool use_weightless) {
ORT_RETURN_IF_ERROR(
session_options_.value.config_options.AddConfigEntry(kOrtSessionOptionEpEnableWeightless,
use_weightless ? "1" : "0"));
return Status::OK();
}

Status ModelCompilationOptions::Check() const {
const ConfigOptions& config_options = session_options_.value.config_options;

Expand Down
8 changes: 8 additions & 0 deletions onnxruntime/core/session/model_compilation_options.h
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,14 @@ class ModelCompilationOptions {
/// <returns></returns>
Status SetGraphOptimizationLevel(GraphOptimizationLevel graph_optimization_level);

/// <summary>
/// Enable weightless mode for model compilation.
/// When enabled, the compiled EPContext model will not embed constant initializer data.
/// </summary>
/// <param name="use_weightless">True to enable weightless mode</param>
/// <returns>Status indicating potential error</returns>
Status SetWeightlessEnabled(bool use_weightless);

/// <summary>
/// Checks if the compilation options described by this object are valid.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ bool IsModelPackagePathSessionOption(std::string_view key) {
// Session-option config keys whose values are path references (sha256:<hex>, relative, or
// absolute) that must be resolved against the model package. Add new path-valued keys here.
return key == kOrtSessionOptionsModelExternalInitializersFileFolderPath ||
key == kOrtSessionOptionEpContextFilePath;
key == kOrtSessionOptionEpContextFilePath ||
key == kOrtSessionOptionEpContextSourceModelPath;
}

namespace {
Expand Down
19 changes: 19 additions & 0 deletions onnxruntime/core/session/onnxruntime_c_api.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2758,6 +2758,23 @@ ORT_API_STATUS_IMPL(OrtApis::SessionOptionsSetCustomJoinThreadFn, _Inout_ OrtSes
API_IMPL_END
}

ORT_API_STATUS_IMPL(OrtApis::SessionOptionsSetWeightlessSourceModelBuffer, _Inout_ OrtSessionOptions* options,
_In_ const void* source_model_data, _In_ size_t source_model_data_length) {
API_IMPL_BEGIN
if (source_model_data == nullptr) {
return OrtApis::CreateStatus(ORT_INVALID_ARGUMENT, "Invalid source model: data pointer is null");
}

if (source_model_data_length == 0) {
return OrtApis::CreateStatus(ORT_INVALID_ARGUMENT, "Invalid source model: data size is 0");
}

options->weightless_source_model_data = source_model_data;
options->weightless_source_model_data_size = source_model_data_length;
return nullptr;
API_IMPL_END
}

ORT_API(void, OrtApis::ReleaseValueInfo, _Frees_ptr_opt_ OrtValueInfo* value_info) {
delete value_info;
}
Expand Down Expand Up @@ -4918,6 +4935,8 @@ static constexpr OrtApi ort_api_1_to_29 = {
&OrtApis::GetExperimentalFunction,
&OrtApis::KernelContext_GetSyncStream,
// End of Version 28 - DO NOT MODIFY ABOVE (see above text for more information)

&OrtApis::SessionOptionsSetWeightlessSourceModelBuffer,
};

// OrtApiBase can never change as there is no way to know what version of OrtApiBase is returned by OrtGetApiBase.
Expand Down
4 changes: 4 additions & 0 deletions onnxruntime/core/session/ort_apis.h
Original file line number Diff line number Diff line change
Expand Up @@ -829,4 +829,8 @@ ORT_API_STATUS_IMPL(GetTensorElementTypeAndShapeDataReference, _In_ const OrtVal
// Experimental API
ORT_API(OrtExperimentalFnPtr, GetExperimentalFunction, _In_ const char* name);

// Weightless source model APIs
ORT_API_STATUS_IMPL(SessionOptionsSetWeightlessSourceModelBuffer, _Inout_ OrtSessionOptions* options,
_In_ const void* source_model_data, _In_ size_t source_model_data_length);

} // namespace OrtApis
Loading
Loading