* Save model artifacts to browser local storage. * * See the documentation to `browserLocalStorage` for details on the saved * artifacts. * * @param modelArtifacts The model artifacts to be stored. * @returns An instance of SaveResult.
(modelArtifacts: ModelArtifacts)
| 164 | * @returns An instance of SaveResult. |
| 165 | */ |
| 166 | async save(modelArtifacts: ModelArtifacts): Promise<SaveResult> { |
| 167 | if (modelArtifacts.modelTopology instanceof ArrayBuffer) { |
| 168 | throw new Error( |
| 169 | 'BrowserLocalStorage.save() does not support saving model topology ' + |
| 170 | 'in binary formats yet.'); |
| 171 | } else { |
| 172 | const topology = JSON.stringify(modelArtifacts.modelTopology); |
| 173 | const weightSpecs = JSON.stringify(modelArtifacts.weightSpecs); |
| 174 | |
| 175 | const modelArtifactsInfo: ModelArtifactsInfo = |
| 176 | getModelArtifactsInfoForJSON(modelArtifacts); |
| 177 | |
| 178 | // TODO(mattsoulanille): Support saving models over 2GB that exceed |
| 179 | // Chrome's ArrayBuffer size limit. |
| 180 | const weightBuffer = CompositeArrayBuffer.join(modelArtifacts.weightData); |
| 181 | |
| 182 | try { |
| 183 | this.LS.setItem(this.keys.info, JSON.stringify(modelArtifactsInfo)); |
| 184 | this.LS.setItem(this.keys.topology, topology); |
| 185 | this.LS.setItem(this.keys.weightSpecs, weightSpecs); |
| 186 | this.LS.setItem( |
| 187 | this.keys.weightData, |
| 188 | arrayBufferToBase64String(weightBuffer)); |
| 189 | |
| 190 | // Note that JSON.stringify doesn't write out keys that have undefined |
| 191 | // values, so for some keys, we set undefined instead of a null-ish |
| 192 | // value. |
| 193 | const metadata: Required<ModelMetadata> = { |
| 194 | format: modelArtifacts.format, |
| 195 | generatedBy: modelArtifacts.generatedBy, |
| 196 | convertedBy: modelArtifacts.convertedBy, |
| 197 | signature: modelArtifacts.signature != null ? |
| 198 | modelArtifacts.signature : |
| 199 | undefined, |
| 200 | userDefinedMetadata: modelArtifacts.userDefinedMetadata != null ? |
| 201 | modelArtifacts.userDefinedMetadata : |
| 202 | undefined, |
| 203 | modelInitializer: modelArtifacts.modelInitializer != null ? |
| 204 | modelArtifacts.modelInitializer : |
| 205 | undefined, |
| 206 | initializerSignature: modelArtifacts.initializerSignature != null ? |
| 207 | modelArtifacts.initializerSignature : |
| 208 | undefined, |
| 209 | trainingConfig: modelArtifacts.trainingConfig != null ? |
| 210 | modelArtifacts.trainingConfig : |
| 211 | undefined |
| 212 | }; |
| 213 | this.LS.setItem(this.keys.modelMetadata, JSON.stringify(metadata)); |
| 214 | |
| 215 | return {modelArtifactsInfo}; |
| 216 | } catch (err) { |
| 217 | // If saving failed, clean up all items saved so far. |
| 218 | removeItems(this.keys); |
| 219 | |
| 220 | throw new Error( |
| 221 | `Failed to save model '${this.modelPath}' to local storage: ` + |
| 222 | `size quota being exceeded is a possible cause of this failure: ` + |
| 223 | `modelTopologyBytes=${modelArtifactsInfo.modelTopologyBytes}, ` + |
nothing calls this directly
no test coverage detected