Skip to content

Commit

Permalink
New models UI (cvat-ai#5635)
Browse files Browse the repository at this point in the history
  • Loading branch information
klakhov authored Jan 30, 2023
1 parent 91b36ce commit 3775bc2
Show file tree
Hide file tree
Showing 41 changed files with 1,748 additions and 303 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Windows Installation Instructions adjusted to work around <https://github.com/nuclio/nuclio/issues/1821>
- The contour detection function for semantic segmentation (<https://github.com/opencv/cvat/pull/4665>)
- Delete newline character when generating a webhook signature (<https://github.com/opencv/cvat/pull/5622>)
- DL models UI (<https://github.com/opencv/cvat/pull/5635>)

### Deprecated
- TDB
Expand Down
2 changes: 1 addition & 1 deletion cvat-core/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "cvat-core",
"version": "8.0.0",
"version": "8.1.0",
"description": "Part of Computer Vision Tool which presents an interface for client-side integration",
"main": "src/api.ts",
"scripts": {
Expand Down
3 changes: 2 additions & 1 deletion cvat-core/src/api-implementation.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Copyright (C) 2019-2022 Intel Corporation
// Copyright (C) 2022 CVAT.ai Corporation
// Copyright (C) 2022-2023 CVAT.ai Corporation
//
// SPDX-License-Identifier: MIT

Expand Down Expand Up @@ -37,6 +37,7 @@ export default function implementAPI(cvat) {
cvat.lambda.cancel.implementation = lambdaManager.cancel.bind(lambdaManager);
cvat.lambda.listen.implementation = lambdaManager.listen.bind(lambdaManager);
cvat.lambda.requests.implementation = lambdaManager.requests.bind(lambdaManager);
cvat.lambda.providers.implementation = lambdaManager.providers.bind(lambdaManager);

cvat.server.about.implementation = async () => {
const result = await serverProxy.server.about();
Expand Down
12 changes: 8 additions & 4 deletions cvat-core/src/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -190,18 +190,22 @@ function build() {
const result = await PluginRegistry.apiWrapper(cvat.lambda.call, task, model, args);
return result;
},
async cancel(requestID) {
const result = await PluginRegistry.apiWrapper(cvat.lambda.cancel, requestID);
async cancel(requestID, functionID) {
const result = await PluginRegistry.apiWrapper(cvat.lambda.cancel, requestID, functionID);
return result;
},
async listen(requestID, onChange) {
const result = await PluginRegistry.apiWrapper(cvat.lambda.listen, requestID, onChange);
async listen(requestID, functionID, onChange) {
const result = await PluginRegistry.apiWrapper(cvat.lambda.listen, requestID, functionID, onChange);
return result;
},
async requests() {
const result = await PluginRegistry.apiWrapper(cvat.lambda.requests);
return result;
},
async providers() {
const result = await PluginRegistry.apiWrapper(cvat.lambda.providers);
return result;
},
},
logger: loggerStorage,
config: {
Expand Down
17 changes: 15 additions & 2 deletions cvat-core/src/enums.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Copyright (C) 2019-2022 Intel Corporation
// Copyright (C) 2022 CVAT.ai Corporation
// Copyright (C) 2022-2023 CVAT.ai Corporation
//
// SPDX-License-Identifier = MIT

Expand Down Expand Up @@ -132,10 +132,23 @@ export enum HistoryActions {
RESTORED_FRAME = 'Restored frame',
}

export enum ModelType {
export enum ModelKind {
DETECTOR = 'detector',
INTERACTOR = 'interactor',
TRACKER = 'tracker',
CLASSIFIER = 'classifier',
REID = 'reid',
}

export enum ModelProviders {
CVAT = 'cvat',
}

export enum ModelReturnType {
RECTANGLE = 'rectangle',
TAG = 'tag',
POLYGON = 'polygon',
MASK = 'mask',
}

export const colors = [
Expand Down
69 changes: 55 additions & 14 deletions cvat-core/src/lambda-manager.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,25 @@
// Copyright (C) 2019-2022 Intel Corporation
// Copyright (C) 2022 CVAT.ai Corporation
// Copyright (C) 2022-2023 CVAT.ai Corporation
//
// SPDX-License-Identifier: MIT

import serverProxy from './server-proxy';
import { ArgumentError } from './exceptions';
import MLModel from './ml-model';
import { RQStatus } from './enums';
import { ModelProviders, RQStatus } from './enums';

export interface ModelProvider {
name: string;
icon: string;
attributes: Record<string, string>;
}

interface ModelProxy {
run: (body: any) => Promise<any>;
call: (modelID: string | number, body: any) => Promise<any>;
status: (requestID: string) => Promise<any>;
cancel: (requestID: string) => Promise<any>;
}

class LambdaManager {
private listening: any;
Expand All @@ -18,18 +31,16 @@ class LambdaManager {
}

async list(): Promise<MLModel[]> {
if (Array.isArray(this.cachedList)) {
return [...this.cachedList];
}
const lambdaFunctions = await serverProxy.lambda.list();
const functions = await serverProxy.functions.list();

const result = await serverProxy.lambda.list();
const result = [...lambdaFunctions, ...functions];
const models = [];

for (const model of result) {
models.push(
new MLModel({
...model,
type: model.kind,
}),
);
}
Expand Down Expand Up @@ -59,7 +70,7 @@ class LambdaManager {
function: model.id,
};

const result = await serverProxy.lambda.run(body);
const result = await LambdaManager.getModelProxy(model).run(body);
return result.id;
}

Expand All @@ -73,32 +84,43 @@ class LambdaManager {
task: taskID,
};

const result = await serverProxy.lambda.call(model.id, body);
const result = await LambdaManager.getModelProxy(model).call(model.id, body);
return result;
}

async requests() {
const result = await serverProxy.lambda.requests();
const lambdaRequests = await serverProxy.lambda.requests();
const functionsRequests = await serverProxy.functions.requests();
const result = [...lambdaRequests, ...functionsRequests];
return result.filter((request) => ['queued', 'started'].includes(request.status));
}

async cancel(requestID): Promise<void> {
async cancel(requestID, functionID): Promise<void> {
if (typeof requestID !== 'string') {
throw new ArgumentError(`Request id argument is required to be a string. But got ${requestID}`);
}
const model = this.cachedList.find((_model) => _model.id === functionID);
if (!model) {
throw new ArgumentError('Incorrect Function Id provided');
}

if (this.listening[requestID]) {
clearTimeout(this.listening[requestID].timeout);
delete this.listening[requestID];
}
await serverProxy.lambda.cancel(requestID);

await LambdaManager.getModelProxy(model).cancel(requestID);
}

async listen(requestID, onUpdate): Promise<void> {
async listen(requestID, functionID, onUpdate): Promise<void> {
const model = this.cachedList.find((_model) => _model.id === functionID);
if (!model) {
throw new ArgumentError('Incorrect Function Id provided');
}
const timeoutCallback = async (): Promise<void> => {
try {
this.listening[requestID].timeout = null;
const response = await serverProxy.lambda.status(requestID);
const response = await LambdaManager.getModelProxy(model).status(requestID);

if (response.status === RQStatus.QUEUED || response.status === RQStatus.STARTED) {
onUpdate(response.status, response.progress || 0);
Expand All @@ -123,9 +145,28 @@ class LambdaManager {

this.listening[requestID] = {
onUpdate,
functionID,
timeout: setTimeout(timeoutCallback, 2000),
};
}

async providers(): Promise<ModelProvider[]> {
const providersData: Record<string, Record<string, string>> = await serverProxy.functions.providers();
const providers = Object.entries(providersData).map(([provider, attributes]) => {
const { icon } = attributes;
delete attributes.icon;
return {
name: provider,
icon,
attributes,
};
});
return providers;
}

private static getModelProxy(model: MLModel): ModelProxy {
return model.provider === ModelProviders.CVAT ? serverProxy.lambda : serverProxy.functions;
}
}

export default new LambdaManager();
Loading

0 comments on commit 3775bc2

Please sign in to comment.