0
# File System and HTTP IO
1
2
TensorFlow.js Node extends the standard TensorFlow.js IO capabilities with Node.js-specific handlers for file system operations and HTTP requests. This enables saving and loading models using the native file system and fetching models from remote servers with enhanced Node.js features.
3
4
## Capabilities
5
6
### File System Operations
7
8
#### File System Handler
9
10
Create an IO handler for saving and loading models using the Node.js file system.
11
12
```typescript { .api }
13
/**
14
* Create a file system IO handler for model persistence
15
* @param path - File path or array of paths for saving/loading models
16
* @returns IOHandler for file system operations
17
*/
18
function fileSystem(path: string | string[]): IOHandler;
19
```
20
21
**Usage Examples:**
22
23
```typescript
24
import * as tf from '@tensorflow/tfjs-node';
25
26
// Create a simple model
27
const model = tf.sequential({
28
layers: [
29
tf.layers.dense({ inputShape: [4], units: 10, activation: 'relu' }),
30
tf.layers.dense({ units: 3, activation: 'softmax' })
31
]
32
});
33
34
model.compile({ optimizer: 'adam', loss: 'sparseCategoricalCrossentropy' });
35
36
// Save model to file system
37
await model.save(tf.io.fileSystem('./my-model'));
38
// This creates:
39
// ./my-model/model.json (model topology and training config)
40
// ./my-model/weights.bin (model weights)
41
42
// Load model from file system
43
const loadedModel = await tf.loadLayersModel(tf.io.fileSystem('./my-model/model.json'));
44
45
// Alternative: Use file:// URL scheme (automatically routed to fileSystem)
46
await model.save('file://./my-model-alt');
47
const altLoadedModel = await tf.loadLayersModel('file://./my-model-alt/model.json');
48
```
49
50
#### File System with Custom Paths
51
52
```typescript
53
// Save with separate paths for model and weights
54
const customHandler = tf.io.fileSystem([
55
'./models/model.json',
56
'./weights/weights.bin'
57
]);
58
59
await model.save(customHandler);
60
61
// Load from custom paths
62
const loadedCustomModel = await tf.loadLayersModel(tf.io.fileSystem('./models/model.json'));
63
```
64
65
#### File System Router
66
67
Automatic routing for file:// URLs to the file system handler.
68
69
```typescript { .api }
70
/**
71
* Router function for file:// URLs (automatically registered)
72
* @param url - File URL or path
73
* @returns FileSystem IOHandler or null if not a file URL
74
*/
75
function nodeFileSystemRouter(url: string | string[]): IOHandler | null;
76
```
77
78
The file system router is automatically registered and handles `file://` URLs:
79
80
```typescript
81
// These are equivalent:
82
await model.save('file://./my-model');
83
await model.save(tf.io.fileSystem('./my-model'));
84
85
// Router handles various file URL formats
86
await model.save('file:///absolute/path/to/model');
87
await model.save('file://./relative/path/to/model');
88
```
89
90
### HTTP Operations
91
92
#### HTTP Request Handler
93
94
Create an IO handler for loading models from HTTP/HTTPS URLs with Node.js-specific features.
95
96
```typescript { .api }
97
/**
98
* Create an HTTP handler for loading models from URLs
99
* @param path - URL to the model.json file
100
* @param requestInit - Fetch options (headers, method, etc.)
101
* @param weightPathPrefix - Custom prefix for weight file URLs
102
* @returns IOHandler for HTTP operations
103
*/
104
function nodeHTTPRequest(
105
path: string,
106
requestInit?: RequestInit,
107
weightPathPrefix?: string
108
): IOHandler;
109
```
110
111
**Usage Examples:**
112
113
```typescript
114
// Load model from HTTP URL
115
const httpModel = await tf.loadLayersModel(
116
tf.io.nodeHTTPRequest('https://example.com/models/my-model.json')
117
);
118
119
// Load with custom headers
120
const authenticatedModel = await tf.loadLayersModel(
121
tf.io.nodeHTTPRequest(
122
'https://api.example.com/models/my-model.json',
123
{
124
headers: {
125
'Authorization': 'Bearer your-token-here',
126
'User-Agent': 'TensorFlow.js-Node/4.22.0'
127
}
128
}
129
)
130
);
131
132
// Load with custom weight path prefix
133
const cdnModel = await tf.loadLayersModel(
134
tf.io.nodeHTTPRequest(
135
'https://api.example.com/models/my-model.json',
136
undefined,
137
'https://cdn.example.com/weights/' // Weights served from different domain
138
)
139
);
140
```
141
142
#### HTTP Router
143
144
Automatic routing for HTTP/HTTPS URLs.
145
146
```typescript { .api }
147
/**
148
* Router function for HTTP/HTTPS URLs (automatically registered)
149
* @param url - HTTP or HTTPS URL
150
* @returns HTTP IOHandler or null if not an HTTP URL
151
*/
152
function nodeHTTPRequestRouter(url: string): IOHandler | null;
153
```
154
155
The HTTP router is automatically registered and handles HTTP/HTTPS URLs:
156
157
```typescript
158
// These are equivalent:
159
const model1 = await tf.loadLayersModel('https://example.com/model.json');
160
const model2 = await tf.loadLayersModel(
161
tf.io.nodeHTTPRequest('https://example.com/model.json')
162
);
163
```
164
165
## Enhanced IO Namespace
166
167
The `io` namespace is extended with Node.js-specific handlers:
168
169
```typescript { .api }
170
const io: {
171
// All standard tf.io functionality plus:
172
fileSystem: (path: string | string[]) => IOHandler;
173
nodeHTTPRequest: (path: string, requestInit?: RequestInit, weightPathPrefix?: string) => IOHandler;
174
175
// Standard tf.io handlers also available:
176
browserFiles: (files: File | File[]) => IOHandler;
177
browserHTTPRequest: (path: string, requestInit?: RequestInit) => IOHandler;
178
indexedDB: (modelURL: string) => IOHandler;
179
localStorage: (modelURL: string) => IOHandler;
180
// ... other standard handlers
181
};
182
```
183
184
185
## Common Usage Patterns
186
187
### Model Version Management
188
189
```typescript
190
async function saveModelVersions(model: tf.LayersModel, version: string) {
191
const baseDir = './models';
192
const versionDir = `${baseDir}/v${version}`;
193
194
// Save current version
195
await model.save(tf.io.fileSystem(versionDir));
196
197
// Also save as 'latest'
198
await model.save(tf.io.fileSystem(`${baseDir}/latest`));
199
200
console.log(`Model saved as version ${version} and latest`);
201
}
202
203
async function loadLatestModel(): Promise<tf.LayersModel> {
204
try {
205
return await tf.loadLayersModel(tf.io.fileSystem('./models/latest/model.json'));
206
} catch (error) {
207
console.error('Could not load latest model:', error);
208
throw error;
209
}
210
}
211
```
212
213
### Progressive Model Loading
214
215
```typescript
216
async function loadModelWithFallback(urls: string[]): Promise<tf.LayersModel> {
217
for (const url of urls) {
218
try {
219
console.log(`Attempting to load model from ${url}`);
220
const model = await tf.loadLayersModel(url);
221
console.log(`Successfully loaded model from ${url}`);
222
return model;
223
} catch (error) {
224
console.warn(`Failed to load from ${url}:`, error.message);
225
continue;
226
}
227
}
228
throw new Error('All model loading attempts failed');
229
}
230
231
// Usage
232
const model = await loadModelWithFallback([
233
'https://cdn.example.com/models/latest.json',
234
'https://backup.example.com/models/latest.json',
235
'file://./local-models/fallback.json'
236
]);
237
```
238
239
### Authenticated Model Loading
240
241
```typescript
242
async function loadProtectedModel(modelUrl: string, apiKey: string): Promise<tf.LayersModel> {
243
const handler = tf.io.nodeHTTPRequest(modelUrl, {
244
headers: {
245
'Authorization': `Bearer ${apiKey}`,
246
'Content-Type': 'application/json',
247
'User-Agent': 'MyApp/1.0.0'
248
},
249
timeout: 30000 // 30 second timeout
250
});
251
252
return await tf.loadLayersModel(handler);
253
}
254
```
255
256
### Custom Weight Path Resolution
257
258
```typescript
259
async function loadModelWithCDN(modelJsonUrl: string, cdnBaseUrl: string): Promise<tf.LayersModel> {
260
// Load model where weights are served from a different CDN
261
const handler = tf.io.nodeHTTPRequest(
262
modelJsonUrl,
263
{
264
headers: {
265
'Cache-Control': 'no-cache' // Always get latest model definition
266
}
267
},
268
cdnBaseUrl // All weight files will be loaded from this base URL
269
);
270
271
return await tf.loadLayersModel(handler);
272
}
273
274
// Usage
275
const model = await loadModelWithCDN(
276
'https://api.example.com/models/image-classifier.json',
277
'https://weights-cdn.example.com/v2/'
278
);
279
```
280
281
### Model Export with Custom Structure
282
283
```typescript
284
async function exportModelWithMetadata(
285
model: tf.LayersModel,
286
exportPath: string,
287
metadata: any
288
) {
289
// Save the model
290
await model.save(tf.io.fileSystem(exportPath));
291
292
// Save additional metadata
293
const fs = require('fs');
294
const path = require('path');
295
296
const metadataPath = path.join(exportPath, 'metadata.json');
297
fs.writeFileSync(metadataPath, JSON.stringify(metadata, null, 2));
298
299
// Create a manifest file
300
const manifest = {
301
modelPath: 'model.json',
302
weightsPath: 'weights.bin',
303
metadataPath: 'metadata.json',
304
exportedAt: new Date().toISOString(),
305
tfVersion: tf.version.tfjs
306
};
307
308
const manifestPath = path.join(exportPath, 'manifest.json');
309
fs.writeFileSync(manifestPath, JSON.stringify(manifest, null, 2));
310
311
console.log(`Model exported to ${exportPath} with metadata and manifest`);
312
}
313
```
314
315
## Types
316
317
```typescript { .api }
318
interface IOHandler {
319
load?(): Promise<ModelArtifacts>;
320
save?(modelArtifacts: ModelArtifacts): Promise<SaveResult>;
321
}
322
323
interface ModelArtifacts {
324
modelTopology: {} | ArrayBuffer;
325
weightSpecs?: WeightsManifestEntry[];
326
weightData?: ArrayBuffer;
327
format?: string;
328
generatedBy?: string;
329
convertedBy?: string;
330
signature?: {};
331
userDefinedMetadata?: {[key: string]: unknown};
332
modelInitializer?: {};
333
trainingConfig?: TrainingConfig;
334
}
335
336
interface SaveResult {
337
modelArtifactsInfo: ModelArtifactsInfo;
338
responses?: Response[];
339
}
340
341
interface ModelArtifactsInfo {
342
dateSaved: Date;
343
modelTopologyType: 'JSON' | 'Protobuf';
344
modelTopologyBytes?: number;
345
weightSpecsBytes?: number;
346
weightDataBytes?: number;
347
}
348
349
// Node.js-specific RequestInit interface
350
interface RequestInit {
351
method?: string;
352
headers?: Record<string, string>;
353
body?: string | Buffer | ArrayBuffer;
354
timeout?: number;
355
agent?: any; // HTTP/HTTPS agent
356
}
357
```