diff --git a/js/common/lib/backend.ts b/js/common/lib/backend.ts index 20dca8942d..5460ae086f 100644 --- a/js/common/lib/backend.ts +++ b/js/common/lib/backend.ts @@ -48,6 +48,7 @@ export interface TrainingSessionHandler extends SessionHandler { readonly evalInputNames: readonly string[]; readonly evalOutputNames: readonly string[]; + lazyResetGrad(): Promise; runTrainStep( feeds: SessionHandler.FeedsType, fetches: SessionHandler.FetchesType, options: InferenceSession.RunOptions): Promise; diff --git a/js/common/lib/training-session-impl.ts b/js/common/lib/training-session-impl.ts index 5260b54b69..23bd4421ae 100644 --- a/js/common/lib/training-session-impl.ts +++ b/js/common/lib/training-session-impl.ts @@ -192,6 +192,10 @@ export class TrainingSession implements TrainingSessionInterface { return returnValue; } + async lazyResetGrad(): Promise { + await this.handler.lazyResetGrad(); + } + runTrainStep(feeds: FeedsType, options?: RunOptions): Promise; runTrainStep(feeds: FeedsType, fetches: FetchesType, options?: RunOptions): Promise; async runTrainStep(feeds: FeedsType, arg1?: FetchesType|RunOptions, arg2?: RunOptions): Promise { diff --git a/js/common/lib/training-session.ts b/js/common/lib/training-session.ts index 0cd35ee6c4..e54aed90e7 100644 --- a/js/common/lib/training-session.ts +++ b/js/common/lib/training-session.ts @@ -22,6 +22,12 @@ export declare namespace TrainingSession { export interface TrainingSession { // #region run() + /** + * Lazily resets the gradients of all trainable parameters to zero. Should happen after the invocation of + * runOptimizerStep. + */ + lazyResetGrad(): Promise; + /** * Run TrainStep asynchronously with the given feeds and options. * diff --git a/js/web/lib/wasm/session-handler-training.ts b/js/web/lib/wasm/session-handler-training.ts index 721669b2fc..71815f21e6 100644 --- a/js/web/lib/wasm/session-handler-training.ts +++ b/js/web/lib/wasm/session-handler-training.ts @@ -6,7 +6,7 @@ import {env, InferenceSession, OnnxValue, SessionHandler, Tensor, TrainingSessio import {SerializableModeldata, TensorMetadata} from './proxy-messages'; import {decodeTensorMetadata, encodeTensorMetadata} from './session-handler-inference'; import {createSessionAllocate, initRuntime, isOrtEnvInitialized} from './wasm-core-impl'; -import {createCheckpointHandle, createTrainingSessionHandle, getContiguousParameters, getModelInputOutputNames, getParametersSize, loadParametersBuffer, releaseTrainingSessionAndCheckpoint, runEvalStep, runOptimizerStep, runTrainStep} from './wasm-training-core-impl'; +import {createCheckpointHandle, createTrainingSessionHandle, getContiguousParameters, getModelInputOutputNames, getParametersSize, lazyResetGrad, loadParametersBuffer, releaseTrainingSessionAndCheckpoint, runEvalStep, runOptimizerStep, runTrainStep} from './wasm-training-core-impl'; export class OnnxruntimeWebAssemblyTrainingSessionHandler implements TrainingSessionHandler { private sessionId: number; @@ -105,6 +105,10 @@ export class OnnxruntimeWebAssemblyTrainingSessionHandler implements TrainingSes return resultMap; } + async lazyResetGrad(): Promise { + await lazyResetGrad(this.sessionId); + } + async runTrainStep( feeds: SessionHandler.FeedsType, fetches: SessionHandler.FetchesType, options: InferenceSession.RunOptions): Promise { diff --git a/js/web/lib/wasm/wasm-training-core-impl.ts b/js/web/lib/wasm/wasm-training-core-impl.ts index 3aea4e308e..0cc28188a6 100644 --- a/js/web/lib/wasm/wasm-training-core-impl.ts +++ b/js/web/lib/wasm/wasm-training-core-impl.ts @@ -253,6 +253,17 @@ const moveOutputToTensorMetadataArr = return output; }; +export const lazyResetGrad = async(trainingSessionId: number): Promise => { + const wasm = getInstance(); + + if (wasm._OrtTrainingLazyResetGrad) { + const errorCode = wasm._OrtTrainingLazyResetGrad(trainingSessionId); + ifErrCodeCheckLastError(errorCode, 'Can\'t call lazyResetGrad.'); + } else { + throw new Error(NO_TRAIN_FUNCS_MSG); + } +}; + export const runTrainStep = async( trainingSessionId: number, inputIndices: number[], inputTensors: TensorMetadata[], outputIndices: number[], outputTensors: Array, options: InferenceSession.RunOptions): Promise => {