add getModelStats method

pull/280/head
Vladimir Mandic 2022-07-02 03:39:40 -04:00
parent 8d9e086bf3
commit 3c3922800e
27 changed files with 687 additions and 530 deletions

View File

@ -9,7 +9,7 @@
## Changelog ## Changelog
### **HEAD -> main** 2022/06/10 mandic00@live.com ### **HEAD -> main** 2022/06/21 mandic00@live.com
### **release: 2.8.1** 2022/06/08 mandic00@live.com ### **release: 2.8.1** 2022/06/08 mandic00@live.com

File diff suppressed because one or more lines are too long

View File

@ -10,7 +10,7 @@
import { Human, Config } from '../../dist/human.esm.js'; // equivalent of @vladmandic/Human import { Human, Config } from '../../dist/human.esm.js'; // equivalent of @vladmandic/Human
const humanConfig: Partial<Config> = { // user configuration for human, used to fine-tune behavior const humanConfig: Partial<Config> = { // user configuration for human, used to fine-tune behavior
// backend: 'webgpu' as const, // backend: 'wasm' as const,
// wasmPath: 'https://cdn.jsdelivr.net/npm/@tensorflow/tfjs-backend-wasm@3.18.0/dist/', // wasmPath: 'https://cdn.jsdelivr.net/npm/@tensorflow/tfjs-backend-wasm@3.18.0/dist/',
// cacheSensitivity: 0, // cacheSensitivity: 0,
async: true, async: true,

15
dist/human.d.ts vendored
View File

@ -808,6 +808,12 @@ declare function getModelArtifactsForJSON(modelJSON: ModelJSON, loadWeights: (we
*/ */
declare function getModelArtifactsInfoForJSON(modelArtifacts: ModelArtifacts): ModelArtifactsInfo; declare function getModelArtifactsInfoForJSON(modelArtifacts: ModelArtifacts): ModelArtifactsInfo;
declare const getModelStats: () => {
sizeManifest: number;
sizeWeights: number;
numModels: number;
};
declare const getSaveHandlers: (url: string | string[]) => IOHandler[]; declare const getSaveHandlers: (url: string | string[]) => IOHandler[];
declare interface GPUData { declare interface GPUData {
@ -1302,6 +1308,12 @@ declare class Human {
* @returns result - {@link Result} * @returns result - {@link Result}
*/ */
next(result?: Result): Result; next(result?: Result): Result;
/** get model loading/loaded stats */
getModelStats: () => {
sizeManifest: number;
sizeWeights: number;
numModels: number;
};
/** Warmup method pre-initializes all configured models for faster inference /** Warmup method pre-initializes all configured models for faster inference
* - can take significant time on startup * - can take significant time on startup
* - only used for `webgl` and `humangl` backends * - only used for `webgl` and `humangl` backends
@ -1830,7 +1842,8 @@ declare namespace models {
reset, reset,
load, load,
validate, validate,
Models Models,
getModelStats
} }
} }
export { models } export { models }

View File

@ -808,6 +808,12 @@ declare function getModelArtifactsForJSON(modelJSON: ModelJSON, loadWeights: (we
*/ */
declare function getModelArtifactsInfoForJSON(modelArtifacts: ModelArtifacts): ModelArtifactsInfo; declare function getModelArtifactsInfoForJSON(modelArtifacts: ModelArtifacts): ModelArtifactsInfo;
declare const getModelStats: () => {
sizeManifest: number;
sizeWeights: number;
numModels: number;
};
declare const getSaveHandlers: (url: string | string[]) => IOHandler[]; declare const getSaveHandlers: (url: string | string[]) => IOHandler[];
declare interface GPUData { declare interface GPUData {
@ -1302,6 +1308,12 @@ declare class Human {
* @returns result - {@link Result} * @returns result - {@link Result}
*/ */
next(result?: Result): Result; next(result?: Result): Result;
/** get model loading/loaded stats */
getModelStats: () => {
sizeManifest: number;
sizeWeights: number;
numModels: number;
};
/** Warmup method pre-initializes all configured models for faster inference /** Warmup method pre-initializes all configured models for faster inference
* - can take significant time on startup * - can take significant time on startup
* - only used for `webgl` and `humangl` backends * - only used for `webgl` and `humangl` backends
@ -1830,7 +1842,8 @@ declare namespace models {
reset, reset,
load, load,
validate, validate,
Models Models,
getModelStats
} }
} }
export { models } export { models }

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

15
dist/human.esm.d.ts vendored
View File

@ -808,6 +808,12 @@ declare function getModelArtifactsForJSON(modelJSON: ModelJSON, loadWeights: (we
*/ */
declare function getModelArtifactsInfoForJSON(modelArtifacts: ModelArtifacts): ModelArtifactsInfo; declare function getModelArtifactsInfoForJSON(modelArtifacts: ModelArtifacts): ModelArtifactsInfo;
declare const getModelStats: () => {
sizeManifest: number;
sizeWeights: number;
numModels: number;
};
declare const getSaveHandlers: (url: string | string[]) => IOHandler[]; declare const getSaveHandlers: (url: string | string[]) => IOHandler[];
declare interface GPUData { declare interface GPUData {
@ -1302,6 +1308,12 @@ declare class Human {
* @returns result - {@link Result} * @returns result - {@link Result}
*/ */
next(result?: Result): Result; next(result?: Result): Result;
/** get model loading/loaded stats */
getModelStats: () => {
sizeManifest: number;
sizeWeights: number;
numModels: number;
};
/** Warmup method pre-initializes all configured models for faster inference /** Warmup method pre-initializes all configured models for faster inference
* - can take significant time on startup * - can take significant time on startup
* - only used for `webgl` and `humangl` backends * - only used for `webgl` and `humangl` backends
@ -1830,7 +1842,8 @@ declare namespace models {
reset, reset,
load, load,
validate, validate,
Models Models,
getModelStats
} }
} }
export { models } export { models }

43
dist/human.esm.js vendored
View File

@ -39165,6 +39165,7 @@ var options = {
debug: false, debug: false,
modelBasePath: "" modelBasePath: ""
}; };
var modelStats = {};
async function httpHandler(url, init2) { async function httpHandler(url, init2) {
if (options.debug) if (options.debug)
log("load model fetch:", url, init2); log("load model fetch:", url, init2);
@ -39176,29 +39177,39 @@ function setModelLoadOptions(config3) {
options.modelBasePath = config3.modelBasePath; options.modelBasePath = config3.modelBasePath;
} }
async function loadModel(modelPath) { async function loadModel(modelPath) {
var _a2, _b2, _c;
let modelUrl = join(options.modelBasePath, modelPath || ""); let modelUrl = join(options.modelBasePath, modelPath || "");
if (!modelUrl.toLowerCase().endsWith(".json")) if (!modelUrl.toLowerCase().endsWith(".json"))
modelUrl += ".json"; modelUrl += ".json";
const modelPathSegments = modelUrl.split("/"); const modelPathSegments = modelUrl.split("/");
const cachedModelName = "indexeddb://" + modelPathSegments[modelPathSegments.length - 1].replace(".json", ""); const shortModelName = modelPathSegments[modelPathSegments.length - 1].replace(".json", "");
const cachedModelName = "indexeddb://" + shortModelName;
modelStats[shortModelName] = {
name: shortModelName,
manifest: 0,
weights: 0,
cached: false
};
const cachedModels = await An.listModels(); const cachedModels = await An.listModels();
const modelCached = options.cacheModels && Object.keys(cachedModels).includes(cachedModelName); modelStats[shortModelName].cached = options.cacheModels && Object.keys(cachedModels).includes(cachedModelName);
const tfLoadOptions = typeof fetch === "undefined" ? {} : { fetchFunc: (url, init2) => httpHandler(url, init2) }; const tfLoadOptions = typeof fetch === "undefined" ? {} : { fetchFunc: (url, init2) => httpHandler(url, init2) };
const model18 = new P0(modelCached ? cachedModelName : modelUrl, tfLoadOptions); const model18 = new P0(modelStats[shortModelName].cached ? cachedModelName : modelUrl, tfLoadOptions);
let loaded = false; let loaded = false;
try { try {
model18.findIOHandler(); model18.findIOHandler();
if (options.debug) if (options.debug)
log("model load handler:", model18.handler); log("model load handler:", model18["handler"]);
const artifacts = await model18.handler.load(); const artifacts = await model18.handler.load();
modelStats[shortModelName].manifest = ((_a2 = artifacts == null ? void 0 : artifacts.weightData) == null ? void 0 : _a2.byteLength) || 0;
model18.loadSync(artifacts); model18.loadSync(artifacts);
modelStats[shortModelName].weights = ((_c = (_b2 = model18 == null ? void 0 : model18.artifacts) == null ? void 0 : _b2.weightData) == null ? void 0 : _c.byteLength) || 0;
if (options.verbose) if (options.verbose)
log("load model:", model18["modelUrl"]); log("load model:", model18["modelUrl"], { bytes: modelStats[shortModelName].weights });
loaded = true; loaded = true;
} catch (err) { } catch (err) {
log("error loading model:", modelUrl, err); log("error loading model:", modelUrl, err);
} }
if (loaded && options.cacheModels && !modelCached) { if (loaded && options.cacheModels && !modelStats[shortModelName].cached) {
try { try {
const saveResult = await model18.save(cachedModelName); const saveResult = await model18.save(cachedModelName);
log("model saved:", cachedModelName, saveResult); log("model saved:", cachedModelName, saveResult);
@ -39216,6 +39227,7 @@ var version = "2.8.1";
var models_exports = {}; var models_exports = {};
__export(models_exports, { __export(models_exports, {
Models: () => Models, Models: () => Models,
getModelStats: () => getModelStats,
load: () => load19, load: () => load19,
reset: () => reset, reset: () => reset,
validate: () => validate2 validate: () => validate2
@ -49303,6 +49315,15 @@ var Models = class {
__publicField(this, "antispoof", null); __publicField(this, "antispoof", null);
} }
}; };
var getModelStats = () => {
let sizeManifest = 0;
let sizeWeights = 0;
for (const m of Object.values(modelStats)) {
sizeManifest += m.manifest;
sizeWeights += m.weights;
}
return { sizeManifest, sizeWeights, numModels: Object.values(modelStats).length };
};
function reset(instance) { function reset(instance) {
for (const model18 of Object.keys(instance.models)) for (const model18 of Object.keys(instance.models))
instance.models[model18] = null; instance.models[model18] = null;
@ -49312,10 +49333,12 @@ async function load19(instance) {
if (env.initial) if (env.initial)
reset(instance); reset(instance);
if (instance.config.hand.enabled) { if (instance.config.hand.enabled) {
if (!instance.models.handpose && ((_b2 = (_a2 = instance.config.hand.detector) == null ? void 0 : _a2.modelPath) == null ? void 0 : _b2.includes("handdetect"))) if (!instance.models.handpose && ((_b2 = (_a2 = instance.config.hand.detector) == null ? void 0 : _a2.modelPath) == null ? void 0 : _b2.includes("handdetect"))) {
[instance.models.handpose, instance.models.handskeleton] = await load13(instance.config); [instance.models.handpose, instance.models.handskeleton] = await load13(instance.config);
if (!instance.models.handskeleton && instance.config.hand.landmarks && ((_d2 = (_c = instance.config.hand.detector) == null ? void 0 : _c.modelPath) == null ? void 0 : _d2.includes("handdetect"))) }
if (!instance.models.handskeleton && instance.config.hand.landmarks && ((_d2 = (_c = instance.config.hand.detector) == null ? void 0 : _c.modelPath) == null ? void 0 : _d2.includes("handdetect"))) {
[instance.models.handpose, instance.models.handskeleton] = await load13(instance.config); [instance.models.handpose, instance.models.handskeleton] = await load13(instance.config);
}
} }
if (instance.config.body.enabled && !instance.models.blazepose && ((_f = (_e2 = instance.config.body) == null ? void 0 : _e2.modelPath) == null ? void 0 : _f.includes("blazepose"))) if (instance.config.body.enabled && !instance.models.blazepose && ((_f = (_e2 = instance.config.body) == null ? void 0 : _e2.modelPath) == null ? void 0 : _f.includes("blazepose")))
instance.models.blazepose = loadPose(instance.config); instance.models.blazepose = loadPose(instance.config);
@ -49360,8 +49383,9 @@ async function load19(instance) {
if (instance.config.segmentation.enabled && !instance.models.segmentation) if (instance.config.segmentation.enabled && !instance.models.segmentation)
instance.models.segmentation = load18(instance.config); instance.models.segmentation = load18(instance.config);
for await (const model18 of Object.keys(instance.models)) { for await (const model18 of Object.keys(instance.models)) {
if (instance.models[model18] && typeof instance.models[model18] !== "undefined") if (instance.models[model18] && typeof instance.models[model18] !== "undefined") {
instance.models[model18] = await instance.models[model18]; instance.models[model18] = await instance.models[model18];
}
} }
} }
async function validate2(instance) { async function validate2(instance) {
@ -51782,6 +51806,7 @@ var Human = class {
if (this.events && this.events.dispatchEvent) if (this.events && this.events.dispatchEvent)
(_a2 = this.events) == null ? void 0 : _a2.dispatchEvent(new Event(event)); (_a2 = this.events) == null ? void 0 : _a2.dispatchEvent(new Event(event));
}); });
__publicField(this, "getModelStats", () => getModelStats());
var _a2; var _a2;
this.env = env; this.env = env;
const tfVersion = (((_a2 = Ghe) == null ? void 0 : _a2.tfjs) || Gpe).replace(/-(.*)/, ""); const tfVersion = (((_a2 = Ghe) == null ? void 0 : _a2.tfjs) || Gpe).replace(/-(.*)/, "");

File diff suppressed because one or more lines are too long

844
dist/human.js vendored

File diff suppressed because one or more lines are too long

View File

@ -808,6 +808,12 @@ declare function getModelArtifactsForJSON(modelJSON: ModelJSON, loadWeights: (we
*/ */
declare function getModelArtifactsInfoForJSON(modelArtifacts: ModelArtifacts): ModelArtifactsInfo; declare function getModelArtifactsInfoForJSON(modelArtifacts: ModelArtifacts): ModelArtifactsInfo;
declare const getModelStats: () => {
sizeManifest: number;
sizeWeights: number;
numModels: number;
};
declare const getSaveHandlers: (url: string | string[]) => IOHandler[]; declare const getSaveHandlers: (url: string | string[]) => IOHandler[];
declare interface GPUData { declare interface GPUData {
@ -1302,6 +1308,12 @@ declare class Human {
* @returns result - {@link Result} * @returns result - {@link Result}
*/ */
next(result?: Result): Result; next(result?: Result): Result;
/** get model loading/loaded stats */
getModelStats: () => {
sizeManifest: number;
sizeWeights: number;
numModels: number;
};
/** Warmup method pre-initializes all configured models for faster inference /** Warmup method pre-initializes all configured models for faster inference
* - can take significant time on startup * - can take significant time on startup
* - only used for `webgl` and `humangl` backends * - only used for `webgl` and `humangl` backends
@ -1830,7 +1842,8 @@ declare namespace models {
reset, reset,
load, load,
validate, validate,
Models Models,
getModelStats
} }
} }
export { models } export { models }

File diff suppressed because one or more lines are too long

View File

@ -808,6 +808,12 @@ declare function getModelArtifactsForJSON(modelJSON: ModelJSON, loadWeights: (we
*/ */
declare function getModelArtifactsInfoForJSON(modelArtifacts: ModelArtifacts): ModelArtifactsInfo; declare function getModelArtifactsInfoForJSON(modelArtifacts: ModelArtifacts): ModelArtifactsInfo;
declare const getModelStats: () => {
sizeManifest: number;
sizeWeights: number;
numModels: number;
};
declare const getSaveHandlers: (url: string | string[]) => IOHandler[]; declare const getSaveHandlers: (url: string | string[]) => IOHandler[];
declare interface GPUData { declare interface GPUData {
@ -1302,6 +1308,12 @@ declare class Human {
* @returns result - {@link Result} * @returns result - {@link Result}
*/ */
next(result?: Result): Result; next(result?: Result): Result;
/** get model loading/loaded stats */
getModelStats: () => {
sizeManifest: number;
sizeWeights: number;
numModels: number;
};
/** Warmup method pre-initializes all configured models for faster inference /** Warmup method pre-initializes all configured models for faster inference
* - can take significant time on startup * - can take significant time on startup
* - only used for `webgl` and `humangl` backends * - only used for `webgl` and `humangl` backends
@ -1830,7 +1842,8 @@ declare namespace models {
reset, reset,
load, load,
validate, validate,
Models Models,
getModelStats
} }
} }
export { models } export { models }

File diff suppressed because one or more lines are too long

15
dist/human.node.d.ts vendored
View File

@ -808,6 +808,12 @@ declare function getModelArtifactsForJSON(modelJSON: ModelJSON, loadWeights: (we
*/ */
declare function getModelArtifactsInfoForJSON(modelArtifacts: ModelArtifacts): ModelArtifactsInfo; declare function getModelArtifactsInfoForJSON(modelArtifacts: ModelArtifacts): ModelArtifactsInfo;
declare const getModelStats: () => {
sizeManifest: number;
sizeWeights: number;
numModels: number;
};
declare const getSaveHandlers: (url: string | string[]) => IOHandler[]; declare const getSaveHandlers: (url: string | string[]) => IOHandler[];
declare interface GPUData { declare interface GPUData {
@ -1302,6 +1308,12 @@ declare class Human {
* @returns result - {@link Result} * @returns result - {@link Result}
*/ */
next(result?: Result): Result; next(result?: Result): Result;
/** get model loading/loaded stats */
getModelStats: () => {
sizeManifest: number;
sizeWeights: number;
numModels: number;
};
/** Warmup method pre-initializes all configured models for faster inference /** Warmup method pre-initializes all configured models for faster inference
* - can take significant time on startup * - can take significant time on startup
* - only used for `webgl` and `humangl` backends * - only used for `webgl` and `humangl` backends
@ -1830,7 +1842,8 @@ declare namespace models {
reset, reset,
load, load,
validate, validate,
Models Models,
getModelStats
} }
} }
export { models } export { models }

20
dist/human.node.js vendored

File diff suppressed because one or more lines are too long

View File

@ -2,6 +2,7 @@
import { log } from '../util/util'; import { log } from '../util/util';
import * as tf from '../../dist/tfjs.esm.js'; import * as tf from '../../dist/tfjs.esm.js';
import { loadModel } from '../tfjs/load';
import type { GraphModel, Tensor } from '../tfjs/types'; import type { GraphModel, Tensor } from '../tfjs/types';
import type { Config } from '../config'; import type { Config } from '../config';
@ -56,7 +57,7 @@ export class FaceBoxes {
} }
export async function load(config) { export async function load(config) {
const model = await tf.loadGraphModel(config.face.detector.modelPath); const model = await loadModel(config.face.detector?.modelPath);
if (config.debug) log(`load model: ${config.face.detector.modelPath.match(/\/(.*)\./)[1]}`); if (config.debug) log(`load model: ${config.face.detector.modelPath.match(/\/(.*)\./)[1]}`);
const faceboxes = new FaceBoxes(model, config); const faceboxes = new FaceBoxes(model, config);
if (config.face.mesh.enabled && config.debug) log(`load model: ${config.face.mesh.modelPath.match(/\/(.*)\./)[1]}`); if (config.face.mesh.enabled && config.debug) log(`load model: ${config.face.mesh.modelPath.match(/\/(.*)\./)[1]}`);

View File

@ -329,6 +329,9 @@ export class Human {
return interpolate.calc(result, this.config) as Result; return interpolate.calc(result, this.config) as Result;
} }
/** get model loading/loaded stats */
getModelStats = () => models.getModelStats();
/** Warmup method pre-initializes all configured models for faster inference /** Warmup method pre-initializes all configured models for faster inference
* - can take significant time on startup * - can take significant time on startup
* - only used for `webgl` and `humangl` backends * - only used for `webgl` and `humangl` backends

View File

@ -24,6 +24,7 @@ import * as movenet from './body/movenet';
import * as nanodet from './object/nanodet'; import * as nanodet from './object/nanodet';
import * as posenet from './body/posenet'; import * as posenet from './body/posenet';
import * as segmentation from './segmentation/segmentation'; import * as segmentation from './segmentation/segmentation';
import { modelStats } from './tfjs/load';
import type { GraphModel } from './tfjs/types'; import type { GraphModel } from './tfjs/types';
import type { Human } from './human'; import type { Human } from './human';
@ -58,6 +59,16 @@ export class Models {
antispoof: null | GraphModel | Promise<GraphModel> = null; antispoof: null | GraphModel | Promise<GraphModel> = null;
} }
export const getModelStats = () => {
let sizeManifest = 0;
let sizeWeights = 0;
for (const m of Object.values(modelStats)) {
sizeManifest += m.manifest;
sizeWeights += m.weights;
}
return { sizeManifest, sizeWeights, numModels: Object.values(modelStats).length };
};
export function reset(instance: Human): void { export function reset(instance: Human): void {
// if (instance.config.debug) log('resetting loaded models'); // if (instance.config.debug) log('resetting loaded models');
for (const model of Object.keys(instance.models)) instance.models[model as keyof Models] = null; for (const model of Object.keys(instance.models)) instance.models[model as keyof Models] = null;
@ -67,8 +78,12 @@ export function reset(instance: Human): void {
export async function load(instance: Human): Promise<void> { export async function load(instance: Human): Promise<void> {
if (env.initial) reset(instance); if (env.initial) reset(instance);
if (instance.config.hand.enabled) { // handpose model is a combo that must be loaded as a whole if (instance.config.hand.enabled) { // handpose model is a combo that must be loaded as a whole
if (!instance.models.handpose && instance.config.hand.detector?.modelPath?.includes('handdetect')) [instance.models.handpose, instance.models.handskeleton] = await handpose.load(instance.config); if (!instance.models.handpose && instance.config.hand.detector?.modelPath?.includes('handdetect')) {
if (!instance.models.handskeleton && instance.config.hand.landmarks && instance.config.hand.detector?.modelPath?.includes('handdetect')) [instance.models.handpose, instance.models.handskeleton] = await handpose.load(instance.config); [instance.models.handpose, instance.models.handskeleton] = await handpose.load(instance.config);
}
if (!instance.models.handskeleton && instance.config.hand.landmarks && instance.config.hand.detector?.modelPath?.includes('handdetect')) {
[instance.models.handpose, instance.models.handskeleton] = await handpose.load(instance.config);
}
} }
if (instance.config.body.enabled && !instance.models.blazepose && instance.config.body?.modelPath?.includes('blazepose')) instance.models.blazepose = blazepose.loadPose(instance.config); if (instance.config.body.enabled && !instance.models.blazepose && instance.config.body?.modelPath?.includes('blazepose')) instance.models.blazepose = blazepose.loadPose(instance.config);
// @ts-ignore optional model // @ts-ignore optional model
@ -99,7 +114,9 @@ export async function load(instance: Human): Promise<void> {
// models are loaded in parallel asynchronously so lets wait until they are actually loaded // models are loaded in parallel asynchronously so lets wait until they are actually loaded
for await (const model of Object.keys(instance.models)) { for await (const model of Object.keys(instance.models)) {
if (instance.models[model as keyof Models] && typeof instance.models[model as keyof Models] !== 'undefined') instance.models[model as keyof Models] = await instance.models[model as keyof Models]; if (instance.models[model as keyof Models] && typeof instance.models[model as keyof Models] !== 'undefined') {
instance.models[model as keyof Models] = await instance.models[model as keyof Models];
}
} }
} }

View File

@ -10,6 +10,15 @@ const options = {
modelBasePath: '', modelBasePath: '',
}; };
type ModelStats = {
name: string,
cached: boolean,
manifest: number,
weights: number,
}
export const modelStats: Record<string, ModelStats> = {};
async function httpHandler(url, init?): Promise<Response | null> { async function httpHandler(url, init?): Promise<Response | null> {
if (options.debug) log('load model fetch:', url, init); if (options.debug) log('load model fetch:', url, init);
return fetch(url, init); return fetch(url, init);
@ -25,26 +34,35 @@ export async function loadModel(modelPath: string | undefined): Promise<GraphMod
let modelUrl = join(options.modelBasePath, modelPath || ''); let modelUrl = join(options.modelBasePath, modelPath || '');
if (!modelUrl.toLowerCase().endsWith('.json')) modelUrl += '.json'; if (!modelUrl.toLowerCase().endsWith('.json')) modelUrl += '.json';
const modelPathSegments = modelUrl.split('/'); const modelPathSegments = modelUrl.split('/');
const cachedModelName = 'indexeddb://' + modelPathSegments[modelPathSegments.length - 1].replace('.json', ''); // generate short model name for cache const shortModelName = modelPathSegments[modelPathSegments.length - 1].replace('.json', '');
const cachedModelName = 'indexeddb://' + shortModelName; // generate short model name for cache
modelStats[shortModelName] = {
name: shortModelName,
manifest: 0,
weights: 0,
cached: false,
};
const cachedModels = await tf.io.listModels(); // list all models already in cache const cachedModels = await tf.io.listModels(); // list all models already in cache
const modelCached = options.cacheModels && Object.keys(cachedModels).includes(cachedModelName); // is model found in cache modelStats[shortModelName].cached = options.cacheModels && Object.keys(cachedModels).includes(cachedModelName); // is model found in cache
const tfLoadOptions = typeof fetch === 'undefined' ? {} : { fetchFunc: (url, init?) => httpHandler(url, init) }; const tfLoadOptions = typeof fetch === 'undefined' ? {} : { fetchFunc: (url, init?) => httpHandler(url, init) };
const model: GraphModel = new tf.GraphModel(modelCached ? cachedModelName : modelUrl, tfLoadOptions) as unknown as GraphModel; // create model prototype and decide if load from cache or from original modelurl const model: GraphModel = new tf.GraphModel(modelStats[shortModelName].cached ? cachedModelName : modelUrl, tfLoadOptions) as unknown as GraphModel; // create model prototype and decide if load from cache or from original modelurl
let loaded = false; let loaded = false;
try { try {
// @ts-ignore private function // @ts-ignore private function
model.findIOHandler(); // decide how to actually load a model model.findIOHandler(); // decide how to actually load a model
// @ts-ignore private property if (options.debug) log('model load handler:', model['handler']);
if (options.debug) log('model load handler:', model.handler);
// @ts-ignore private property // @ts-ignore private property
const artifacts = await model.handler.load(); // load manifest const artifacts = await model.handler.load(); // load manifest
modelStats[shortModelName].manifest = artifacts?.weightData?.byteLength || 0;
model.loadSync(artifacts); // load weights model.loadSync(artifacts); // load weights
if (options.verbose) log('load model:', model['modelUrl']); // @ts-ignore private property
modelStats[shortModelName].weights = model?.artifacts?.weightData?.byteLength || 0;
if (options.verbose) log('load model:', model['modelUrl'], { bytes: modelStats[shortModelName].weights });
loaded = true; loaded = true;
} catch (err) { } catch (err) {
log('error loading model:', modelUrl, err); log('error loading model:', modelUrl, err);
} }
if (loaded && options.cacheModels && !modelCached) { // save model to cache if (loaded && options.cacheModels && !modelStats[shortModelName].cached) { // save model to cache
try { try {
const saveResult = await model.save(cachedModelName); const saveResult = await model.save(cachedModelName);
log('model saved:', cachedModelName, saveResult); log('model saved:', cachedModelName, saveResult);

View File

@ -1,24 +1,24 @@
2022-06-21 13:20:54 INFO:  Application: {"name":"@vladmandic/human","version":"2.8.1"} 2022-07-02 03:34:20 INFO:  Application: {"name":"@vladmandic/human","version":"2.8.1"}
2022-06-21 13:20:54 INFO:  Environment: {"profile":"production","config":".build.json","package":"package.json","tsconfig":true,"eslintrc":true,"git":true} 2022-07-02 03:34:20 INFO:  Environment: {"profile":"production","config":".build.json","package":"package.json","tsconfig":true,"eslintrc":true,"git":true}
2022-06-21 13:20:54 INFO:  Toolchain: {"build":"0.7.3","esbuild":"0.14.47","typescript":"4.7.4","typedoc":"0.22.17","eslint":"8.18.0"} 2022-07-02 03:34:20 INFO:  Toolchain: {"build":"0.7.3","esbuild":"0.14.47","typescript":"4.7.4","typedoc":"0.22.17","eslint":"8.18.0"}
2022-06-21 13:20:54 INFO:  Build: {"profile":"production","steps":["clean","compile","typings","typedoc","lint","changelog"]} 2022-07-02 03:34:20 INFO:  Build: {"profile":"production","steps":["clean","compile","typings","typedoc","lint","changelog"]}
2022-06-21 13:20:54 STATE: Clean: {"locations":["dist/*","types/lib/*","typedoc/*"]} 2022-07-02 03:34:20 STATE: Clean: {"locations":["dist/*","types/lib/*","typedoc/*"]}
2022-06-21 13:20:54 STATE: Compile: {"name":"tfjs/nodejs/cpu","format":"cjs","platform":"node","input":"tfjs/tf-node.ts","output":"dist/tfjs.esm.js","files":1,"inputBytes":102,"outputBytes":608} 2022-07-02 03:34:20 STATE: Compile: {"name":"tfjs/nodejs/cpu","format":"cjs","platform":"node","input":"tfjs/tf-node.ts","output":"dist/tfjs.esm.js","files":1,"inputBytes":102,"outputBytes":608}
2022-06-21 13:20:54 STATE: Compile: {"name":"human/nodejs/cpu","format":"cjs","platform":"node","input":"src/human.ts","output":"dist/human.node.js","files":73,"inputBytes":642839,"outputBytes":300711} 2022-07-02 03:34:21 STATE: Compile: {"name":"human/nodejs/cpu","format":"cjs","platform":"node","input":"src/human.ts","output":"dist/human.node.js","files":73,"inputBytes":643891,"outputBytes":301229}
2022-06-21 13:20:54 STATE: Compile: {"name":"tfjs/nodejs/gpu","format":"cjs","platform":"node","input":"tfjs/tf-node-gpu.ts","output":"dist/tfjs.esm.js","files":1,"inputBytes":110,"outputBytes":612} 2022-07-02 03:34:21 STATE: Compile: {"name":"tfjs/nodejs/gpu","format":"cjs","platform":"node","input":"tfjs/tf-node-gpu.ts","output":"dist/tfjs.esm.js","files":1,"inputBytes":110,"outputBytes":612}
2022-06-21 13:20:54 STATE: Compile: {"name":"human/nodejs/gpu","format":"cjs","platform":"node","input":"src/human.ts","output":"dist/human.node-gpu.js","files":73,"inputBytes":642843,"outputBytes":300715} 2022-07-02 03:34:21 STATE: Compile: {"name":"human/nodejs/gpu","format":"cjs","platform":"node","input":"src/human.ts","output":"dist/human.node-gpu.js","files":73,"inputBytes":643895,"outputBytes":301233}
2022-06-21 13:20:54 STATE: Compile: {"name":"tfjs/nodejs/wasm","format":"cjs","platform":"node","input":"tfjs/tf-node-wasm.ts","output":"dist/tfjs.esm.js","files":1,"inputBytes":149,"outputBytes":664} 2022-07-02 03:34:21 STATE: Compile: {"name":"tfjs/nodejs/wasm","format":"cjs","platform":"node","input":"tfjs/tf-node-wasm.ts","output":"dist/tfjs.esm.js","files":1,"inputBytes":149,"outputBytes":664}
2022-06-21 13:20:54 STATE: Compile: {"name":"human/nodejs/wasm","format":"cjs","platform":"node","input":"src/human.ts","output":"dist/human.node-wasm.js","files":73,"inputBytes":642895,"outputBytes":300765} 2022-07-02 03:34:21 STATE: Compile: {"name":"human/nodejs/wasm","format":"cjs","platform":"node","input":"src/human.ts","output":"dist/human.node-wasm.js","files":73,"inputBytes":643947,"outputBytes":301283}
2022-06-21 13:20:54 STATE: Compile: {"name":"tfjs/browser/version","format":"esm","platform":"browser","input":"tfjs/tf-version.ts","output":"dist/tfjs.version.js","files":1,"inputBytes":1069,"outputBytes":371} 2022-07-02 03:34:21 STATE: Compile: {"name":"tfjs/browser/version","format":"esm","platform":"browser","input":"tfjs/tf-version.ts","output":"dist/tfjs.version.js","files":1,"inputBytes":1069,"outputBytes":371}
2022-06-21 13:20:54 STATE: Compile: {"name":"tfjs/browser/esm/nobundle","format":"esm","platform":"browser","input":"tfjs/tf-browser.ts","output":"dist/tfjs.esm.js","files":2,"inputBytes":1045,"outputBytes":596} 2022-07-02 03:34:21 STATE: Compile: {"name":"tfjs/browser/esm/nobundle","format":"esm","platform":"browser","input":"tfjs/tf-browser.ts","output":"dist/tfjs.esm.js","files":2,"inputBytes":1045,"outputBytes":596}
2022-06-21 13:20:54 STATE: Compile: {"name":"human/browser/esm/nobundle","format":"esm","platform":"browser","input":"src/human.ts","output":"dist/human.esm-nobundle.js","files":73,"inputBytes":642827,"outputBytes":299608} 2022-07-02 03:34:21 STATE: Compile: {"name":"human/browser/esm/nobundle","format":"esm","platform":"browser","input":"src/human.ts","output":"dist/human.esm-nobundle.js","files":73,"inputBytes":643879,"outputBytes":300126}
2022-06-21 13:20:55 STATE: Compile: {"name":"tfjs/browser/esm/custom","format":"esm","platform":"browser","input":"tfjs/tf-custom.ts","output":"dist/tfjs.esm.js","files":1,"inputBytes":110,"outputBytes":1353541} 2022-07-02 03:34:21 STATE: Compile: {"name":"tfjs/browser/esm/custom","format":"esm","platform":"browser","input":"tfjs/tf-custom.ts","output":"dist/tfjs.esm.js","files":1,"inputBytes":110,"outputBytes":1353541}
2022-06-21 13:20:55 STATE: Compile: {"name":"human/browser/iife/bundle","format":"iife","platform":"browser","input":"src/human.ts","output":"dist/human.js","files":73,"inputBytes":1995772,"outputBytes":1652210} 2022-07-02 03:34:21 STATE: Compile: {"name":"human/browser/iife/bundle","format":"iife","platform":"browser","input":"src/human.ts","output":"dist/human.js","files":73,"inputBytes":1996824,"outputBytes":1652733}
2022-06-21 13:20:55 STATE: Compile: {"name":"human/browser/esm/bundle","format":"esm","platform":"browser","input":"src/human.ts","output":"dist/human.esm.js","files":73,"inputBytes":1995772,"outputBytes":2139073} 2022-07-02 03:34:21 STATE: Compile: {"name":"human/browser/esm/bundle","format":"esm","platform":"browser","input":"src/human.ts","output":"dist/human.esm.js","files":73,"inputBytes":1996824,"outputBytes":2140101}
2022-06-21 13:21:07 STATE: Typings: {"input":"src/human.ts","output":"types/lib","files":116} 2022-07-02 03:34:36 STATE: Typings: {"input":"src/human.ts","output":"types/lib","files":116}
2022-06-21 13:21:13 STATE: TypeDoc: {"input":"src/human.ts","output":"typedoc","objects":73,"generated":true} 2022-07-02 03:34:44 STATE: TypeDoc: {"input":"src/human.ts","output":"typedoc","objects":73,"generated":true}
2022-06-21 13:21:13 STATE: Compile: {"name":"demo/typescript","format":"esm","platform":"browser","input":"demo/typescript/index.ts","output":"demo/typescript/index.js","files":1,"inputBytes":6326,"outputBytes":3070} 2022-07-02 03:34:44 STATE: Compile: {"name":"demo/typescript","format":"esm","platform":"browser","input":"demo/typescript/index.ts","output":"demo/typescript/index.js","files":1,"inputBytes":6324,"outputBytes":3070}
2022-06-21 13:21:13 STATE: Compile: {"name":"demo/faceid","format":"esm","platform":"browser","input":"demo/faceid/index.ts","output":"demo/faceid/index.js","files":2,"inputBytes":15174,"outputBytes":7833} 2022-07-02 03:34:44 STATE: Compile: {"name":"demo/faceid","format":"esm","platform":"browser","input":"demo/faceid/index.ts","output":"demo/faceid/index.js","files":2,"inputBytes":15174,"outputBytes":7833}
2022-06-21 13:22:08 STATE: Lint: {"locations":["*.json","src/**/*.ts","test/**/*.js","demo/**/*.js"],"files":106,"errors":0,"warnings":0} 2022-07-02 03:35:04 STATE: Lint: {"locations":["*.json","src/**/*.ts","test/**/*.js","demo/**/*.js"],"files":106,"errors":0,"warnings":0}
2022-06-21 13:22:08 STATE: ChangeLog: {"repository":"https://github.com/vladmandic/human","branch":"main","output":"CHANGELOG.md"} 2022-07-02 03:35:05 STATE: ChangeLog: {"repository":"https://github.com/vladmandic/human","branch":"main","output":"CHANGELOG.md"}
2022-06-21 13:22:08 INFO:  Done... 2022-07-02 03:35:05 INFO:  Done...

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

15
types/human.d.ts vendored
View File

@ -808,6 +808,12 @@ declare function getModelArtifactsForJSON(modelJSON: ModelJSON, loadWeights: (we
*/ */
declare function getModelArtifactsInfoForJSON(modelArtifacts: ModelArtifacts): ModelArtifactsInfo; declare function getModelArtifactsInfoForJSON(modelArtifacts: ModelArtifacts): ModelArtifactsInfo;
declare const getModelStats: () => {
sizeManifest: number;
sizeWeights: number;
numModels: number;
};
declare const getSaveHandlers: (url: string | string[]) => IOHandler[]; declare const getSaveHandlers: (url: string | string[]) => IOHandler[];
declare interface GPUData { declare interface GPUData {
@ -1302,6 +1308,12 @@ declare class Human {
* @returns result - {@link Result} * @returns result - {@link Result}
*/ */
next(result?: Result): Result; next(result?: Result): Result;
/** get model loading/loaded stats */
getModelStats: () => {
sizeManifest: number;
sizeWeights: number;
numModels: number;
};
/** Warmup method pre-initializes all configured models for faster inference /** Warmup method pre-initializes all configured models for faster inference
* - can take significant time on startup * - can take significant time on startup
* - only used for `webgl` and `humangl` backends * - only used for `webgl` and `humangl` backends
@ -1830,7 +1842,8 @@ declare namespace models {
reset, reset,
load, load,
validate, validate,
Models Models,
getModelStats
} }
} }
export { models } export { models }