// Load the shared-head file first.
Services.scriptloader.loadSubScript( "chrome://mochitests/content/browser/toolkit/components/ml/tests/browser/shared-head.js", this
);
// This test suite shares some utility functions with translations as they work in a very // similar fashion. Eventually, the plan is to unify these two components.
Services.scriptloader.loadSubScript( "chrome://mochitests/content/browser/toolkit/components/translations/tests/browser/shared-head.js", this
);
return {
remoteClients,
async cleanup() {
await removeMocks();
await waitForCondition(
() => EngineProcess.areAllEnginesTerminated(), "Waiting for all of the engines to be terminated.", 100, 200
);
await SpecialPowers.popPrefEnv();
},
};
}
const modelHubRootUrl = Services.env.get("MOZ_MODELS_HUB"); if (!modelHubRootUrl) { thrownew Error( "MOZ_MODELS_HUB is not set, you need to run with --hooks toolkit/components/ml/tests/tools/hooks_local_hub.py"
);
}
info(`ModelHubRootUrl: ${modelHubRootUrl}`); var browserPrefs = [["browser.ml.modelHubRootUrl", modelHubRootUrl]]; if (prefs) {
browserPrefs = browserPrefs.concat(prefs);
}
function normalizePathForOS(path) { if (Services.appinfo.OS === "WINNT") { // On Windows, replace forward slashes with backslashes return path.replace(/\//g, "\\");
}
// On Unix-like systems, replace backslashes with forward slashes return path.replace(/\\/g, "/");
}
// Stop immediately if this fails. if (!artifactDirectory) {
artifactDirectory = normalizePathForOS(
`${Services.env.get("MOZ_ML_LOCAL_DIR")}`
);
}
if (!artifactDirectory) { thrownew Error(
`The wasm artifact directory is not set. This usually happens when running locally. " + "Please download all the files from taskcluster/kinds/fetch/onnxruntime-web-fetch.yml. " + "Place them in a directory and rerun the test with the environment variable 'MOZ_ML_LOCAL_DIR' " + "set such that all the files are directly inside 'MOZ_ML_LOCAL_DIR'`
);
}
if (!PathUtils.isAbsolute(artifactDirectory)) { thrownew Error( "Please provide an absolute path for 'MOZ_ML_LOCAL_DIR and not a relative path"
);
}
// Stop immediately if this fails. if (!(await pathExists(recordPath))) { thrownew Error(`The wasm file <${recordPath}> does not exist. This usually happens when running locally. " + "Please download all the files from taskcluster/kinds/fetch/onnxruntime-web-fetch.yml. " + "Place them in the directory <${artifactDirectory}> " + "such that <${recordPath}> exists.`);
}
// Lot of unit tests even the one outside our components declare sinon // So we are not making it module level to allow including this file without issue const { sinon } = ChromeUtils.importESModule( "resource://testing-common/Sinon.sys.mjs"
);
return {
remoteClients,
async cleanup() {
await removeMocks();
await waitForCondition(
() => EngineProcess.areAllEnginesTerminated(), "Waiting for all of the engines to be terminated.", 100, 200
);
await SpecialPowers.popPrefEnv(); if (downloadRSAttachmentStub) {
downloadRSAttachmentStub.restore();
}
},
};
}
let metrics = {};
let timeToFirstToken;
let startTime;
let runStartTime;
let runEndTime;
let numGeneratedCharacters = 0;
let numGeneratedTokens = 0;
let numPromptCharacters = 0; if (streamerOptions.skipPrompt && Array.isArray(request?.args)) {
numPromptCharacters += request.args
.flat()
.reduce((sum, item) => sum + (item?.length || 0), 0);
}
let numPromptTokens = 0; const run = async () => {
let isFirstTokenReceived = false;
let result;
let currentTokenLen = 0;
let currentCharLen = 0;
startTime = performance.now();
runStartTime = startTime; const generator = engine.runWithGenerator(request);
// When tracking peak memory we only do this because we're // stressing the system with 500ms callbacks so other netrics are impacted if (trackPeakMemory) {
METRICS = [`${name}-${PEAK_MEMORY_USAGE}`];
} else {
METRICS = [
`${name}-${PIPELINE_READY_LATENCY}`,
`${name}-${INITIALIZATION_LATENCY}`,
`${name}-${MODEL_RUN_LATENCY}`,
`${name}-${TOTAL_MEMORY_USAGE}`,
`${name}-${E2E_RUN_LATENCY}`,
`${name}-${E2E_INIT_LATENCY}`,
`${name}-${FIRST_TOKEN_LATENCY}`,
`${name}-${DECODING_LATENCY}`,
`${name}-${DECODING_CHARACTERS_SPEED}`,
`${name}-${DECODING_TOKEN_SPEED}`,
`${name}-${PROMPT_CHARACTERS_SPEED}`,
`${name}-${PROMPT_TOKEN_SPEED}`,
...(addColdStart
? [
`${name}-${COLD_START_PREFIX}${PIPELINE_READY_LATENCY}`,
`${name}-${COLD_START_PREFIX}${INITIALIZATION_LATENCY}`,
`${name}-${COLD_START_PREFIX}${MODEL_RUN_LATENCY}`,
`${name}-${COLD_START_PREFIX}${TOTAL_MEMORY_USAGE}`,
]
: []),
];
}
const journal = {}; for (let metric of METRICS) {
journal[metric] = [];
}
const pipelineOptions = new PipelineOptions(options); var tracker;
let nIterations = addColdStart ? iterations + 1 : iterations; for (let i = 0; i < nIterations; i++) { if (trackPeakMemory) {
tracker = new PeakMemoryTracker(peakMemoryInterval);
tracker.start();
} const shouldAddColdStart = addColdStart && i === 0;
let metrics = await runInference({
pipelineOptions,
request,
isFirstRun: shouldAddColdStart,
browserPrefs,
}); if (trackPeakMemory) {
journal[`${name}-${PEAK_MEMORY_USAGE}`].push(tracker.stop());
} else { for (let [metricName, metricVal] of Object.entries(metrics)) { if (!Number.isFinite(metricVal) || metricVal < 0) {
metricVal = 0;
} // Add the metric if it wasn't there if (journal[`${name}-${metricName}`] === undefined) {
journal[`${name}-${metricName}`] = [];
}
journal[`${name}-${metricName}`].push(metricVal);
}
}
} Assert.ok(true);
reportMetrics(journal);
}
/** *Assertswhethertwofloatarraysareequalwithinepsilontolerance. * *@param{number[]|ArrayBufferLike}a *@param{number[]|ArrayBufferLike}b *@param{string}message *@param{number}[epsilon]
*/ function assertFloatArraysMatch(a, b, message, epsilon) { const raise = () => { // When logging errors, spread into a new array so that the logging is nice for // ArrayBufferLike values. This makes it easy to see how arrays differ
console.log("a:", [...a]);
console.log("b:", [...b]); thrownew Error(message);
}; if (a.length !== b.length) {
raise();
} for (let i = 0; i < a.length; i++) { if (!isEqualWithTolerance(a[i], b[i], epsilon)) {
raise();
}
}
ok(true, message);
}
function readRequestBody(request) { // Read the POST body as UTF-8 text const stream = request.bodyInputStream; const available = stream.available(); return NetUtil.readInputStreamToString(stream, available, {
charset: "UTF-8",
});
}
function startMockOpenAI({
echo = "This gets echoed.",
onRequest = null,
} = {}) { const server = new HttpServer();
server.registerPathHandler("/v1/chat/completions", (request, response) => {
info("[openai] GET /v1/chat/completions");
// Call the onRequest callback if provided to allow test inspection if (onRequest) {
onRequest(request);
}
// Signal the turn ends with tool calls
sendSSE({
id: "chatcmpl-mock-tools-stream-3",
object: "chat.completion.chunk",
created: Math.floor(Date.now() / 1000),
model: "qwen3:0.6b",
choices: [{ index: 0, delta: {}, finish_reason: "tool_calls" }],
});
endSSE(); return;
}
if (wantsStream && askedForTools && hasToolResult) { // Second turn (after tool result): stream normal assistant text
info("[openai] Streaming tool call, with results");
/** *Checksthataprocessexists. * *@param{string}remoteType
*/
async function checkForRemoteType(remoteType) {
let procinfo3 = await ChromeUtils.requestProcInfo(); for (const child of procinfo3.children) { if (child.type === remoteType) { returntrue;
}
} returnfalse;
}
Messung V0.5 in Prozent
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.11Bemerkung:
(vorverarbeitet am 2026-09-28)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.