Skip to content

Commit f88580e

Browse files
authored
Merge pull request #238 from kmiller68/transformers-js-loads-resources-at-runtime
Transformers.js line items shouldn't load resources in the benchmark
2 parents 0de7d54 + 1f6ad81 commit f88580e

2 files changed

Lines changed: 37 additions & 30 deletions

File tree

JetStreamDriver.js

Lines changed: 28 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -560,20 +560,35 @@ const BenchmarkState = Object.freeze({
560560

561561

562562
class Scripts {
563-
constructor() {
563+
constructor(preloads) {
564564
this.scripts = [];
565+
566+
let preloadsCode = "";
567+
let resourcesCode = "";
568+
for (let { name, resource, blobURLOrPath } of preloads) {
569+
console.assert(name?.length > 0, "Invalid preload name.");
570+
console.assert(resource?.length > 0, "Invalid preload resource.");
571+
console.assert(blobURLOrPath?.length > 0, "Invalid preload data.");
572+
preloadsCode += `${JSON.stringify(name)}: "${blobURLOrPath}",\n`;
573+
resourcesCode += `${JSON.stringify(resource)}: "${blobURLOrPath}",\n`;
574+
}
565575
// Expose a globalThis.JetStream object to the workload. We use
566576
// a proxy to prevent prototype access and throw on unknown properties.
567577
this.add(`
568578
const throwOnAccess = (name) => new Proxy({}, {
569579
get(target, property, receiver) {
570580
throw new Error(name + "." + property + " is not defined.");
571581
}
572-
});
582+
});
573583
globalThis.JetStream = {
574584
__proto__: throwOnAccess("JetStream"),
575585
preload: {
576586
__proto__: throwOnAccess("JetStream.preload"),
587+
${preloadsCode}
588+
},
589+
resources: {
590+
__proto__: throwOnAccess("JetStream.preload"),
591+
${resourcesCode}
577592
},
578593
};
579594
`);
@@ -631,8 +646,8 @@ class Scripts {
631646
}
632647

633648
class ShellScripts extends Scripts {
634-
constructor() {
635-
super();
649+
constructor(preloads) {
650+
super(preloads);
636651
this.prefetchedResources = Object.create(null);;
637652
}
638653

@@ -698,8 +713,8 @@ class ShellScripts extends Scripts {
698713
}
699714

700715
class BrowserScripts extends Scripts {
701-
constructor() {
702-
super();
716+
constructor(preloads) {
717+
super(preloads);
703718
this.add("window.onerror = top.currentReject;");
704719
}
705720

@@ -738,7 +753,7 @@ class Benchmark {
738753
this.isAsync = !!plan.isAsync;
739754
this.allowUtf16 = !!plan.allowUtf16;
740755
this.scripts = null;
741-
this.preloads = null;
756+
this.preloads = [];
742757
this.shellPrefetchedResources = null;
743758
this.results = [];
744759
this._state = BenchmarkState.READY;
@@ -898,7 +913,7 @@ class Benchmark {
898913
if (this.isDone)
899914
throw new Error(`Cannot run Benchmark ${this.name} twice`);
900915
this._state = BenchmarkState.PREPARE;
901-
const scripts = isInBrowser ? new BrowserScripts() : new ShellScripts();
916+
const scripts = isInBrowser ? new BrowserScripts(this.preloads) : new ShellScripts(this.preloads);
902917

903918
if (!!this.plan.deterministicRandom)
904919
scripts.addDeterministicRandom()
@@ -908,15 +923,6 @@ class Benchmark {
908923
if (this.shellPrefetchedResources) {
909924
scripts.addPrefetchedResources(this.shellPrefetchedResources);
910925
}
911-
if (this.plan.preload) {
912-
let preloadCode = "";
913-
for (let [ variableName, blobURLOrPath ] of this.preloads) {
914-
console.assert(variableName?.length > 0, "Invalid preload name.");
915-
console.assert(blobURLOrPath?.length > 0, "Invalid preload data.");
916-
preloadCode += `JetStream.preload[${JSON.stringify(variableName)}] = "${blobURLOrPath}";\n`;
917-
}
918-
scripts.add(preloadCode);
919-
}
920926

921927
const prerunCode = this.prerunCode;
922928
if (prerunCode)
@@ -1067,12 +1073,11 @@ class Benchmark {
10671073
}));
10681074

10691075
if (this.plan.preload) {
1070-
this.preloads = [];
10711076
for (const [name, resource] of Object.entries(this.plan.preload)) {
10721077
promises.push(this.loadBlob("preload", name, resource).then((blobData) => {
10731078
if (!globalThis.allIsGood)
10741079
return;
1075-
this.preloads.push([ blobData.prop, blobData.blobURL ]);
1080+
this.preloads.push({ name: blobData.prop, resource: blobData.resource, blobURLOrPath: blobData.blobURL });
10761081
this.updateCounter();
10771082
}).catch((error) => {
10781083
// We'll try again later in retryPrefetchResourceForBrowser(). Don't throw an error.
@@ -1099,7 +1104,7 @@ class Benchmark {
10991104
if (type == "preload") {
11001105
if (this.failedPreloads && this.failedPreloads[blobData.prop]) {
11011106
this.failedPreloads[blobData.prop] = false;
1102-
this.preloads.push([ blobData.prop, blobData.blobURL ]);
1107+
this.preloads.push({ name: blobData.prop, resource: blobData.resource, blobURLOrPath: blobData.blobURL });
11031108
counter.failedPreloadResources--;
11041109
}
11051110
}
@@ -1112,7 +1117,7 @@ class Benchmark {
11121117
if (!globalThis.allIsGood)
11131118
return;
11141119
if (blobData.type == "preload")
1115-
this.preloads.push([ blobData.prop, blobData.blobURL ]);
1120+
this.preloads.push({ name: blobData.prop, resource: blobData.resource, blobURLOrPath: blobData.blobURL });
11161121
this.updateCounter();
11171122
});
11181123

@@ -1150,8 +1155,7 @@ class Benchmark {
11501155
console.assert(this.scripts === null, "This initialization should be called only once.");
11511156
this.scripts = this.plan.files.map(file => shellFileLoader.load(file));
11521157

1153-
console.assert(this.preloads === null, "This initialization should be called only once.");
1154-
this.preloads = [];
1158+
console.assert(this.preloads.length === 0, "This initialization should be called only once.");
11551159
this.shellPrefetchedResources = Object.create(null);
11561160
if (!this.plan.preload) {
11571161
return;
@@ -1170,7 +1174,7 @@ class Benchmark {
11701174
this.shellPrefetchedResources[resource] = bytes;
11711175
}
11721176

1173-
this.preloads.push([name, resource]);
1177+
this.preloads.push({ name, resource, blobURLOrPath: resource });
11741178
}
11751179
}
11761180

transformersjs/benchmark.js

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,14 @@ globalThis.URL = URL;
1616

1717
// Polyfill fetch for shell-compatibility and to cache / preload model weights etc.
1818
let preload = { /* Initialized in init() below due to async. */ };
19-
const originalFetch = globalThis.fetch ?? function(url) {
20-
throw new Error("no fetch available");
21-
}
22-
globalThis.fetch = async function(url) {
19+
20+
async function redirectingFetch(url) {
2321
// DEBUG
2422
// console.log('fetch', url);
2523

24+
if (url.startsWith("./"))
25+
url = JetStream.resources[url];
26+
2627
// Redirect some paths to cached/preloaded resources.
2728
if (preload[url]) {
2829
return {
@@ -38,8 +39,7 @@ globalThis.fetch = async function(url) {
3839
};
3940
}
4041

41-
// This should only be called in the browser, where fetch() is available.
42-
return originalFetch(url);
42+
throw new Error(`Unexpected resource requested in benchmark: ${url}`);
4343
};
4444

4545
// JetStream benchmark harness. Reuse for two different Transformers.js tasks.
@@ -66,6 +66,9 @@ class Benchmark {
6666
// DEBUG
6767
// console.log('inputFile', this.inputFile.byteLength, 'bytes');
6868
}
69+
70+
// After we have loaded everything close the door behind us to make sure no other network requests happen.
71+
globalThis.fetch = redirectingFetch;
6972
}
7073

7174
async runIteration() {

0 commit comments

Comments
 (0)