feat(laboratory): publish M48S load envelope
This commit is contained in:
@@ -2,6 +2,7 @@ import type { LaboratoryFetch } from "./advancedResults";
|
||||
|
||||
const RESULT_ID = /^m48s-fixed-class-detector-lab-[a-f0-9]{64}$/;
|
||||
const FRAME_ID = /^[0-9]{6}$/;
|
||||
const SHA256 = /^[a-f0-9]{64}$/;
|
||||
const MODES = ["source", "yolox", "dfine", "rf-detr"] as const;
|
||||
const DETECTOR_MODES = ["yolox", "dfine", "rf-detr"] as const;
|
||||
const RESULT_STATUSES = [
|
||||
@@ -105,6 +106,48 @@ export interface M48SRuntimeHardeningComparison {
|
||||
};
|
||||
}
|
||||
|
||||
export interface M48SLoadEnvelopeScenario {
|
||||
id: "production-10fps" | "reserve-12fps" | "limit-15fps";
|
||||
loadPurpose: "production-rate" | "reserve-gate" | "limit-discovery";
|
||||
requestedSourceRateHz: number;
|
||||
sourceFramesAdmitted: number;
|
||||
deliveredWorldStates: number;
|
||||
supersededFrames: number;
|
||||
deliveryRatio: number;
|
||||
effectiveWorldStateFps: number;
|
||||
worldStateCompletionAgeP95Ms: number;
|
||||
worldStateCompletionAgeP99Ms: number;
|
||||
worldStateCompletionAgeMaximumMs: number;
|
||||
decodeP95Ms: number;
|
||||
decodeMaximumMs: number;
|
||||
detectorP95Ms: number;
|
||||
detectorMaximumMs: number;
|
||||
gpuUtilizationMeanPercent: number;
|
||||
gpuUtilizationMaximumPercent: number;
|
||||
gpuMemoryMaximumMib: number;
|
||||
processPeakRssMib: number;
|
||||
queueHighWatermarks: Readonly<Record<"detector" | "geometry" | "temporal" | "rolling" | "threat", number>>;
|
||||
queueCapacity: number;
|
||||
additionalInferencePasses: number;
|
||||
integrityGatePassed: boolean;
|
||||
operatingTargetGatePassed: boolean;
|
||||
thresholds: {
|
||||
minimumDeliveryRatio: number;
|
||||
minimumEffectiveWorldStateFps: number;
|
||||
maximumWorldStateCompletionP95Ms: number;
|
||||
};
|
||||
}
|
||||
|
||||
export interface M48SLoadEnvelopeComparison {
|
||||
productionRateRepeatabilityPassed: false;
|
||||
reserve12FpsPassed: true;
|
||||
limit15FpsPassed: true;
|
||||
loadEnvelopeAccepted: false;
|
||||
computeCapacityAtLeastFps: 15;
|
||||
bottleneckInterpretation: "rare-source-decode-or-scheduling-tail-not-steady-gpu-saturation";
|
||||
scenarios: readonly M48SLoadEnvelopeScenario[];
|
||||
}
|
||||
|
||||
export interface M48SFixedClassDetectorResult {
|
||||
resultId: string;
|
||||
createdAtUtc: string;
|
||||
@@ -144,6 +187,7 @@ export interface M48SFixedClassDetectorResult {
|
||||
};
|
||||
integratedWorldState: M48SIntegratedWorldState | null;
|
||||
runtimeHardening: M48SRuntimeHardeningComparison | null;
|
||||
loadEnvelope: M48SLoadEnvelopeComparison | null;
|
||||
};
|
||||
decision: {
|
||||
selectedCandidate: "rf-detr";
|
||||
@@ -151,6 +195,11 @@ export interface M48SFixedClassDetectorResult {
|
||||
integratedWorldStateGateEvaluated: boolean;
|
||||
integratedWorldStateGatePassed: boolean;
|
||||
detectorReplacementAuthorized: false;
|
||||
loadEnvelopeEvaluated: boolean;
|
||||
productionRateRepeatabilityPassed: boolean;
|
||||
reserve12FpsPassed: boolean;
|
||||
limit15FpsPassed: boolean;
|
||||
loadEnvelopeAccepted: boolean;
|
||||
productionAccepted: false;
|
||||
};
|
||||
limitations: readonly string[];
|
||||
@@ -457,6 +506,96 @@ function runtimeHardeningComparisonValue(value: unknown): M48SRuntimeHardeningCo
|
||||
};
|
||||
}
|
||||
|
||||
function loadEnvelopeComparisonValue(value: unknown): M48SLoadEnvelopeComparison {
|
||||
const comparison = objectValue(value, "M4.8S.metrics.load_envelope");
|
||||
exact(
|
||||
comparison.schema_version,
|
||||
"missioncore.m48s-load-envelope-comparison/v1",
|
||||
"M4.8S.metrics.load_envelope.schema_version",
|
||||
);
|
||||
exact(comparison.production_rate_repeatability_passed, false, "M4.8S.load_envelope.production_rate_repeatability_passed");
|
||||
exact(comparison.reserve_12_fps_passed, true, "M4.8S.load_envelope.reserve_12_fps_passed");
|
||||
exact(comparison.limit_15_fps_passed, true, "M4.8S.load_envelope.limit_15_fps_passed");
|
||||
exact(comparison.load_envelope_accepted, false, "M4.8S.load_envelope.load_envelope_accepted");
|
||||
exact(comparison.compute_capacity_at_least_fps, 15, "M4.8S.load_envelope.compute_capacity_at_least_fps");
|
||||
exact(
|
||||
comparison.bottleneck_interpretation,
|
||||
"rare-source-decode-or-scheduling-tail-not-steady-gpu-saturation",
|
||||
"M4.8S.load_envelope.bottleneck_interpretation",
|
||||
);
|
||||
const ids = ["production-10fps", "reserve-12fps", "limit-15fps"] as const;
|
||||
const purposes = ["production-rate", "reserve-gate", "limit-discovery"] as const;
|
||||
const targetGates = [false, true, true] as const;
|
||||
const scenarios = arrayValue(comparison.scenarios, "M4.8S.load_envelope.scenarios").map((value, index) => {
|
||||
const label = `M4.8S.load_envelope.scenarios[${index}]`;
|
||||
const scenario = objectValue(value, label);
|
||||
const id = ids[index];
|
||||
const purpose = purposes[index];
|
||||
if (id === undefined || purpose === undefined) {
|
||||
throw new M48SFixedClassDetectorContractError("M4.8S.load_envelope.scenarios: лишний сценарий.");
|
||||
}
|
||||
exact(scenario.id, id, `${label}.id`);
|
||||
exact(scenario.load_purpose, purpose, `${label}.load_purpose`);
|
||||
exact(scenario.integrity_gate_passed, true, `${label}.integrity_gate_passed`);
|
||||
exact(scenario.operating_target_gate_passed, targetGates[index], `${label}.operating_target_gate_passed`);
|
||||
exact(scenario.additional_inference_passes, 0, `${label}.additional_inference_passes`);
|
||||
const queues = integerRecordValue(scenario.queue_high_watermarks, `${label}.queue_high_watermarks`);
|
||||
for (const key of ["detector", "geometry", "temporal", "rolling", "threat"] as const) {
|
||||
if (!(key in queues)) {
|
||||
throw new M48SFixedClassDetectorContractError(`${label}.queue_high_watermarks.${key}: отсутствует.`);
|
||||
}
|
||||
}
|
||||
const thresholds = objectValue(scenario.thresholds, `${label}.thresholds`);
|
||||
const frameEvidenceSha256 = textValue(scenario.frame_evidence_sha256, `${label}.frame_evidence_sha256`);
|
||||
if (!SHA256.test(frameEvidenceSha256)) {
|
||||
throw new M48SFixedClassDetectorContractError(`${label}.frame_evidence_sha256: нарушен SHA-256.`);
|
||||
}
|
||||
return {
|
||||
id,
|
||||
loadPurpose: purpose,
|
||||
requestedSourceRateHz: numberValue(scenario.requested_source_rate_hz, `${label}.requested_source_rate_hz`),
|
||||
sourceFramesAdmitted: integerValue(scenario.source_frames_admitted, `${label}.source_frames_admitted`),
|
||||
deliveredWorldStates: integerValue(scenario.delivered_world_states, `${label}.delivered_world_states`),
|
||||
supersededFrames: integerValue(scenario.superseded_frames, `${label}.superseded_frames`),
|
||||
deliveryRatio: numberValue(scenario.delivery_ratio, `${label}.delivery_ratio`),
|
||||
effectiveWorldStateFps: numberValue(scenario.effective_world_state_fps, `${label}.effective_world_state_fps`),
|
||||
worldStateCompletionAgeP95Ms: numberValue(scenario.world_state_completion_age_p95_ms, `${label}.world_state_completion_age_p95_ms`),
|
||||
worldStateCompletionAgeP99Ms: numberValue(scenario.world_state_completion_age_p99_ms, `${label}.world_state_completion_age_p99_ms`),
|
||||
worldStateCompletionAgeMaximumMs: numberValue(scenario.world_state_completion_age_maximum_ms, `${label}.world_state_completion_age_maximum_ms`),
|
||||
decodeP95Ms: numberValue(scenario.decode_p95_ms, `${label}.decode_p95_ms`),
|
||||
decodeMaximumMs: numberValue(scenario.decode_maximum_ms, `${label}.decode_maximum_ms`),
|
||||
detectorP95Ms: numberValue(scenario.detector_p95_ms, `${label}.detector_p95_ms`),
|
||||
detectorMaximumMs: numberValue(scenario.detector_maximum_ms, `${label}.detector_maximum_ms`),
|
||||
gpuUtilizationMeanPercent: numberValue(scenario.gpu_utilization_mean_percent, `${label}.gpu_utilization_mean_percent`),
|
||||
gpuUtilizationMaximumPercent: numberValue(scenario.gpu_utilization_maximum_percent, `${label}.gpu_utilization_maximum_percent`),
|
||||
gpuMemoryMaximumMib: numberValue(scenario.gpu_memory_maximum_mib, `${label}.gpu_memory_maximum_mib`),
|
||||
processPeakRssMib: numberValue(scenario.process_peak_rss_mib, `${label}.process_peak_rss_mib`),
|
||||
queueHighWatermarks: queues as M48SLoadEnvelopeScenario["queueHighWatermarks"],
|
||||
queueCapacity: integerValue(scenario.queue_capacity, `${label}.queue_capacity`),
|
||||
additionalInferencePasses: 0,
|
||||
integrityGatePassed: true,
|
||||
operatingTargetGatePassed: targetGates[index],
|
||||
thresholds: {
|
||||
minimumDeliveryRatio: numberValue(thresholds.minimum_delivery_ratio, `${label}.thresholds.minimum_delivery_ratio`),
|
||||
minimumEffectiveWorldStateFps: numberValue(thresholds.minimum_effective_world_state_fps, `${label}.thresholds.minimum_effective_world_state_fps`),
|
||||
maximumWorldStateCompletionP95Ms: numberValue(thresholds.maximum_world_state_completion_p95_ms, `${label}.thresholds.maximum_world_state_completion_p95_ms`),
|
||||
},
|
||||
};
|
||||
});
|
||||
if (scenarios.length !== ids.length) {
|
||||
throw new M48SFixedClassDetectorContractError("M4.8S.load_envelope.scenarios: неполный набор.");
|
||||
}
|
||||
return {
|
||||
productionRateRepeatabilityPassed: false,
|
||||
reserve12FpsPassed: true,
|
||||
limit15FpsPassed: true,
|
||||
loadEnvelopeAccepted: false,
|
||||
computeCapacityAtLeastFps: 15,
|
||||
bottleneckInterpretation: "rare-source-decode-or-scheduling-tail-not-steady-gpu-saturation",
|
||||
scenarios,
|
||||
};
|
||||
}
|
||||
|
||||
function parseResult(value: unknown, resultId: string): M48SFixedClassDetectorResult {
|
||||
const payload = objectValue(value, "M4.8S");
|
||||
exact(
|
||||
@@ -475,6 +614,9 @@ function parseResult(value: unknown, resultId: string): M48SFixedClassDetectorRe
|
||||
const metrics = objectValue(payload.metrics, "M4.8S.metrics");
|
||||
const load = objectValue(metrics.detector_load, "M4.8S.metrics.detector_load");
|
||||
const decision = objectValue(payload.decision, "M4.8S.decision");
|
||||
const loadEnvelope = metrics.load_envelope === undefined
|
||||
? null
|
||||
: loadEnvelopeComparisonValue(metrics.load_envelope);
|
||||
const cameraRaster = arrayValue(source.camera_raster, "M4.8S.source.camera_raster");
|
||||
if (cameraRaster.length !== 2) {
|
||||
throw new M48SFixedClassDetectorContractError("M4.8S.source.camera_raster: нарушен размер.");
|
||||
@@ -503,6 +645,13 @@ function parseResult(value: unknown, resultId: string): M48SFixedClassDetectorRe
|
||||
exact(decision.detector_replacement_authorized, false, "M4.8S.decision.detector_replacement_authorized");
|
||||
}
|
||||
exact(decision.production_accepted, false, "M4.8S.decision.production_accepted");
|
||||
if (loadEnvelope !== null) {
|
||||
exact(decision.load_envelope_evaluated, true, "M4.8S.decision.load_envelope_evaluated");
|
||||
exact(decision.production_rate_repeatability_passed, false, "M4.8S.decision.production_rate_repeatability_passed");
|
||||
exact(decision.reserve_12_fps_passed, true, "M4.8S.decision.reserve_12_fps_passed");
|
||||
exact(decision.limit_15_fps_passed, true, "M4.8S.decision.limit_15_fps_passed");
|
||||
exact(decision.load_envelope_accepted, false, "M4.8S.decision.load_envelope_accepted");
|
||||
}
|
||||
const frames = arrayValue(payload.frames, "M4.8S.frames").map(descriptorValue);
|
||||
const evidenceFrameCount = integerValue(source.evidence_frame_count, "M4.8S.source.evidence_frame_count");
|
||||
if (frames.length !== evidenceFrameCount || new Set(frames.map((frame) => frame.frameId)).size !== frames.length) {
|
||||
@@ -551,6 +700,7 @@ function parseResult(value: unknown, resultId: string): M48SFixedClassDetectorRe
|
||||
runtimeHardening: metrics.runtime_hardening === undefined
|
||||
? null
|
||||
: runtimeHardeningComparisonValue(metrics.runtime_hardening),
|
||||
loadEnvelope,
|
||||
},
|
||||
decision: {
|
||||
selectedCandidate: "rf-detr",
|
||||
@@ -558,6 +708,11 @@ function parseResult(value: unknown, resultId: string): M48SFixedClassDetectorRe
|
||||
integratedWorldStateGateEvaluated: integratedGate,
|
||||
integratedWorldStateGatePassed: integratedGate,
|
||||
detectorReplacementAuthorized: false,
|
||||
loadEnvelopeEvaluated: loadEnvelope !== null,
|
||||
productionRateRepeatabilityPassed: false,
|
||||
reserve12FpsPassed: loadEnvelope?.reserve12FpsPassed ?? false,
|
||||
limit15FpsPassed: loadEnvelope?.limit15FpsPassed ?? false,
|
||||
loadEnvelopeAccepted: false,
|
||||
productionAccepted: false,
|
||||
},
|
||||
limitations: arrayValue(payload.limitations, "M4.8S.limitations").map((item, index) => textValue(item, `M4.8S.limitations[${index}]`)),
|
||||
|
||||
@@ -19,10 +19,19 @@ export function M48SFixedClassDetectorResultView({
|
||||
result: M48SFixedClassDetectorResult;
|
||||
}) {
|
||||
const selected = result.metrics.candidates.find((candidate) => candidate.selected);
|
||||
const load = result.metrics.detectorLoad;
|
||||
const detectorLoad = result.metrics.detectorLoad;
|
||||
const integrated = result.metrics.integratedWorldState;
|
||||
const hardening = result.metrics.runtimeHardening;
|
||||
const status = hardening
|
||||
const loadEnvelope = result.metrics.loadEnvelope;
|
||||
const production = loadEnvelope?.scenarios.find((scenario) => scenario.id === "production-10fps");
|
||||
const reserve = loadEnvelope?.scenarios.find((scenario) => scenario.id === "reserve-12fps");
|
||||
const limit = loadEnvelope?.scenarios.find((scenario) => scenario.id === "limit-15fps");
|
||||
const load = loadEnvelope && production && reserve && limit
|
||||
? { comparison: loadEnvelope, production, reserve, limit }
|
||||
: null;
|
||||
const status = load
|
||||
? "Capacity ≥ 15 FPS подтверждён; repeatability 10 FPS требует закрытия"
|
||||
: hardening
|
||||
? `После hardening: ${hardening.hardened.deliveredWorldStates.toLocaleString("ru-RU")} из ${hardening.hardened.sourceFramesAdmitted.toLocaleString("ru-RU")} world states доставлены`
|
||||
: integrated
|
||||
? "Полный RF-DETR reference graph выдержал realtime shadow"
|
||||
@@ -32,9 +41,9 @@ export function M48SFixedClassDetectorResultView({
|
||||
summary={(
|
||||
<LaboratorySummary
|
||||
title="M4.8S · fixed-class semantics риск-объектов"
|
||||
description="Сравнение трёх готовых COCO-детекторов на точных кадрах RAVNOVES00, 30-минутная квалификация RF-DETR-L и полный source-paced прогон RF-DETR → geometry → temporal → motion → rolling map → threat на Worker 006. Ниже отдельно показано, что именно изменилось после разгрузки realtime-контура и prewarm первого кадра."
|
||||
description="RF-DETR-L встроен в полный source-paced граф RF-DETR → geometry → temporal → motion → rolling map → threat. После hardening один и тот же immutable проход отдельно измерен на 10, 12 и 15 FPS: показаны не только средние значения, но delivery, хвосты задержки, GPU/VRAM/RAM и честный незакрытый gate."
|
||||
status={status}
|
||||
statusTone="success"
|
||||
statusTone={load ? "warning" : "success"}
|
||||
facts={[
|
||||
{ label: "Источник", value: `${rigLabel} RIGHT · raw KB4 · ${result.source.evidenceFrameCount} diagnostic frames` },
|
||||
{ label: "Сравнение", value: "YOLOX-S · D-FINE-S · RF-DETR-L · единый threshold 0.50" },
|
||||
@@ -42,14 +51,22 @@ export function M48SFixedClassDetectorResultView({
|
||||
{ label: "Authority", value: "SHADOW ONLY · commands OFF · actuation OFF · production NO" },
|
||||
]}
|
||||
brief={{
|
||||
question: "Можно ли заменить слабую class-семантику YOLOX готовой моделью, не потеряв realtime на предельном Worker с RTX 4090?",
|
||||
approach: `YOLOX-S, D-FINE-S и RF-DETR-L сравнили на одинаковых ${result.source.evidenceFrameCount} raw-KB4 кадрах с порогом 0.50. RF-DETR-L отдельно квалифицировали ${decimal(load.durationSeconds / 60, 0)} минут, затем встроили в полный reference graph без дополнительного inference-прохода.`,
|
||||
principalResult: hardening
|
||||
question: load
|
||||
? "Какой realtime-запас имеет неизменный single-pass RF-DETR graph на Worker 006 и где начинается его вычислительный предел?"
|
||||
: "Можно ли заменить слабую class-семантику YOLOX готовой моделью, не потеряв realtime на предельном Worker с RTX 4090?",
|
||||
approach: load
|
||||
? "Один и тот же проход из 4489 кадров прогнали последовательно на 10, 12 и 15 FPS. Sensor timestamps, модель, graph providers, очереди, prewarm и single inference не менялись; менялся только wall-clock pacing. Пороги delivery/FPS/p95 были записаны до запусков."
|
||||
: `YOLOX-S, D-FINE-S и RF-DETR-L сравнили на одинаковых ${result.source.evidenceFrameCount} raw-KB4 кадрах с порогом 0.50. RF-DETR-L отдельно квалифицировали ${decimal(result.metrics.detectorLoad.durationSeconds / 60, 0)} минут, затем встроили в полный reference graph без дополнительного inference-прохода.`,
|
||||
principalResult: load
|
||||
? `12 FPS прошли reserve-gate: ${load.reserve.deliveredWorldStates.toLocaleString("ru-RU")}/${load.reserve.sourceFramesAdmitted.toLocaleString("ru-RU")} доставлено. 15 FPS также прошли: ${load.limit.deliveredWorldStates.toLocaleString("ru-RU")}/${load.limit.sourceFramesAdmitted.toLocaleString("ru-RU")}. Но 10 FPS не добрали заранее заданный delivery ratio: ${load.production.deliveredWorldStates.toLocaleString("ru-RU")}/${load.production.sourceFramesAdmitted.toLocaleString("ru-RU")}, на два кадра ниже порога.`
|
||||
: hardening
|
||||
? `На одинаковых ${hardening.baseline.sourceFramesAdmitted.toLocaleString("ru-RU")} входных кадрах полный граф увеличил доставку с ${hardening.baseline.deliveredWorldStates.toLocaleString("ru-RU")} до ${hardening.hardened.deliveredWorldStates.toLocaleString("ru-RU")} world states, а число вытесненных кадров снизил с ${hardening.baseline.supersededFrames} до ${hardening.hardened.supersededFrames}. Отдельный ${hardening.startup.validationFrames.toLocaleString("ru-RU")}-кадровый прогон подтвердил prewarm до допуска источника.`
|
||||
: integrated
|
||||
? `Полный граф доставил ${integrated.deliveredWorldStates.toLocaleString("ru-RU")} world states при ${decimal(integrated.effectiveWorldStateFps, 3)} FPS и p95 ${decimal(integrated.worldStateCompletionAgeP95Ms, 3)} ms; ${integrated.supersededFrames} входных кадров штатно вытеснены latest-wins очередью.`
|
||||
: `RF-DETR-L выбран из трёх кандидатов и обработал ${load.sourceFramesConsumed.toLocaleString("ru-RU")} кадров detector-only без замен и ошибок.`,
|
||||
limitation: "Прогон доказывает runtime envelope, а не истинность классов, качество track identity, корректность risk policy или безопасность движения. Production authority и команды отключены.",
|
||||
: `RF-DETR-L выбран из трёх кандидатов и обработал ${detectorLoad.sourceFramesConsumed.toLocaleString("ru-RU")} кадров detector-only без замен и ошибок.`,
|
||||
limitation: load
|
||||
? "Capacity полного графа доказан как минимум до 15 FPS, но production repeatability не принята: delivery на 10 FPS немонотонно хуже 12/15 из-за редкого decode/scheduling tail. Истинность классов, collision safety и physical-live не проверялись; команды отключены."
|
||||
: "Прогон доказывает runtime envelope, а не истинность классов, качество track identity, корректность risk policy или безопасность движения. Production authority и команды отключены.",
|
||||
}}
|
||||
method={{
|
||||
completeness: result.method.completeness,
|
||||
@@ -79,13 +96,24 @@ export function M48SFixedClassDetectorResultView({
|
||||
result={(
|
||||
<LaboratoryResultSummary
|
||||
title={hardening
|
||||
? "Что сравнивать: один и тот же полный прогон до и после hardening"
|
||||
? load
|
||||
? "Что сравнивать: один graph на 10 / 12 / 15 FPS"
|
||||
: "Что сравнивать: один и тот же полный прогон до и после hardening"
|
||||
: integrated
|
||||
? "Что дал прогон: полный world-state graph проходит realtime envelope"
|
||||
: "Что дал прогон: RF-DETR-L проходит detector-only realtime envelope"}
|
||||
status={status}
|
||||
statusTone="success"
|
||||
metrics={hardening ? [
|
||||
statusTone={load ? "warning" : "success"}
|
||||
metrics={load ? [
|
||||
{ label: "Effective world-state FPS", value: `${decimal(load.production.effectiveWorldStateFps, 3)} / ${decimal(load.reserve.effectiveWorldStateFps, 3)} / ${decimal(load.limit.effectiveWorldStateFps, 3)}`, hint: "вход 10 / 12 / 15 FPS" },
|
||||
{ label: "Delivered / superseded", value: `${load.production.deliveredWorldStates.toLocaleString("ru-RU")}/${load.production.supersededFrames} · ${load.reserve.deliveredWorldStates.toLocaleString("ru-RU")}/${load.reserve.supersededFrames} · ${load.limit.deliveredWorldStates.toLocaleString("ru-RU")}/${load.limit.supersededFrames}`, hint: "10 FPS gate не прошёл · 12 и 15 прошли" },
|
||||
{ label: "World-state p95", value: `${decimal(load.production.worldStateCompletionAgeP95Ms, 3)} / ${decimal(load.reserve.worldStateCompletionAgeP95Ms, 3)} / ${decimal(load.limit.worldStateCompletionAgeP95Ms, 3)} ms`, hint: "10 / 12 / 15 FPS" },
|
||||
{ label: "World-state p99", value: `${decimal(load.production.worldStateCompletionAgeP99Ms, 3)} / ${decimal(load.reserve.worldStateCompletionAgeP99Ms, 3)} / ${decimal(load.limit.worldStateCompletionAgeP99Ms, 3)} ms`, hint: "хвост не растёт вместе с rate" },
|
||||
{ label: "Decode maximum", value: `${decimal(load.production.decodeMaximumMs, 0)} / ${decimal(load.reserve.decodeMaximumMs, 0)} / ${decimal(load.limit.decodeMaximumMs, 0)} ms`, hint: "редкий source/decode tail · не steady compute" },
|
||||
{ label: "Detector p95", value: `${decimal(load.production.detectorP95Ms, 3)} / ${decimal(load.reserve.detectorP95Ms, 3)} / ${decimal(load.limit.detectorP95Ms, 3)} ms`, hint: "тот же RF-DETR · один inference" },
|
||||
{ label: "GPU mean", value: `${decimal(load.production.gpuUtilizationMeanPercent)}% / ${decimal(load.reserve.gpuUtilizationMeanPercent)}% / ${decimal(load.limit.gpuUtilizationMeanPercent)}%`, hint: "10 / 12 / 15 FPS · насыщения нет" },
|
||||
{ label: "VRAM / process RAM peak", value: `${decimal(Math.max(...load.comparison.scenarios.map((scenario) => scenario.gpuMemoryMaximumMib)) / 1024, 2)} / ${decimal(Math.max(...load.comparison.scenarios.map((scenario) => scenario.processPeakRssMib)) / 1024, 2)} GiB`, hint: "общий GPU counter / graph process RSS" },
|
||||
] : hardening ? [
|
||||
{ label: "World-state FPS", value: `${decimal(hardening.baseline.effectiveWorldStateFps, 3)} → ${decimal(hardening.hardened.effectiveWorldStateFps, 3)}`, hint: "до → после · target ≥ 9.5 FPS" },
|
||||
{ label: "Задержка p95", value: `${decimal(hardening.baseline.worldStateCompletionAgeP95Ms, 3)} → ${decimal(hardening.hardened.worldStateCompletionAgeP95Ms, 3)} ms`, hint: `p99 ${decimal(hardening.baseline.worldStateCompletionAgeP99Ms, 3)} → ${decimal(hardening.hardened.worldStateCompletionAgeP99Ms, 3)} ms` },
|
||||
{ label: "Максимальная задержка", value: `${decimal(hardening.baseline.worldStateCompletionAgeMaximumMs, 3)} → ${decimal(hardening.hardened.worldStateCompletionAgeMaximumMs, 3)} ms`, hint: "полный прогон без prewarm" },
|
||||
@@ -101,18 +129,24 @@ export function M48SFixedClassDetectorResultView({
|
||||
{ label: "GPU / VRAM peak", value: `${decimal(integrated.gpuUtilizationMaximumPercent, 0)}% / ${decimal(integrated.gpuMemoryMaximumMib / 1024)} GiB`, hint: `GPU mean ${decimal(integrated.gpuUtilizationMeanPercent)}% · ${decimal(integrated.gpuPowerMaximumW)} W` },
|
||||
] : [
|
||||
{ label: "Detector capacity", value: `${decimal(selected?.capacityFps ?? 0)} FPS`, hint: "RF-DETR-L TensorRT/Triton" },
|
||||
{ label: "Completion age p95", value: `${decimal(load.completionAgeP95Ms)} ms`, hint: "detector-only · target ≤ 175 ms" },
|
||||
{ label: "Consumed / replaced", value: `${load.sourceFramesConsumed.toLocaleString("ru-RU")} / ${load.sourceFrameReplacements}`, hint: `${decimal(load.effectiveConsumedFps, 3)} source FPS · ${load.failures} failures` },
|
||||
{ label: "GPU / VRAM peak", value: `${decimal(load.gpuUtilizationMaximumPercent, 0)}% / ${decimal(load.gpuMemoryMaximumMib / 1024)} GiB`, hint: `GPU mean ${decimal(load.gpuUtilizationMeanPercent)}% · queue ${load.queueMaximumDepth}/${load.queueCapacity}` },
|
||||
{ label: "Completion age p95", value: `${decimal(detectorLoad.completionAgeP95Ms)} ms`, hint: "detector-only · target ≤ 175 ms" },
|
||||
{ label: "Consumed / replaced", value: `${detectorLoad.sourceFramesConsumed.toLocaleString("ru-RU")} / ${detectorLoad.sourceFrameReplacements}`, hint: `${decimal(detectorLoad.effectiveConsumedFps, 3)} source FPS · ${detectorLoad.failures} failures` },
|
||||
{ label: "GPU / VRAM peak", value: `${decimal(detectorLoad.gpuUtilizationMaximumPercent, 0)}% / ${decimal(detectorLoad.gpuMemoryMaximumMib / 1024)} GiB`, hint: `GPU mean ${decimal(detectorLoad.gpuUtilizationMeanPercent)}% · queue ${detectorLoad.queueMaximumDepth}/${detectorLoad.queueCapacity}` },
|
||||
]}
|
||||
conclusion={{
|
||||
proved: hardening
|
||||
proved: load
|
||||
? `Полный single-pass graph сохранил bounded queues 2/2, нулевые failed/stale/rejected/unavailable и нулевые дополнительные inference-проходы во всех трёх режимах. Reserve 12 FPS прошёл с delivery ${(load.reserve.deliveryRatio * 100).toLocaleString("ru-RU", { maximumFractionDigits: 3 })}% и p95 ${decimal(load.reserve.worldStateCompletionAgeP95Ms, 3)} ms; 15 FPS также прошли с delivery ${(load.limit.deliveryRatio * 100).toLocaleString("ru-RU", { maximumFractionDigits: 3 })}%. Вычислительная capacity доказана как минимум до 15 FPS без более мощного Worker.`
|
||||
: hardening
|
||||
? `На полном сравнительном прогоне с ${hardening.hardened.sourceFramesAdmitted.toLocaleString("ru-RU")} одинаковыми входными кадрами hardening сохранил realtime FPS, доставил на ${(hardening.hardened.deliveredWorldStates - hardening.baseline.deliveredWorldStates).toLocaleString("ru-RU")} world states больше и сократил вытеснения ${hardening.baseline.supersededFrames} → ${hardening.hardened.supersededFrames}. Максимальный стоп rolling stage уменьшился ${decimal(hardening.baseline.rollingMaximumMs, 3)} → ${decimal(hardening.hardened.rollingMaximumMs, 3)} ms. Отдельный prewarm-прогон снизил первый detector frame ${decimal(hardening.startup.baseline.detectorMs, 3)} → ${decimal(hardening.startup.prewarmed.detectorMs, 3)} ms и первый world state ${decimal(hardening.startup.baseline.worldStateMs, 3)} → ${decimal(hardening.startup.prewarmed.worldStateMs, 3)} ms без дополнительного inference на кадрах.`
|
||||
: integrated
|
||||
? `На Worker 006 полный граф обработал ${integrated.sourceFramesAdmitted.toLocaleString("ru-RU")} входных кадров, доставил ${integrated.deliveredWorldStates.toLocaleString("ru-RU")} состояний без ошибок, удержал все очереди в пределах ${integrated.queueCapacity} и p95 ${decimal(integrated.worldStateCompletionAgeP95Ms, 3)} ms. Advisory сформировал публикации по семействам: geometry-only (${integrated.advisoryFamilyCounts["generic-obstacle"].toLocaleString("ru-RU")}), люди (${integrated.advisoryFamilyCounts.person.toLocaleString("ru-RU")}), животные (${integrated.advisoryFamilyCounts.animal.toLocaleString("ru-RU")}) и транспорт (${integrated.advisoryFamilyCounts.vehicle.toLocaleString("ru-RU")}); это не количество уникальных физических объектов и не потребовало второго inference.`
|
||||
: `RF-DETR-L ${decimal(load.durationSeconds / 60, 0)} минут устойчиво потреблял source-paced поток около 10 FPS: ${load.sourceFramesConsumed.toLocaleString("ru-RU")} кадров, 0 замен, 0 ошибок, completion-age p95 ${decimal(load.completionAgeP95Ms, 3)} ms.`,
|
||||
notProved: "Не доказаны unbiased precision/recall классов, независимое качество track identity и risk policy, поведение planner или collision safety. Кадровые рамки не заменяют геометрическую occupancy-карту.",
|
||||
decision: hardening
|
||||
: `RF-DETR-L ${decimal(detectorLoad.durationSeconds / 60, 0)} минут устойчиво потреблял source-paced поток около 10 FPS: ${detectorLoad.sourceFramesConsumed.toLocaleString("ru-RU")} кадров, 0 замен, 0 ошибок, completion-age p95 ${decimal(detectorLoad.completionAgeP95Ms, 3)} ms.`,
|
||||
notProved: load
|
||||
? `Не закрыта repeatability delivery на production-rate: 10 FPS дали ${(load.production.deliveryRatio * 100).toLocaleString("ru-RU", { maximumFractionDigits: 3 })}% при gate ${(load.production.thresholds.minimumDeliveryRatio * 100).toLocaleString("ru-RU", { maximumFractionDigits: 1 })}%. Немонотонность 10 → 12 → 15 и decode maxima 3,2–3,6 s не позволяют объявить production envelope принятым.`
|
||||
: "Не доказаны unbiased precision/recall классов, независимое качество track identity и risk policy, поведение planner или collision safety. Кадровые рамки не заменяют геометрическую occupancy-карту.",
|
||||
decision: load
|
||||
? "Не усиливать GPU и не добавлять второй детектор. Сначала изолировать/предзагружать video decode и измерить scheduler tail, затем повторить тот же sealed 10/12/15 FPS набор серией прогонов. До закрытия repeatability production switch не разрешён."
|
||||
: hardening
|
||||
? "Сохранить разгрузку cyclic GC и обязательный detector prewarm как текущий runtime baseline. Следующий этап — измерять запас realtime при росте сцены и числа семантических объектов, не добавляя второй детектор и не расширяя inference-нагрузку. Production switch не разрешён."
|
||||
: "Сохранить RF-DETR-L как risk-semantic shadow provider полного reference graph. Не классифицировать миллионы статических форм: неизвестное неподвижное препятствие остаётся geometry-owned и объезжается; классы сохраняются для людей, животных и транспорта. Production switch не разрешён.",
|
||||
}}
|
||||
|
||||
@@ -45,6 +45,38 @@ function resultPayload() {
|
||||
selected: false,
|
||||
...overrides,
|
||||
});
|
||||
const loadScenario = (id, loadPurpose, rate, delivered, superseded, targetPassed) => ({
|
||||
id,
|
||||
load_purpose: loadPurpose,
|
||||
requested_source_rate_hz: rate,
|
||||
source_frames_admitted: 4489,
|
||||
delivered_world_states: delivered,
|
||||
superseded_frames: superseded,
|
||||
delivery_ratio: delivered / 4489,
|
||||
effective_world_state_fps: rate * 0.975,
|
||||
world_state_completion_age_p95_ms: 75,
|
||||
world_state_completion_age_p99_ms: 100,
|
||||
world_state_completion_age_maximum_ms: 400,
|
||||
decode_p95_ms: 12,
|
||||
decode_maximum_ms: 3200,
|
||||
detector_p95_ms: 40,
|
||||
detector_maximum_ms: 370,
|
||||
gpu_utilization_mean_percent: 35,
|
||||
gpu_utilization_maximum_percent: 85,
|
||||
gpu_memory_maximum_mib: 9584,
|
||||
process_peak_rss_mib: 2327,
|
||||
queue_high_watermarks: { detector: 2, geometry: 2, temporal: 2, rolling: 2, threat: 2 },
|
||||
queue_capacity: 2,
|
||||
additional_inference_passes: 0,
|
||||
integrity_gate_passed: true,
|
||||
operating_target_gate_passed: targetPassed,
|
||||
thresholds: {
|
||||
minimum_delivery_ratio: rate === 10 ? 0.999 : rate === 12 ? 0.995 : 0.95,
|
||||
minimum_effective_world_state_fps: rate * 0.95,
|
||||
maximum_world_state_completion_p95_ms: rate === 10 ? 125 : rate === 12 ? 150 : 175,
|
||||
},
|
||||
frame_evidence_sha256: "8".repeat(64),
|
||||
});
|
||||
return {
|
||||
schema_version: "missioncore.m48s-fixed-class-detector-result-view/v1",
|
||||
result_id: resultId,
|
||||
@@ -172,6 +204,20 @@ function resultPayload() {
|
||||
validation_frames: 1000,
|
||||
},
|
||||
},
|
||||
load_envelope: {
|
||||
schema_version: "missioncore.m48s-load-envelope-comparison/v1",
|
||||
production_rate_repeatability_passed: false,
|
||||
reserve_12_fps_passed: true,
|
||||
limit_15_fps_passed: true,
|
||||
load_envelope_accepted: false,
|
||||
compute_capacity_at_least_fps: 15,
|
||||
bottleneck_interpretation: "rare-source-decode-or-scheduling-tail-not-steady-gpu-saturation",
|
||||
scenarios: [
|
||||
loadScenario("production-10fps", "production-rate", 10, 4483, 6, false),
|
||||
loadScenario("reserve-12fps", "reserve-gate", 12, 4477, 12, true),
|
||||
loadScenario("limit-15fps", "limit-discovery", 15, 4488, 1, true),
|
||||
],
|
||||
},
|
||||
},
|
||||
decision: {
|
||||
selected_candidate: "rf-detr",
|
||||
@@ -179,6 +225,11 @@ function resultPayload() {
|
||||
integrated_world_state_gate_evaluated: true,
|
||||
integrated_world_state_gate_passed: true,
|
||||
detector_replacement_authorized: false,
|
||||
load_envelope_evaluated: true,
|
||||
production_rate_repeatability_passed: false,
|
||||
reserve_12_fps_passed: true,
|
||||
limit_15_fps_passed: true,
|
||||
load_envelope_accepted: false,
|
||||
production_accepted: false,
|
||||
},
|
||||
limitations: ["No independent semantic ground truth."],
|
||||
@@ -212,6 +263,10 @@ test("M4.8S result exposes complete graph load without production authority", as
|
||||
assert.equal(result.metrics.runtimeHardening.baseline.supersededFrames, 9);
|
||||
assert.equal(result.metrics.runtimeHardening.hardened.supersededFrames, 1);
|
||||
assert.equal(result.metrics.runtimeHardening.startup.prewarmed.worldStateMs, 60.516957);
|
||||
assert.equal(result.metrics.loadEnvelope.scenarios[0].operatingTargetGatePassed, false);
|
||||
assert.equal(result.metrics.loadEnvelope.scenarios[1].deliveredWorldStates, 4477);
|
||||
assert.equal(result.metrics.loadEnvelope.computeCapacityAtLeastFps, 15);
|
||||
assert.equal(result.decision.loadEnvelopeAccepted, false);
|
||||
assert.equal(result.decision.integratedWorldStateGatePassed, true);
|
||||
assert.equal(result.decision.productionAccepted, false);
|
||||
assert.equal(result.authority.navigationOrSafetyAccepted, false);
|
||||
|
||||
@@ -249,7 +249,7 @@
|
||||
},
|
||||
{
|
||||
"catalog_id": "m48s-fixed-class-detector",
|
||||
"evidence_id": "m48s-fixed-class-detector-lab-7411aadc35f5b61b97ee59c983e125e0a3781612d399c4dfa779b272eeb0e56e",
|
||||
"evidence_id": "m48s-fixed-class-detector-lab-4a901d811f53734540337f8d1f2c01666539aa0a9b7786f26d4f1f2e08cc858a",
|
||||
"signal": "progress",
|
||||
"lifecycle": "current",
|
||||
"visual_evidence": "available"
|
||||
|
||||
@@ -22,6 +22,7 @@ CATALOG_SCHEMA: Final = "missioncore.m48s-fixed-class-detector-frame-catalog/v1"
|
||||
FRAME_SCHEMA: Final = "missioncore.m48s-fixed-class-detector-frame/v1"
|
||||
REPORT_SCHEMA: Final = "missioncore.m48s-fixed-class-detector-report/v1"
|
||||
RUNTIME_HARDENING_SCHEMA: Final = "missioncore.m48s-runtime-hardening-comparison/v1"
|
||||
LOAD_ENVELOPE_SCHEMA: Final = "missioncore.m48s-load-envelope-comparison/v1"
|
||||
METHOD_SCHEMA: Final = "missioncore.laboratory-method/v1"
|
||||
RESULT_PREFIX: Final = "m48s-fixed-class-detector-lab-"
|
||||
TOURNAMENT_ID: Final = (
|
||||
@@ -65,6 +66,47 @@ RUNTIME_HARDENING_RUNS: Final = {
|
||||
"frame_count": 1000,
|
||||
},
|
||||
}
|
||||
LOAD_ENVELOPE_RUNS: Final = {
|
||||
"production-10fps": {
|
||||
"run_id": "m48s-load-envelope-v1-production-10fps-a1",
|
||||
"load_purpose": "production-rate",
|
||||
"source_rate_hz": 10.0,
|
||||
"result_sha256": "60d4d82a8d47e5087019640353c9f8f7ddae518b52801dfd8c64423f5aba9fe2",
|
||||
"frames_sha256": "9e836f13a49390be498ce2b133fe2c20538af43adf667b0e7b89dc6349379ab0",
|
||||
"delivered": 4483,
|
||||
"superseded": 6,
|
||||
"operating_target_gate_passed": False,
|
||||
},
|
||||
"reserve-12fps": {
|
||||
"run_id": "m48s-load-envelope-v1-reserve-12fps-a1",
|
||||
"load_purpose": "reserve-gate",
|
||||
"source_rate_hz": 12.0,
|
||||
"result_sha256": "c8cb917f6f3a8cb6ffcc5146211066dbaed4aa2d8671e55820c266c49d5d5321",
|
||||
"frames_sha256": "3c1e635f6fbea643024bbd1711fb6c1ed5380430972cbb434ec76f4488d1c8b7",
|
||||
"delivered": 4477,
|
||||
"superseded": 12,
|
||||
"operating_target_gate_passed": True,
|
||||
},
|
||||
"limit-15fps": {
|
||||
"run_id": "m48s-load-envelope-v1-limit-15fps-a1",
|
||||
"load_purpose": "limit-discovery",
|
||||
"source_rate_hz": 15.0,
|
||||
"result_sha256": "a78767ee2a7d8f3f7f7625c408e9bc8fb6c60e8ba6f77ab54fddbca018540713",
|
||||
"frames_sha256": "8be16ed155111ffa7093bbf46ceda4bc679593bfaf7a00c38c5d50c2385138d0",
|
||||
"delivered": 4488,
|
||||
"superseded": 1,
|
||||
"operating_target_gate_passed": True,
|
||||
},
|
||||
}
|
||||
LOAD_ENVELOPE_PROFILE_SHA256: Final = (
|
||||
"d63c711534d84ee526d056885cfa0b5221df61d8394b244188b735bb34d20869"
|
||||
)
|
||||
LOAD_RUNTIME_ARTIFACT_SHA256: Final = (
|
||||
"c2344c91ce48111abb364cad38bd73fca9e5b30c8d001c113718dc1b30a8d859"
|
||||
)
|
||||
LOAD_RUNNER_SHA256: Final = (
|
||||
"0ff2ed9bdf5d5982cce08c4930853f65aa7be2c5986afacfe6a7cf925a2815e9"
|
||||
)
|
||||
YOLOX_ID: Final = (
|
||||
"m48s-yolox-all-coco-shadow-7dbe6043b3fc12c7ddb162f609f883d86b34a4f2dd3785a632795f257e192d06"
|
||||
)
|
||||
@@ -149,6 +191,11 @@ def build_m48s_fixed_class_detector_lab(
|
||||
}
|
||||
for name, definition in RUNTIME_HARDENING_RUNS.items()
|
||||
}
|
||||
load_envelope_profile_path = repository / "config/perception/m48s-load-envelope-v1.json"
|
||||
load_envelope_paths = {
|
||||
name: runtime / "load-envelope-worker" / str(definition["run_id"]) / "result.json"
|
||||
for name, definition in LOAD_ENVELOPE_RUNS.items()
|
||||
}
|
||||
yolox_root = runtime / "yolox-all-coco-results" / YOLOX_ID
|
||||
yolox_manifest_path = yolox_root / "manifest.json"
|
||||
yolox_frames_path = yolox_root / "frames.jsonl"
|
||||
@@ -171,6 +218,8 @@ def build_m48s_fixed_class_detector_lab(
|
||||
dfine_path,
|
||||
rf_detr_path,
|
||||
profile_path,
|
||||
load_envelope_profile_path,
|
||||
*load_envelope_paths.values(),
|
||||
*(path for paths in hardening_paths.values() for path in paths.values()),
|
||||
):
|
||||
if path.is_symlink() or not path.is_file():
|
||||
@@ -188,6 +237,10 @@ def build_m48s_fixed_class_detector_lab(
|
||||
hardening_runs = {
|
||||
name: _read_object(paths["result"]) for name, paths in hardening_paths.items()
|
||||
}
|
||||
load_envelope_profile = _read_object(load_envelope_profile_path)
|
||||
load_envelope_runs = {
|
||||
name: _read_object(path) for name, path in load_envelope_paths.items()
|
||||
}
|
||||
hardening_first_frames = {
|
||||
name: _read_first_jsonl_object(paths["frames"])
|
||||
for name, paths in hardening_paths.items()
|
||||
@@ -215,6 +268,10 @@ def build_m48s_fixed_class_detector_lab(
|
||||
hardening_runs=hardening_runs,
|
||||
hardening_first_frames=hardening_first_frames,
|
||||
hardening_paths=hardening_paths,
|
||||
load_envelope_profile=load_envelope_profile,
|
||||
load_envelope_profile_path=load_envelope_profile_path,
|
||||
load_envelope_runs=load_envelope_runs,
|
||||
load_envelope_paths=load_envelope_paths,
|
||||
)
|
||||
|
||||
source_paths = {frame_id: source_root / f"frame-{frame_id}.jpg" for frame_id in FRAME_IDS}
|
||||
@@ -277,6 +334,16 @@ def build_m48s_fixed_class_detector_lab(
|
||||
}
|
||||
for name, paths in hardening_paths.items()
|
||||
},
|
||||
"load_envelope": {
|
||||
"profile_sha256": sha256_path(load_envelope_profile_path),
|
||||
"runs": {
|
||||
name: {
|
||||
"result_sha256": sha256_path(load_envelope_paths[name]),
|
||||
"frames_sha256": run["execution"]["frame_evidence"]["sha256"],
|
||||
}
|
||||
for name, run in load_envelope_runs.items()
|
||||
},
|
||||
},
|
||||
"yolox_result_id": YOLOX_ID,
|
||||
"yolox_document_sha256": sha256_path(yolox_manifest_path),
|
||||
},
|
||||
@@ -285,7 +352,7 @@ def build_m48s_fixed_class_detector_lab(
|
||||
}
|
||||
identity_sha256 = hashlib.sha256(canonical_json(identity)).hexdigest()
|
||||
result_id = RESULT_PREFIX + identity_sha256
|
||||
completed_utc_ns = hardening_runs["prewarmed"].get("completed_utc_ns")
|
||||
completed_utc_ns = load_envelope_runs["limit-15fps"].get("completed_utc_ns")
|
||||
if not isinstance(completed_utc_ns, int) or isinstance(completed_utc_ns, bool):
|
||||
raise M48SFixedClassDetectorLabError(
|
||||
"complete reference-graph completion time is unavailable"
|
||||
@@ -309,6 +376,7 @@ def build_m48s_fixed_class_detector_lab(
|
||||
candidates=candidates,
|
||||
hardening_runs=hardening_runs,
|
||||
hardening_first_frames=hardening_first_frames,
|
||||
load_envelope_runs=load_envelope_runs,
|
||||
)
|
||||
decision = {
|
||||
"bounded_question_accepted": True,
|
||||
@@ -317,6 +385,11 @@ def build_m48s_fixed_class_detector_lab(
|
||||
"integrated_world_state_gate_evaluated": True,
|
||||
"integrated_world_state_gate_passed": True,
|
||||
"full_replay_visual_published": True,
|
||||
"load_envelope_evaluated": True,
|
||||
"production_rate_repeatability_passed": False,
|
||||
"reserve_12_fps_passed": True,
|
||||
"limit_15_fps_passed": True,
|
||||
"load_envelope_accepted": False,
|
||||
"detector_replacement_authorized": False,
|
||||
"production_accepted": False,
|
||||
}
|
||||
@@ -335,6 +408,11 @@ def build_m48s_fixed_class_detector_lab(
|
||||
"The visual timeline is the original qualified semantic replay; runtime-hardening "
|
||||
"metrics come from separately sealed, input-identical replay runs."
|
||||
),
|
||||
(
|
||||
"The 12 and 15 FPS operating gates passed, but the separately predeclared 10 FPS "
|
||||
"delivery-ratio gate missed by two frames; capacity is demonstrated while delivery "
|
||||
"repeatability remains open."
|
||||
),
|
||||
]
|
||||
|
||||
root = output_root.expanduser().absolute()
|
||||
@@ -421,6 +499,12 @@ def build_m48s_fixed_class_detector_lab(
|
||||
)
|
||||
for name, paths in hardening_paths.items():
|
||||
shutil.copyfile(paths["result"], temporary / f"runtime-hardening-{name}.json")
|
||||
shutil.copyfile(
|
||||
load_envelope_profile_path,
|
||||
temporary / "runtime-load-envelope-profile.json",
|
||||
)
|
||||
for name, path in load_envelope_paths.items():
|
||||
shutil.copyfile(path, temporary / f"runtime-load-{name}.json")
|
||||
startup_evidence = {
|
||||
"schema_version": RUNTIME_HARDENING_SCHEMA,
|
||||
"source_frames_sha256": {
|
||||
@@ -441,11 +525,15 @@ def build_m48s_fixed_class_detector_lab(
|
||||
"detector_load": load["execution"],
|
||||
"complete_reference_graph": reference_graph["identity"]["evidence"]["execution"],
|
||||
"runtime_hardening": metrics["runtime_hardening"],
|
||||
"load_envelope": metrics["load_envelope"],
|
||||
},
|
||||
"metrics": metrics,
|
||||
"acceptance": {
|
||||
"detector_load": load["checks"],
|
||||
"complete_reference_graph": reference_graph["identity"]["evidence"]["checks"],
|
||||
"load_envelope": {
|
||||
name: run["checks"] for name, run in load_envelope_runs.items()
|
||||
},
|
||||
},
|
||||
"decision": decision,
|
||||
"limitations": limitations,
|
||||
@@ -515,6 +603,10 @@ def _validate_inputs(
|
||||
hardening_runs: dict[str, dict[str, Any]],
|
||||
hardening_first_frames: dict[str, dict[str, Any]],
|
||||
hardening_paths: dict[str, dict[str, Path]],
|
||||
load_envelope_profile: dict[str, Any],
|
||||
load_envelope_profile_path: Path,
|
||||
load_envelope_runs: dict[str, dict[str, Any]],
|
||||
load_envelope_paths: dict[str, Path],
|
||||
) -> None:
|
||||
decision = deployment.get("decision")
|
||||
graph_identity = reference_graph.get("identity")
|
||||
@@ -654,6 +746,101 @@ def _validate_inputs(
|
||||
raise M48SFixedClassDetectorLabError(
|
||||
f"runtime-hardening startup evidence changed: {name}"
|
||||
)
|
||||
_validate_load_envelope(
|
||||
profile=load_envelope_profile,
|
||||
profile_path=load_envelope_profile_path,
|
||||
runs=load_envelope_runs,
|
||||
paths=load_envelope_paths,
|
||||
)
|
||||
|
||||
|
||||
def _validate_load_envelope(
|
||||
*,
|
||||
profile: dict[str, Any],
|
||||
profile_path: Path,
|
||||
runs: dict[str, dict[str, Any]],
|
||||
paths: dict[str, Path],
|
||||
) -> None:
|
||||
scenarios = profile.get("scenarios")
|
||||
if (
|
||||
profile.get("schema_version") != "missioncore.m48s-load-envelope-profile/v1"
|
||||
or profile.get("profile_id") != "m48s-rf-detr-reference-graph-load-envelope/v1"
|
||||
or sha256_path(profile_path) != LOAD_ENVELOPE_PROFILE_SHA256
|
||||
or not isinstance(scenarios, list)
|
||||
or len(scenarios) != len(LOAD_ENVELOPE_RUNS)
|
||||
):
|
||||
raise M48SFixedClassDetectorLabError("load-envelope profile identity changed")
|
||||
scenarios_by_id = {
|
||||
scenario.get("id"): scenario for scenario in scenarios if isinstance(scenario, dict)
|
||||
}
|
||||
if set(scenarios_by_id) != set(LOAD_ENVELOPE_RUNS):
|
||||
raise M48SFixedClassDetectorLabError("load-envelope scenarios changed")
|
||||
shared_inputs: dict[str, object] | None = None
|
||||
for name, definition in LOAD_ENVELOPE_RUNS.items():
|
||||
run = runs.get(name)
|
||||
path = paths.get(name)
|
||||
scenario = scenarios_by_id[name]
|
||||
if not isinstance(run, dict) or not isinstance(path, Path):
|
||||
raise M48SFixedClassDetectorLabError("load-envelope evidence is incomplete")
|
||||
source = run.get("source")
|
||||
identity = run.get("identity")
|
||||
execution = run.get("execution")
|
||||
integrity_checks = run.get("integrity_checks")
|
||||
thresholds = run.get("predeclared_thresholds")
|
||||
frame_evidence = execution.get("frame_evidence") if isinstance(execution, dict) else None
|
||||
terminal = execution.get("terminal_outcomes") if isinstance(execution, dict) else None
|
||||
pipeline = run.get("metrics", {}).get("pipeline_timing")
|
||||
if (
|
||||
run.get("schema_version") != "missioncore.m48s-reference-graph-shadow-load/v4"
|
||||
or run.get("completed") is not True
|
||||
or run.get("production_accepted") is not False
|
||||
or run.get("authority") != false_authority()
|
||||
or run.get("evidence_integrity_gate_passed") is not True
|
||||
or run.get("operating_target_gate_passed")
|
||||
is not definition["operating_target_gate_passed"]
|
||||
or not isinstance(integrity_checks, dict)
|
||||
or not integrity_checks
|
||||
or not all(value is True for value in integrity_checks.values())
|
||||
or not isinstance(source, dict)
|
||||
or source.get("source_id") != "RAVNOVES00"
|
||||
or source.get("pacing_contract")
|
||||
!= "wall-clock-scaled-source-timestamps-immutable/v1"
|
||||
or source.get("requested_rate_hz") != definition["source_rate_hz"]
|
||||
or not isinstance(identity, dict)
|
||||
or identity.get("worker_id") != "worker-006"
|
||||
or identity.get("graph_id") != "reference-perception-graph/v2"
|
||||
or identity.get("detector_provider_id")
|
||||
!= "triton-rf-detr-large-coco-risk-fp16-shadow/v0"
|
||||
or identity.get("runtime_artifact_sha256") != LOAD_RUNTIME_ARTIFACT_SHA256
|
||||
or identity.get("runner_sha256") != LOAD_RUNNER_SHA256
|
||||
or not isinstance(execution, dict)
|
||||
or execution.get("load_purpose") != definition["load_purpose"]
|
||||
or execution.get("requested_source_rate_hz") != definition["source_rate_hz"]
|
||||
or execution.get("source_timestamps_preserved") is not True
|
||||
or execution.get("admitted_frames") != 4489
|
||||
or execution.get("delivered_world_states") != definition["delivered"]
|
||||
or not isinstance(terminal, dict)
|
||||
or terminal.get("delivered") != definition["delivered"]
|
||||
or terminal.get("superseded") != definition["superseded"]
|
||||
or sum(terminal.values()) != 4489
|
||||
or not isinstance(frame_evidence, dict)
|
||||
or frame_evidence.get("row_count") != definition["delivered"]
|
||||
or frame_evidence.get("sha256") != definition["frames_sha256"]
|
||||
or not isinstance(pipeline, dict)
|
||||
or pipeline.get("additional_inference_passes") != 0
|
||||
or thresholds != scenario.get("thresholds")
|
||||
or sha256_path(path) != definition["result_sha256"]
|
||||
):
|
||||
raise M48SFixedClassDetectorLabError(
|
||||
f"sealed load-envelope evidence changed: {name}"
|
||||
)
|
||||
inputs = identity.get("inputs")
|
||||
if not isinstance(inputs, dict):
|
||||
raise M48SFixedClassDetectorLabError("load-envelope input identity is unavailable")
|
||||
if shared_inputs is None:
|
||||
shared_inputs = inputs
|
||||
elif inputs != shared_inputs:
|
||||
raise M48SFixedClassDetectorLabError("load-envelope runs changed graph inputs")
|
||||
|
||||
|
||||
def _method(
|
||||
@@ -791,6 +978,7 @@ def _metrics(
|
||||
candidates: list[dict[str, object]],
|
||||
hardening_runs: dict[str, dict[str, Any]],
|
||||
hardening_first_frames: dict[str, dict[str, Any]],
|
||||
load_envelope_runs: dict[str, dict[str, Any]],
|
||||
) -> dict[str, object]:
|
||||
graph_evidence = reference_graph["identity"]["evidence"]
|
||||
graph_execution = graph_evidence["execution"]
|
||||
@@ -860,6 +1048,62 @@ def _metrics(
|
||||
runs=hardening_runs,
|
||||
first_frames=hardening_first_frames,
|
||||
),
|
||||
"load_envelope": _load_envelope_metrics(load_envelope_runs),
|
||||
}
|
||||
|
||||
|
||||
def _load_envelope_metrics(runs: dict[str, dict[str, Any]]) -> dict[str, object]:
|
||||
scenarios: list[dict[str, object]] = []
|
||||
for name in LOAD_ENVELOPE_RUNS:
|
||||
run = runs[name]
|
||||
execution = run["execution"]
|
||||
metrics = run["metrics"]
|
||||
completion = metrics["world_state_completion_age_ms"]
|
||||
gpu = metrics["gpu"]
|
||||
pipeline = metrics["pipeline_timing"]
|
||||
terminal = execution["terminal_outcomes"]
|
||||
thresholds = run["predeclared_thresholds"]
|
||||
scenarios.append(
|
||||
{
|
||||
"id": name,
|
||||
"load_purpose": execution["load_purpose"],
|
||||
"requested_source_rate_hz": execution["requested_source_rate_hz"],
|
||||
"source_frames_admitted": execution["admitted_frames"],
|
||||
"delivered_world_states": execution["delivered_world_states"],
|
||||
"superseded_frames": terminal.get("superseded", 0),
|
||||
"delivery_ratio": execution["delivery_ratio"],
|
||||
"effective_world_state_fps": execution["effective_world_state_fps"],
|
||||
"world_state_completion_age_p95_ms": completion["p95"],
|
||||
"world_state_completion_age_p99_ms": completion["p99"],
|
||||
"world_state_completion_age_maximum_ms": completion["maximum"],
|
||||
"decode_p95_ms": pipeline["decode_duration_ms"]["p95"],
|
||||
"decode_maximum_ms": pipeline["decode_duration_ms"]["maximum"],
|
||||
"detector_p95_ms": pipeline["detector_ms"]["total"]["p95"],
|
||||
"detector_maximum_ms": pipeline["detector_ms"]["total"]["maximum"],
|
||||
"gpu_utilization_mean_percent": gpu["gpu_utilization_percent"]["mean"],
|
||||
"gpu_utilization_maximum_percent": gpu["gpu_utilization_percent"]["maximum"],
|
||||
"gpu_memory_maximum_mib": gpu["gpu_memory_used_mib"]["maximum"],
|
||||
"process_peak_rss_mib": metrics["process_peak_rss_after_mib"],
|
||||
"queue_high_watermarks": execution["queue_high_watermarks"],
|
||||
"queue_capacity": 2,
|
||||
"additional_inference_passes": pipeline["additional_inference_passes"],
|
||||
"integrity_gate_passed": run["evidence_integrity_gate_passed"],
|
||||
"operating_target_gate_passed": run["operating_target_gate_passed"],
|
||||
"thresholds": thresholds,
|
||||
"frame_evidence_sha256": execution["frame_evidence"]["sha256"],
|
||||
}
|
||||
)
|
||||
return {
|
||||
"schema_version": LOAD_ENVELOPE_SCHEMA,
|
||||
"production_rate_repeatability_passed": False,
|
||||
"reserve_12_fps_passed": True,
|
||||
"limit_15_fps_passed": True,
|
||||
"load_envelope_accepted": False,
|
||||
"compute_capacity_at_least_fps": 15.0,
|
||||
"bottleneck_interpretation": (
|
||||
"rare-source-decode-or-scheduling-tail-not-steady-gpu-saturation"
|
||||
),
|
||||
"scenarios": scenarios,
|
||||
}
|
||||
|
||||
|
||||
@@ -1016,6 +1260,12 @@ def _artifact_manifest(root: Path) -> list[dict[str, object]]:
|
||||
RUNTIME_HARDENING_SCHEMA if relative == "runtime-hardening-startup.json" else None
|
||||
)
|
||||
role = "upstream-runtime-hardening-evidence"
|
||||
elif relative == "runtime-load-envelope-profile.json":
|
||||
schema_version = "missioncore.m48s-load-envelope-profile/v1"
|
||||
role = "predeclared-load-envelope-profile"
|
||||
elif relative.startswith("runtime-load-"):
|
||||
schema_version = "missioncore.m48s-reference-graph-shadow-load/v4"
|
||||
role = "upstream-load-envelope-evidence"
|
||||
artifacts.append(
|
||||
{
|
||||
"role": role,
|
||||
|
||||
@@ -331,6 +331,16 @@ def _load_result_uncached(candidate: Path) -> dict[str, Any]:
|
||||
or decision.get("integrated_world_state_gate_evaluated") is not integrated
|
||||
or (integrated and decision.get("integrated_world_state_gate_passed") is not True)
|
||||
or (integrated and decision.get("detector_replacement_authorized") is not False)
|
||||
or (
|
||||
metrics.get("load_envelope") is not None
|
||||
and (
|
||||
decision.get("load_envelope_evaluated") is not True
|
||||
or decision.get("production_rate_repeatability_passed") is not False
|
||||
or decision.get("reserve_12_fps_passed") is not True
|
||||
or decision.get("limit_15_fps_passed") is not True
|
||||
or decision.get("load_envelope_accepted") is not False
|
||||
)
|
||||
)
|
||||
or decision.get("production_accepted") is not False
|
||||
or not isinstance(method, dict)
|
||||
or method.get("schema_version") != "missioncore.laboratory-method/v1"
|
||||
@@ -341,6 +351,10 @@ def _load_result_uncached(candidate: Path) -> dict[str, Any]:
|
||||
metrics.get("runtime_hardening") is not None
|
||||
and not _valid_runtime_hardening(metrics["runtime_hardening"])
|
||||
)
|
||||
or (
|
||||
metrics.get("load_envelope") is not None
|
||||
and not _valid_load_envelope(metrics["load_envelope"])
|
||||
)
|
||||
or not isinstance(manifest.get("limitations"), list)
|
||||
or not isinstance(catalog_descriptor, dict)
|
||||
or catalog_descriptor.get("path") != "catalog.json"
|
||||
@@ -420,6 +434,67 @@ def _valid_runtime_hardening(value: object) -> bool:
|
||||
)
|
||||
|
||||
|
||||
def _valid_load_envelope(value: object) -> bool:
|
||||
if not isinstance(value, dict) or value.get("schema_version") != (
|
||||
"missioncore.m48s-load-envelope-comparison/v1"
|
||||
):
|
||||
return False
|
||||
if (
|
||||
value.get("production_rate_repeatability_passed") is not False
|
||||
or value.get("reserve_12_fps_passed") is not True
|
||||
or value.get("limit_15_fps_passed") is not True
|
||||
or value.get("load_envelope_accepted") is not False
|
||||
or value.get("compute_capacity_at_least_fps") != 15.0
|
||||
or value.get("bottleneck_interpretation")
|
||||
!= "rare-source-decode-or-scheduling-tail-not-steady-gpu-saturation"
|
||||
):
|
||||
return False
|
||||
scenarios = value.get("scenarios")
|
||||
scenario_ids = [item.get("id") for item in scenarios if isinstance(item, dict)] if (
|
||||
isinstance(scenarios, list)
|
||||
) else []
|
||||
if scenario_ids != ["production-10fps", "reserve-12fps", "limit-15fps"]:
|
||||
return False
|
||||
expected_targets = (False, True, True)
|
||||
required_numeric = {
|
||||
"requested_source_rate_hz",
|
||||
"source_frames_admitted",
|
||||
"delivered_world_states",
|
||||
"superseded_frames",
|
||||
"delivery_ratio",
|
||||
"effective_world_state_fps",
|
||||
"world_state_completion_age_p95_ms",
|
||||
"world_state_completion_age_p99_ms",
|
||||
"world_state_completion_age_maximum_ms",
|
||||
"decode_p95_ms",
|
||||
"decode_maximum_ms",
|
||||
"detector_p95_ms",
|
||||
"detector_maximum_ms",
|
||||
"gpu_utilization_mean_percent",
|
||||
"gpu_utilization_maximum_percent",
|
||||
"gpu_memory_maximum_mib",
|
||||
"process_peak_rss_mib",
|
||||
"queue_capacity",
|
||||
"additional_inference_passes",
|
||||
}
|
||||
for scenario, target in zip(scenarios, expected_targets, strict=True):
|
||||
if (
|
||||
not isinstance(scenario, dict)
|
||||
or scenario.get("integrity_gate_passed") is not True
|
||||
or scenario.get("operating_target_gate_passed") is not target
|
||||
or scenario.get("additional_inference_passes") != 0
|
||||
or scenario.get("queue_capacity") != 2
|
||||
or not isinstance(scenario.get("queue_high_watermarks"), dict)
|
||||
or any(value != 2 for value in scenario["queue_high_watermarks"].values())
|
||||
or not isinstance(scenario.get("thresholds"), dict)
|
||||
or any(not _nonnegative_number(scenario.get(key)) for key in required_numeric)
|
||||
or not isinstance(scenario.get("frame_evidence_sha256"), str)
|
||||
or SHA256.fullmatch(scenario["frame_evidence_sha256"]) is None
|
||||
):
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def _nonnegative_number(value: object) -> bool:
|
||||
return isinstance(value, (int, float)) and not isinstance(value, bool) and float(value) >= 0.0
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ def test_m48s_lab_seals_visual_comparison_and_load_evidence(tmp_path: Path) -> N
|
||||
assert manifest["result_id"] == result.result_id
|
||||
assert result.result_id.endswith(identity_digest)
|
||||
assert manifest["identity_sha256"] == identity_digest
|
||||
assert len(manifest["artifacts"]) == 35
|
||||
assert len(manifest["artifacts"]) == 39
|
||||
assert manifest["method"]["completeness"] == "complete"
|
||||
assert manifest["bounded_question_accepted"] is True
|
||||
assert manifest["ground_truth"] is False
|
||||
@@ -49,6 +49,11 @@ def test_m48s_lab_seals_visual_comparison_and_load_evidence(tmp_path: Path) -> N
|
||||
"integrated_world_state_gate_evaluated": True,
|
||||
"integrated_world_state_gate_passed": True,
|
||||
"full_replay_visual_published": True,
|
||||
"load_envelope_evaluated": True,
|
||||
"production_rate_repeatability_passed": False,
|
||||
"reserve_12_fps_passed": True,
|
||||
"limit_15_fps_passed": True,
|
||||
"load_envelope_accepted": False,
|
||||
"detector_replacement_authorized": False,
|
||||
"production_accepted": False,
|
||||
}
|
||||
@@ -80,6 +85,24 @@ def test_m48s_lab_seals_visual_comparison_and_load_evidence(tmp_path: Path) -> N
|
||||
assert hardening["startup"]["prewarmed"]["world_state_ms"] == 60.516957
|
||||
assert hardening["startup"]["prewarm_duration_ms"] == 420.721918
|
||||
assert hardening["startup"]["validation_frames"] == 1_000
|
||||
envelope = manifest["metrics"]["load_envelope"]
|
||||
assert envelope["schema_version"] == "missioncore.m48s-load-envelope-comparison/v1"
|
||||
assert envelope["production_rate_repeatability_passed"] is False
|
||||
assert envelope["reserve_12_fps_passed"] is True
|
||||
assert envelope["limit_15_fps_passed"] is True
|
||||
assert envelope["load_envelope_accepted"] is False
|
||||
assert envelope["compute_capacity_at_least_fps"] == 15.0
|
||||
production, reserve, limit = envelope["scenarios"]
|
||||
assert production["delivered_world_states"] == 4_483
|
||||
assert production["superseded_frames"] == 6
|
||||
assert production["operating_target_gate_passed"] is False
|
||||
assert reserve["delivered_world_states"] == 4_477
|
||||
assert reserve["superseded_frames"] == 12
|
||||
assert reserve["operating_target_gate_passed"] is True
|
||||
assert limit["delivered_world_states"] == 4_488
|
||||
assert limit["superseded_frames"] == 1
|
||||
assert limit["operating_target_gate_passed"] is True
|
||||
assert all(item["additional_inference_passes"] == 0 for item in envelope["scenarios"])
|
||||
|
||||
catalog = json.loads((result.result_root / "catalog.json").read_text("utf-8"))
|
||||
assert catalog["frame_count"] == len(FRAME_IDS) == 11
|
||||
@@ -99,7 +122,7 @@ def test_m48s_lab_seals_visual_comparison_and_load_evidence(tmp_path: Path) -> N
|
||||
)
|
||||
proof = verify_laboratory_evidence_result(definition, result.result_root)
|
||||
assert proof["result_id"] == result.result_id
|
||||
assert proof["artifact_count"] == 35
|
||||
assert proof["artifact_count"] == 39
|
||||
|
||||
with pytest.raises(M48SFixedClassDetectorLabError, match="already exists"):
|
||||
build_m48s_fixed_class_detector_lab(
|
||||
|
||||
@@ -51,6 +51,15 @@ def test_m48s_lab_api_projects_verified_result_frame_and_camera(tmp_path: Path)
|
||||
assert hardening["baseline"]["delivered_world_states"] == 4_480
|
||||
assert hardening["hardened"]["delivered_world_states"] == 4_488
|
||||
assert hardening["startup"]["prewarmed"]["world_state_ms"] == 60.516957
|
||||
envelope = result.json()["metrics"]["load_envelope"]
|
||||
assert envelope["production_rate_repeatability_passed"] is False
|
||||
assert envelope["reserve_12_fps_passed"] is True
|
||||
assert envelope["limit_15_fps_passed"] is True
|
||||
assert [item["requested_source_rate_hz"] for item in envelope["scenarios"]] == [
|
||||
10.0,
|
||||
12.0,
|
||||
15.0,
|
||||
]
|
||||
assert result.json()["ground_truth"] is False
|
||||
assert len(result.json()["frames"]) == 11
|
||||
|
||||
|
||||
Reference in New Issue
Block a user