edgeflowjs 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +473 -0
- package/dist/backends/index.d.ts +13 -0
- package/dist/backends/index.d.ts.map +1 -0
- package/dist/backends/index.js +32 -0
- package/dist/backends/index.js.map +1 -0
- package/dist/backends/onnx.d.ts +46 -0
- package/dist/backends/onnx.d.ts.map +1 -0
- package/dist/backends/onnx.js +249 -0
- package/dist/backends/onnx.js.map +1 -0
- package/dist/backends/wasm.d.ts +78 -0
- package/dist/backends/wasm.d.ts.map +1 -0
- package/dist/backends/wasm.js +358 -0
- package/dist/backends/wasm.js.map +1 -0
- package/dist/backends/webgpu.d.ts +143 -0
- package/dist/backends/webgpu.d.ts.map +1 -0
- package/dist/backends/webgpu.js +326 -0
- package/dist/backends/webgpu.js.map +1 -0
- package/dist/backends/webnn.d.ts +115 -0
- package/dist/backends/webnn.d.ts.map +1 -0
- package/dist/backends/webnn.js +202 -0
- package/dist/backends/webnn.js.map +1 -0
- package/dist/core/index.d.ts +9 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +14 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/memory.d.ts +234 -0
- package/dist/core/memory.d.ts.map +1 -0
- package/dist/core/memory.js +554 -0
- package/dist/core/memory.js.map +1 -0
- package/dist/core/runtime.d.ts +129 -0
- package/dist/core/runtime.d.ts.map +1 -0
- package/dist/core/runtime.js +352 -0
- package/dist/core/runtime.js.map +1 -0
- package/dist/core/scheduler.d.ts +118 -0
- package/dist/core/scheduler.d.ts.map +1 -0
- package/dist/core/scheduler.js +600 -0
- package/dist/core/scheduler.js.map +1 -0
- package/dist/core/tensor.d.ts +149 -0
- package/dist/core/tensor.d.ts.map +1 -0
- package/dist/core/tensor.js +719 -0
- package/dist/core/tensor.js.map +1 -0
- package/dist/core/types.d.ts +367 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +54 -0
- package/dist/core/types.js.map +1 -0
- package/dist/edgeflow.browser.js +5601 -0
- package/dist/edgeflow.browser.js.map +7 -0
- package/dist/edgeflow.browser.min.js +19 -0
- package/dist/edgeflow.browser.min.js.map +7 -0
- package/dist/index.d.ts +71 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +158 -0
- package/dist/index.js.map +1 -0
- package/dist/pipelines/base.d.ts +122 -0
- package/dist/pipelines/base.d.ts.map +1 -0
- package/dist/pipelines/base.js +155 -0
- package/dist/pipelines/base.js.map +1 -0
- package/dist/pipelines/feature-extraction.d.ts +68 -0
- package/dist/pipelines/feature-extraction.d.ts.map +1 -0
- package/dist/pipelines/feature-extraction.js +197 -0
- package/dist/pipelines/feature-extraction.js.map +1 -0
- package/dist/pipelines/image-classification.d.ts +61 -0
- package/dist/pipelines/image-classification.d.ts.map +1 -0
- package/dist/pipelines/image-classification.js +140 -0
- package/dist/pipelines/image-classification.js.map +1 -0
- package/dist/pipelines/index.d.ts +58 -0
- package/dist/pipelines/index.d.ts.map +1 -0
- package/dist/pipelines/index.js +72 -0
- package/dist/pipelines/index.js.map +1 -0
- package/dist/pipelines/text-classification.d.ts +71 -0
- package/dist/pipelines/text-classification.d.ts.map +1 -0
- package/dist/pipelines/text-classification.js +175 -0
- package/dist/pipelines/text-classification.js.map +1 -0
- package/dist/tools/index.d.ts +143 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +294 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/utils/cache.d.ts +162 -0
- package/dist/utils/cache.d.ts.map +1 -0
- package/dist/utils/cache.js +443 -0
- package/dist/utils/cache.js.map +1 -0
- package/dist/utils/index.d.ts +8 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +12 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/model-loader.d.ts +107 -0
- package/dist/utils/model-loader.d.ts.map +1 -0
- package/dist/utils/model-loader.js +694 -0
- package/dist/utils/model-loader.js.map +1 -0
- package/dist/utils/preprocessor.d.ts +147 -0
- package/dist/utils/preprocessor.d.ts.map +1 -0
- package/dist/utils/preprocessor.js +423 -0
- package/dist/utils/preprocessor.js.map +1 -0
- package/dist/utils/tokenizer.d.ts +140 -0
- package/dist/utils/tokenizer.d.ts.map +1 -0
- package/dist/utils/tokenizer.js +397 -0
- package/dist/utils/tokenizer.js.map +1 -0
- package/package.json +87 -0
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* edgeFlow.js - Text Classification Pipeline
|
|
3
|
+
*
|
|
4
|
+
* High-level API for text classification tasks including
|
|
5
|
+
* sentiment analysis, topic classification, etc.
|
|
6
|
+
*/
|
|
7
|
+
import { EdgeFlowTensor, softmax } from '../core/tensor.js';
|
|
8
|
+
import { createBasicTokenizer } from '../utils/tokenizer.js';
|
|
9
|
+
import { BasePipeline, registerPipeline, SENTIMENT_LABELS, } from './base.js';
|
|
10
|
+
/**
|
|
11
|
+
* TextClassificationPipeline - Classify text into categories
|
|
12
|
+
*/
|
|
13
|
+
export class TextClassificationPipeline extends BasePipeline {
|
|
14
|
+
tokenizer = null;
|
|
15
|
+
labels;
|
|
16
|
+
constructor(config, labels) {
|
|
17
|
+
super(config);
|
|
18
|
+
this.labels = labels ?? SENTIMENT_LABELS;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Initialize pipeline
|
|
22
|
+
*/
|
|
23
|
+
async initialize() {
|
|
24
|
+
await super.initialize();
|
|
25
|
+
// Initialize tokenizer
|
|
26
|
+
if (!this.tokenizer) {
|
|
27
|
+
this.tokenizer = createBasicTokenizer();
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Set custom labels
|
|
32
|
+
*/
|
|
33
|
+
setLabels(labels) {
|
|
34
|
+
this.labels = labels;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Run classification
|
|
38
|
+
*/
|
|
39
|
+
async run(input, options) {
|
|
40
|
+
const isBatch = Array.isArray(input);
|
|
41
|
+
const inputs = isBatch ? input : [input];
|
|
42
|
+
await this.initialize();
|
|
43
|
+
const startTime = performance.now();
|
|
44
|
+
const results = [];
|
|
45
|
+
for (const text of inputs) {
|
|
46
|
+
// Preprocess
|
|
47
|
+
const tensorInputs = await this.preprocess(text);
|
|
48
|
+
// Run inference
|
|
49
|
+
const outputs = await this.runInference(tensorInputs);
|
|
50
|
+
// Postprocess
|
|
51
|
+
const result = await this.postprocess(outputs, options);
|
|
52
|
+
results.push(result);
|
|
53
|
+
}
|
|
54
|
+
const processingTime = performance.now() - startTime;
|
|
55
|
+
// Add processing time to results
|
|
56
|
+
for (const result of results) {
|
|
57
|
+
result.processingTime = processingTime / results.length;
|
|
58
|
+
}
|
|
59
|
+
return isBatch ? results : results[0];
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Preprocess text input
|
|
63
|
+
*/
|
|
64
|
+
async preprocess(input) {
|
|
65
|
+
const text = Array.isArray(input) ? input[0] : input;
|
|
66
|
+
// Tokenize
|
|
67
|
+
const encoded = this.tokenizer.encode(text, {
|
|
68
|
+
maxLength: 128,
|
|
69
|
+
padding: 'max_length',
|
|
70
|
+
truncation: true,
|
|
71
|
+
});
|
|
72
|
+
// Create tensors
|
|
73
|
+
const inputIds = new EdgeFlowTensor(new Float32Array(encoded.inputIds), [1, encoded.inputIds.length], 'float32');
|
|
74
|
+
const attentionMask = new EdgeFlowTensor(new Float32Array(encoded.attentionMask), [1, encoded.attentionMask.length], 'float32');
|
|
75
|
+
return [inputIds, attentionMask];
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Run model inference
|
|
79
|
+
*/
|
|
80
|
+
async runInference(inputs) {
|
|
81
|
+
// For demo: generate mock logits based on input
|
|
82
|
+
// In production, this would call the actual model
|
|
83
|
+
const numClasses = this.labels.length;
|
|
84
|
+
const logits = new Float32Array(numClasses);
|
|
85
|
+
// Simple sentiment heuristic for demo
|
|
86
|
+
const inputData = inputs[0]?.toFloat32Array() ?? new Float32Array(0);
|
|
87
|
+
const sum = inputData.reduce((a, b) => a + b, 0);
|
|
88
|
+
// Generate pseudo-random but deterministic scores
|
|
89
|
+
for (let i = 0; i < numClasses; i++) {
|
|
90
|
+
logits[i] = Math.sin(sum * (i + 1)) * 2;
|
|
91
|
+
}
|
|
92
|
+
return [new EdgeFlowTensor(logits, [1, numClasses], 'float32')];
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Postprocess model outputs
|
|
96
|
+
*/
|
|
97
|
+
async postprocess(outputs, options) {
|
|
98
|
+
const logits = outputs[0];
|
|
99
|
+
if (!logits) {
|
|
100
|
+
return { label: 'unknown', score: 0 };
|
|
101
|
+
}
|
|
102
|
+
// Apply softmax
|
|
103
|
+
const probs = softmax(logits, -1);
|
|
104
|
+
const probsArray = probs.toFloat32Array();
|
|
105
|
+
// Get predictions
|
|
106
|
+
const topK = options?.topK ?? 1;
|
|
107
|
+
const returnAllScores = options?.returnAllScores ?? false;
|
|
108
|
+
if (returnAllScores || topK > 1) {
|
|
109
|
+
// Return multiple results - for simplicity, return top-1 here
|
|
110
|
+
// Full implementation would return sorted array
|
|
111
|
+
}
|
|
112
|
+
// Find argmax
|
|
113
|
+
let maxIdx = 0;
|
|
114
|
+
let maxScore = probsArray[0] ?? 0;
|
|
115
|
+
for (let i = 1; i < probsArray.length; i++) {
|
|
116
|
+
if ((probsArray[i] ?? 0) > maxScore) {
|
|
117
|
+
maxScore = probsArray[i] ?? 0;
|
|
118
|
+
maxIdx = i;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
const label = options?.labels?.[maxIdx] ?? this.labels[maxIdx] ?? `class_${maxIdx}`;
|
|
122
|
+
return {
|
|
123
|
+
label,
|
|
124
|
+
score: maxScore,
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
// ============================================================================
|
|
129
|
+
// Sentiment Analysis Pipeline
|
|
130
|
+
// ============================================================================
|
|
131
|
+
/**
|
|
132
|
+
* SentimentAnalysisPipeline - Specialized for sentiment analysis
|
|
133
|
+
*/
|
|
134
|
+
export class SentimentAnalysisPipeline extends TextClassificationPipeline {
|
|
135
|
+
constructor(config) {
|
|
136
|
+
super(config, SENTIMENT_LABELS);
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Analyze sentiment
|
|
140
|
+
*/
|
|
141
|
+
async analyze(text, options) {
|
|
142
|
+
return this.run(text, options);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
// ============================================================================
|
|
146
|
+
// Factory Functions
|
|
147
|
+
// ============================================================================
|
|
148
|
+
/**
|
|
149
|
+
* Create text classification pipeline
|
|
150
|
+
*/
|
|
151
|
+
export function createTextClassificationPipeline(config = {}) {
|
|
152
|
+
return new TextClassificationPipeline({
|
|
153
|
+
task: 'text-classification',
|
|
154
|
+
model: config.model ?? 'default',
|
|
155
|
+
runtime: config.runtime,
|
|
156
|
+
cache: config.cache ?? true,
|
|
157
|
+
quantization: config.quantization,
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Create sentiment analysis pipeline
|
|
162
|
+
*/
|
|
163
|
+
export function createSentimentAnalysisPipeline(config = {}) {
|
|
164
|
+
return new SentimentAnalysisPipeline({
|
|
165
|
+
task: 'sentiment-analysis',
|
|
166
|
+
model: config.model ?? 'default',
|
|
167
|
+
runtime: config.runtime,
|
|
168
|
+
cache: config.cache ?? true,
|
|
169
|
+
quantization: config.quantization,
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
// Register pipelines
|
|
173
|
+
registerPipeline('text-classification', (config) => new TextClassificationPipeline(config));
|
|
174
|
+
registerPipeline('sentiment-analysis', (config) => new SentimentAnalysisPipeline(config));
|
|
175
|
+
//# sourceMappingURL=text-classification.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"text-classification.js","sourceRoot":"","sources":["../../src/pipelines/text-classification.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* edgeFlow.js - Tools and Utilities
|
|
3
|
+
*
|
|
4
|
+
* Model optimization, quantization, and analysis tools.
|
|
5
|
+
*/
|
|
6
|
+
import { LoadedModel, QuantizationType } from '../core/types.js';
|
|
7
|
+
/**
|
|
8
|
+
* Quantization options
|
|
9
|
+
*/
|
|
10
|
+
export interface QuantizationOptions {
|
|
11
|
+
/** Quantization method */
|
|
12
|
+
method: QuantizationType;
|
|
13
|
+
/** Calibration data for calibrated quantization */
|
|
14
|
+
calibrationData?: Float32Array[];
|
|
15
|
+
/** Whether to quantize weights only */
|
|
16
|
+
weightsOnly?: boolean;
|
|
17
|
+
/** Layers to exclude from quantization */
|
|
18
|
+
excludeLayers?: string[];
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Quantization result
|
|
22
|
+
*/
|
|
23
|
+
export interface QuantizationResult {
|
|
24
|
+
/** Quantized model data */
|
|
25
|
+
modelData: ArrayBuffer;
|
|
26
|
+
/** Original size in bytes */
|
|
27
|
+
originalSize: number;
|
|
28
|
+
/** Quantized size in bytes */
|
|
29
|
+
quantizedSize: number;
|
|
30
|
+
/** Compression ratio */
|
|
31
|
+
compressionRatio: number;
|
|
32
|
+
/** Quantization statistics */
|
|
33
|
+
stats: {
|
|
34
|
+
layersQuantized: number;
|
|
35
|
+
layersSkipped: number;
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Quantize a model
|
|
40
|
+
*
|
|
41
|
+
* @example
|
|
42
|
+
* ```typescript
|
|
43
|
+
* const quantized = await quantize(model, {
|
|
44
|
+
* method: 'int8',
|
|
45
|
+
* calibrationData: samples,
|
|
46
|
+
* });
|
|
47
|
+
* ```
|
|
48
|
+
*/
|
|
49
|
+
export declare function quantize(model: LoadedModel | ArrayBuffer, options: QuantizationOptions): Promise<QuantizationResult>;
|
|
50
|
+
/**
|
|
51
|
+
* Pruning options
|
|
52
|
+
*/
|
|
53
|
+
export interface PruningOptions {
|
|
54
|
+
/** Target sparsity (0-1) */
|
|
55
|
+
sparsity: number;
|
|
56
|
+
/** Pruning method */
|
|
57
|
+
method?: 'magnitude' | 'random' | 'structured';
|
|
58
|
+
/** Layers to exclude */
|
|
59
|
+
excludeLayers?: string[];
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Pruning result
|
|
63
|
+
*/
|
|
64
|
+
export interface PruningResult {
|
|
65
|
+
/** Pruned model data */
|
|
66
|
+
modelData: ArrayBuffer;
|
|
67
|
+
/** Achieved sparsity */
|
|
68
|
+
actualSparsity: number;
|
|
69
|
+
/** Number of parameters pruned */
|
|
70
|
+
parametersPruned: number;
|
|
71
|
+
/** Total parameters */
|
|
72
|
+
totalParameters: number;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Prune model weights
|
|
76
|
+
*/
|
|
77
|
+
export declare function prune(model: LoadedModel | ArrayBuffer, options: PruningOptions): Promise<PruningResult>;
|
|
78
|
+
/**
|
|
79
|
+
* Model analysis result
|
|
80
|
+
*/
|
|
81
|
+
export interface ModelAnalysis {
|
|
82
|
+
/** Total number of parameters */
|
|
83
|
+
totalParameters: number;
|
|
84
|
+
/** Model size in bytes */
|
|
85
|
+
sizeBytes: number;
|
|
86
|
+
/** Layer information */
|
|
87
|
+
layers: Array<{
|
|
88
|
+
name: string;
|
|
89
|
+
type: string;
|
|
90
|
+
parameters: number;
|
|
91
|
+
inputShape: number[];
|
|
92
|
+
outputShape: number[];
|
|
93
|
+
}>;
|
|
94
|
+
/** Estimated FLOPs */
|
|
95
|
+
estimatedFlops: number;
|
|
96
|
+
/** Memory requirements */
|
|
97
|
+
memoryRequirements: {
|
|
98
|
+
weights: number;
|
|
99
|
+
activations: number;
|
|
100
|
+
total: number;
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Analyze a model
|
|
105
|
+
*/
|
|
106
|
+
export declare function analyzeModel(model: LoadedModel | ArrayBuffer): Promise<ModelAnalysis>;
|
|
107
|
+
/**
|
|
108
|
+
* Benchmark options
|
|
109
|
+
*/
|
|
110
|
+
export interface BenchmarkOptions {
|
|
111
|
+
/** Number of warmup runs */
|
|
112
|
+
warmupRuns?: number;
|
|
113
|
+
/** Number of benchmark runs */
|
|
114
|
+
runs?: number;
|
|
115
|
+
/** Input shape */
|
|
116
|
+
inputShape?: number[];
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Benchmark result
|
|
120
|
+
*/
|
|
121
|
+
export interface BenchmarkResult {
|
|
122
|
+
/** Average inference time in ms */
|
|
123
|
+
avgTime: number;
|
|
124
|
+
/** Minimum inference time in ms */
|
|
125
|
+
minTime: number;
|
|
126
|
+
/** Maximum inference time in ms */
|
|
127
|
+
maxTime: number;
|
|
128
|
+
/** Standard deviation */
|
|
129
|
+
stdDev: number;
|
|
130
|
+
/** Throughput (inferences per second) */
|
|
131
|
+
throughput: number;
|
|
132
|
+
/** All run times */
|
|
133
|
+
times: number[];
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Benchmark model inference
|
|
137
|
+
*/
|
|
138
|
+
export declare function benchmark(runFn: () => Promise<void>, options?: BenchmarkOptions): Promise<BenchmarkResult>;
|
|
139
|
+
/**
|
|
140
|
+
* Export model to different formats
|
|
141
|
+
*/
|
|
142
|
+
export declare function exportModel(model: LoadedModel | ArrayBuffer, format: 'onnx' | 'json' | 'binary'): Promise<ArrayBuffer | string>;
|
|
143
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* edgeFlow.js - Tools and Utilities
|
|
3
|
+
*
|
|
4
|
+
* Model optimization, quantization, and analysis tools.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Quantize a model
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```typescript
|
|
11
|
+
* const quantized = await quantize(model, {
|
|
12
|
+
* method: 'int8',
|
|
13
|
+
* calibrationData: samples,
|
|
14
|
+
* });
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
export async function quantize(model, options) {
|
|
18
|
+
// Get model data
|
|
19
|
+
const modelData = model instanceof ArrayBuffer
|
|
20
|
+
? model
|
|
21
|
+
: await getModelData(model);
|
|
22
|
+
const originalSize = modelData.byteLength;
|
|
23
|
+
// Apply quantization based on method
|
|
24
|
+
let quantizedData;
|
|
25
|
+
let layersQuantized = 0;
|
|
26
|
+
let layersSkipped = 0;
|
|
27
|
+
switch (options.method) {
|
|
28
|
+
case 'int8':
|
|
29
|
+
({ data: quantizedData, layersQuantized, layersSkipped } =
|
|
30
|
+
quantizeInt8(modelData, options));
|
|
31
|
+
break;
|
|
32
|
+
case 'uint8':
|
|
33
|
+
({ data: quantizedData, layersQuantized, layersSkipped } =
|
|
34
|
+
quantizeUint8(modelData, options));
|
|
35
|
+
break;
|
|
36
|
+
case 'float16':
|
|
37
|
+
({ data: quantizedData, layersQuantized, layersSkipped } =
|
|
38
|
+
quantizeFloat16(modelData, options));
|
|
39
|
+
break;
|
|
40
|
+
case 'int4':
|
|
41
|
+
({ data: quantizedData, layersQuantized, layersSkipped } =
|
|
42
|
+
quantizeInt4(modelData, options));
|
|
43
|
+
break;
|
|
44
|
+
default:
|
|
45
|
+
quantizedData = modelData;
|
|
46
|
+
}
|
|
47
|
+
return {
|
|
48
|
+
modelData: quantizedData,
|
|
49
|
+
originalSize,
|
|
50
|
+
quantizedSize: quantizedData.byteLength,
|
|
51
|
+
compressionRatio: originalSize / quantizedData.byteLength,
|
|
52
|
+
stats: {
|
|
53
|
+
layersQuantized,
|
|
54
|
+
layersSkipped,
|
|
55
|
+
},
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Placeholder for getting model data
|
|
60
|
+
*/
|
|
61
|
+
async function getModelData(_model) {
|
|
62
|
+
// In production, this would extract the model weights
|
|
63
|
+
return new ArrayBuffer(0);
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* INT8 quantization
|
|
67
|
+
*/
|
|
68
|
+
function quantizeInt8(data, _options) {
|
|
69
|
+
// Simplified INT8 quantization
|
|
70
|
+
const input = new Float32Array(data);
|
|
71
|
+
const output = new Int8Array(input.length);
|
|
72
|
+
// Find scale
|
|
73
|
+
let max = 0;
|
|
74
|
+
for (let i = 0; i < input.length; i++) {
|
|
75
|
+
const abs = Math.abs(input[i] ?? 0);
|
|
76
|
+
if (abs > max)
|
|
77
|
+
max = abs;
|
|
78
|
+
}
|
|
79
|
+
const scale = max / 127;
|
|
80
|
+
// Quantize
|
|
81
|
+
for (let i = 0; i < input.length; i++) {
|
|
82
|
+
output[i] = Math.round((input[i] ?? 0) / scale);
|
|
83
|
+
}
|
|
84
|
+
return {
|
|
85
|
+
data: output.buffer,
|
|
86
|
+
layersQuantized: 1,
|
|
87
|
+
layersSkipped: 0,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* UINT8 quantization
|
|
92
|
+
*/
|
|
93
|
+
function quantizeUint8(data, _options) {
|
|
94
|
+
const input = new Float32Array(data);
|
|
95
|
+
const output = new Uint8Array(input.length);
|
|
96
|
+
// Find min/max
|
|
97
|
+
let min = Infinity, max = -Infinity;
|
|
98
|
+
for (let i = 0; i < input.length; i++) {
|
|
99
|
+
const val = input[i] ?? 0;
|
|
100
|
+
if (val < min)
|
|
101
|
+
min = val;
|
|
102
|
+
if (val > max)
|
|
103
|
+
max = val;
|
|
104
|
+
}
|
|
105
|
+
const scale = (max - min) / 255;
|
|
106
|
+
// Quantize
|
|
107
|
+
for (let i = 0; i < input.length; i++) {
|
|
108
|
+
output[i] = Math.round(((input[i] ?? 0) - min) / scale);
|
|
109
|
+
}
|
|
110
|
+
return {
|
|
111
|
+
data: output.buffer,
|
|
112
|
+
layersQuantized: 1,
|
|
113
|
+
layersSkipped: 0,
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Float16 quantization
|
|
118
|
+
*/
|
|
119
|
+
function quantizeFloat16(data, _options) {
|
|
120
|
+
const input = new Float32Array(data);
|
|
121
|
+
const output = new Uint16Array(input.length);
|
|
122
|
+
// Convert float32 to float16
|
|
123
|
+
for (let i = 0; i < input.length; i++) {
|
|
124
|
+
output[i] = float32ToFloat16(input[i] ?? 0);
|
|
125
|
+
}
|
|
126
|
+
return {
|
|
127
|
+
data: output.buffer,
|
|
128
|
+
layersQuantized: 1,
|
|
129
|
+
layersSkipped: 0,
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* INT4 quantization
|
|
134
|
+
*/
|
|
135
|
+
function quantizeInt4(data, _options) {
|
|
136
|
+
const input = new Float32Array(data);
|
|
137
|
+
// Pack two INT4 values per byte
|
|
138
|
+
const output = new Uint8Array(Math.ceil(input.length / 2));
|
|
139
|
+
// Find scale
|
|
140
|
+
let max = 0;
|
|
141
|
+
for (let i = 0; i < input.length; i++) {
|
|
142
|
+
const abs = Math.abs(input[i] ?? 0);
|
|
143
|
+
if (abs > max)
|
|
144
|
+
max = abs;
|
|
145
|
+
}
|
|
146
|
+
const scale = max / 7; // INT4 range: -8 to 7
|
|
147
|
+
// Quantize and pack
|
|
148
|
+
for (let i = 0; i < input.length; i += 2) {
|
|
149
|
+
const val1 = Math.round((input[i] ?? 0) / scale) + 8;
|
|
150
|
+
const val2 = Math.round((input[i + 1] ?? 0) / scale) + 8;
|
|
151
|
+
output[i / 2] = ((val1 & 0xF) << 4) | (val2 & 0xF);
|
|
152
|
+
}
|
|
153
|
+
return {
|
|
154
|
+
data: output.buffer,
|
|
155
|
+
layersQuantized: 1,
|
|
156
|
+
layersSkipped: 0,
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Convert float32 to float16
|
|
161
|
+
*/
|
|
162
|
+
function float32ToFloat16(value) {
|
|
163
|
+
const floatView = new Float32Array(1);
|
|
164
|
+
const int32View = new Int32Array(floatView.buffer);
|
|
165
|
+
floatView[0] = value;
|
|
166
|
+
const x = int32View[0] ?? 0;
|
|
167
|
+
let bits = (x >> 16) & 0x8000; // sign
|
|
168
|
+
let m = (x >> 12) & 0x07ff; // mantissa
|
|
169
|
+
const e = (x >> 23) & 0xff; // exponent
|
|
170
|
+
if (e < 103) {
|
|
171
|
+
// Too small, return zero
|
|
172
|
+
return bits;
|
|
173
|
+
}
|
|
174
|
+
if (e > 142) {
|
|
175
|
+
// Too large, return infinity
|
|
176
|
+
bits |= 0x7c00;
|
|
177
|
+
bits |= ((e === 255) ? 0 : 1) && (x & 0x007fffff);
|
|
178
|
+
return bits;
|
|
179
|
+
}
|
|
180
|
+
if (e < 113) {
|
|
181
|
+
// Denormalized
|
|
182
|
+
m |= 0x0800;
|
|
183
|
+
bits |= (m >> (114 - e)) + ((m >> (113 - e)) & 1);
|
|
184
|
+
return bits;
|
|
185
|
+
}
|
|
186
|
+
bits |= ((e - 112) << 10) | (m >> 1);
|
|
187
|
+
bits += m & 1;
|
|
188
|
+
return bits;
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Prune model weights
|
|
192
|
+
*/
|
|
193
|
+
export async function prune(model, options) {
|
|
194
|
+
const modelData = model instanceof ArrayBuffer
|
|
195
|
+
? model
|
|
196
|
+
: await getModelData(model);
|
|
197
|
+
const weights = new Float32Array(modelData);
|
|
198
|
+
const total = weights.length;
|
|
199
|
+
// Calculate threshold for magnitude pruning
|
|
200
|
+
const magnitudes = weights.map(Math.abs);
|
|
201
|
+
const sorted = [...magnitudes].sort((a, b) => a - b);
|
|
202
|
+
const thresholdIdx = Math.floor(options.sparsity * sorted.length);
|
|
203
|
+
const threshold = sorted[thresholdIdx] ?? 0;
|
|
204
|
+
// Prune weights
|
|
205
|
+
let pruned = 0;
|
|
206
|
+
for (let i = 0; i < weights.length; i++) {
|
|
207
|
+
if (Math.abs(weights[i] ?? 0) < threshold) {
|
|
208
|
+
weights[i] = 0;
|
|
209
|
+
pruned++;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
return {
|
|
213
|
+
modelData: weights.buffer,
|
|
214
|
+
actualSparsity: pruned / total,
|
|
215
|
+
parametersPruned: pruned,
|
|
216
|
+
totalParameters: total,
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Analyze a model
|
|
221
|
+
*/
|
|
222
|
+
export async function analyzeModel(model) {
|
|
223
|
+
// Simplified analysis
|
|
224
|
+
const size = model instanceof ArrayBuffer
|
|
225
|
+
? model.byteLength
|
|
226
|
+
: model.metadata.sizeBytes;
|
|
227
|
+
const estimatedParams = Math.floor(size / 4); // Assume float32
|
|
228
|
+
return {
|
|
229
|
+
totalParameters: estimatedParams,
|
|
230
|
+
sizeBytes: size,
|
|
231
|
+
layers: [],
|
|
232
|
+
estimatedFlops: estimatedParams * 2, // Rough estimate
|
|
233
|
+
memoryRequirements: {
|
|
234
|
+
weights: size,
|
|
235
|
+
activations: size * 0.1, // Rough estimate
|
|
236
|
+
total: size * 1.1,
|
|
237
|
+
},
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* Benchmark model inference
|
|
242
|
+
*/
|
|
243
|
+
export async function benchmark(runFn, options = {}) {
|
|
244
|
+
const { warmupRuns = 3, runs = 10, } = options;
|
|
245
|
+
// Warmup
|
|
246
|
+
for (let i = 0; i < warmupRuns; i++) {
|
|
247
|
+
await runFn();
|
|
248
|
+
}
|
|
249
|
+
// Benchmark
|
|
250
|
+
const times = [];
|
|
251
|
+
for (let i = 0; i < runs; i++) {
|
|
252
|
+
const start = performance.now();
|
|
253
|
+
await runFn();
|
|
254
|
+
times.push(performance.now() - start);
|
|
255
|
+
}
|
|
256
|
+
// Calculate statistics
|
|
257
|
+
const sum = times.reduce((a, b) => a + b, 0);
|
|
258
|
+
const avgTime = sum / times.length;
|
|
259
|
+
const minTime = Math.min(...times);
|
|
260
|
+
const maxTime = Math.max(...times);
|
|
261
|
+
const squaredDiffs = times.map(t => Math.pow(t - avgTime, 2));
|
|
262
|
+
const avgSquaredDiff = squaredDiffs.reduce((a, b) => a + b, 0) / times.length;
|
|
263
|
+
const stdDev = Math.sqrt(avgSquaredDiff);
|
|
264
|
+
return {
|
|
265
|
+
avgTime,
|
|
266
|
+
minTime,
|
|
267
|
+
maxTime,
|
|
268
|
+
stdDev,
|
|
269
|
+
throughput: 1000 / avgTime,
|
|
270
|
+
times,
|
|
271
|
+
};
|
|
272
|
+
}
|
|
273
|
+
// ============================================================================
|
|
274
|
+
// Export Utilities
|
|
275
|
+
// ============================================================================
|
|
276
|
+
/**
|
|
277
|
+
* Export model to different formats
|
|
278
|
+
*/
|
|
279
|
+
export async function exportModel(model, format) {
|
|
280
|
+
const modelData = model instanceof ArrayBuffer
|
|
281
|
+
? model
|
|
282
|
+
: await getModelData(model);
|
|
283
|
+
switch (format) {
|
|
284
|
+
case 'json':
|
|
285
|
+
// Export as JSON (for small models)
|
|
286
|
+
const array = new Float32Array(modelData);
|
|
287
|
+
return JSON.stringify(Array.from(array));
|
|
288
|
+
case 'binary':
|
|
289
|
+
case 'onnx':
|
|
290
|
+
default:
|
|
291
|
+
return modelData;
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"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"}
|