Skip to content

Commit

Permalink
Merge pull request #1 from mlops-club/feat/sidebar
Browse files Browse the repository at this point in the history
Feat/sidebar
  • Loading branch information
shilongjaycui committed Mar 9, 2024
2 parents a9547b0 + 3cc08aa commit 5f45c93
Show file tree
Hide file tree
Showing 14 changed files with 387 additions and 113 deletions.
37 changes: 37 additions & 0 deletions bentoml-playground-workspace/linear_regression/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# BentoML Sklearn Example: Linear Regression

0. Install dependencies:

```bash
pip install -r ./requirements.txt
```

1. Train a linear regression model

```bash
python ./train.py
```

2. Run the service:

```bash
bentoml serve service.py:svc
```

3. Send test request

```
curl -X POST -H "content-type: application/json" --data "[[5, 3]]" http://127.0.0.1:3000/predict
```

4. Build Bento

```
bentoml build
```

5. Build docker image

```
bentoml containerize linear_regression:latest
```
5 changes: 5 additions & 0 deletions bentoml-playground-workspace/linear_regression/bentofile.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
service: "service.py:svc"
include:
- "service.py"
python:
requirements_txt: "./requirements.txt"
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
bentoml>=1.0.0
scikit-learn
13 changes: 13 additions & 0 deletions bentoml-playground-workspace/linear_regression/service.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import bentoml
from bentoml.io import NumpyNdarray

reg_runner = bentoml.sklearn.get("linear_reg:latest").to_runner()

svc = bentoml.Service("linear_regression", runners=[reg_runner])

input_spec = NumpyNdarray(dtype="int", shape=(-1, 2))


@svc.api(input=input_spec, output=NumpyNdarray())
async def predict(input_arr):
return await reg_runner.predict.async_run(input_arr)
16 changes: 16 additions & 0 deletions bentoml-playground-workspace/linear_regression/train.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from sklearn import linear_model

import bentoml

if __name__ == "__main__":
reg = linear_model.LinearRegression()
reg.fit([[0, 0], [1, 1], [2, 2]], [0, 1, 2])

print("coef: ", reg.coef_)
bento_model = bentoml.sklearn.save_model("linear_reg", reg)
print(f"Model saved: {bento_model}")

# Test running inference with BentoML runner
test_runner = bentoml.sklearn.get("linear_reg:latest").to_runner()
test_runner.init_local()
assert test_runner.predict.run([[1, 1]]) == reg.predict([[1, 1]])
8 changes: 4 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

70 changes: 52 additions & 18 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,17 +60,21 @@
"viewsContainers": {
"activitybar": [
{
"id": "models-explorer-view-container",
"title": "BentoML",
"id": "bentoml-explorer",
"title": "BentoML Explorer",
"icon": "src/resources/bentoml-logo.svg"
}
]
},
"views": {
"models-explorer-view-container": [
"bentoml-explorer": [
{
"id": "bentoml-models-tree-view",
"id": "bentoml-models",
"name": "Models"
},
{
"id": "bentoml-bentos",
"name": "Bentos"
}
]
},
Expand All @@ -80,47 +84,77 @@
"title": "BentoML: Install Python Dependencies"
},
{
"command": "bentoml.refreshEntry",
"command": "bentoml.refreshModelEntry",
"title": "BentoML: Refresh models",
"icon": "$(refresh)"
},
{
"command": "bentoml.openInBrowser",
"title": "View in browser",
"command": "bentoml.refreshBentoEntry",
"title": "BentoML: Refresh Bentos",
"icon": "$(refresh)"
},
{
"command": "bentoml.openModelInBrowser",
"title": "View model in browser",
"icon": "$(link-external)"
},
{
"command": "bentoml.attachToSession",
"title": "Attach to session",
"icon": "$(debug-start)"
"command": "bentoml.openBentoInBrowser",
"title": "View Bento in browser",
"icon": "$(link-external)"
},
{
"command": "bentoml.deleteModel",
"title": "Delete BentoML Model",
"icon": "$(remove)"
},
{
"command": "bentoml.deleteBento",
"title": "Delete BentoML Bento",
"icon": "$(remove)"
},
{
"command": "bentoml.copyValueToClipboard",
"title": "Copy to clipboard"
"title": "Copy value to clipboard"
}
],
"menus": {
"view/title": [
{
"command": "bentoml.refreshEntry",
"when": "view == bentoml-models-tree-view",
"command": "bentoml.refreshModelEntry",
"when": "view == bentoml-models",
"group": "navigation"
},
{
"command": "bentoml.refreshBentoEntry",
"when": "view == bentoml-bentos",
"group": "navigation"
}
],
"view/item/context": [
{
"command": "bentoml.openInBrowser",
"when": "view == bentoml-models-tree-view && viewItem == top-level-clearml-session-tree-item",
"command": "bentoml.openModelInBrowser",
"when": "view == bentoml-models && viewItem == top-level-bentoml-model-tree-item",
"group": "inline"
},
{
"command": "bentoml.openBentoInBrowser",
"when": "view == bentoml-bentos && viewItem == top-level-bentoml-bento-tree-item",
"group": "inline"
},
{
"command": "bentoml.deleteModel",
"when": "view == bentoml-models && viewItem == top-level-bentoml-model-tree-item",
"group": "inline"
},
{
"command": "bentoml.attachToSession",
"when": "view == bentoml-models-tree-view && viewItem == top-level-clearml-session-tree-item",
"command": "bentoml.deleteBento",
"when": "view == bentoml-bentos && viewItem == top-level-bentoml-bento-tree-item",
"group": "inline"
},
{
"command": "bentoml.copyValueToClipboard",
"when": "view == bentoml-models-tree-view && viewItem == clearml-session-detail-tree-item",
"when": "view == bentoml-models && viewItem == top-level-bentoml-model-tree-item",
"group": "inline"
}
]
Expand Down
Empty file added src/common/bentoml/bentos.ts
Empty file.
33 changes: 33 additions & 0 deletions src/common/bentoml/cli-client.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import * as vscode from 'vscode';
import { Model, SimpleModel, Bento } from './models';
import { runShellCommand } from '../shell';
import { getPathToActivePythonInterpreter, promptIfPythonInterpreterIsNotConfigured } from '../python';


export async function getModels() {
const interpreterFpath = (await getPathToActivePythonInterpreter()) as string;
const response = await runShellCommand(interpreterFpath, ["-m","bentoml", "models", "list", "--output", "json"]);
console.log(`getModels() response: ${response.logs}`);
return JSON.parse(response.logs) as SimpleModel[];
}

export async function getBentos() {
const interpreterFpath = (await getPathToActivePythonInterpreter()) as string;
const response = await runShellCommand(interpreterFpath, ["-m","bentoml", "list", "--output", "json"]);
console.log(`getBentos() response: ${response.logs}`);
return JSON.parse(response.logs) as Bento[];
}

export async function deleteModel(object: SimpleModel){
const interpreterFpath = (await getPathToActivePythonInterpreter()) as string;
const response = await runShellCommand(interpreterFpath, ["-m","bentoml", "models","delete", object.tag, "-y"]);
console.log(response.logs);
return response.logs;
}

export async function deleteBento(object: Bento){
const interpreterFpath = (await getPathToActivePythonInterpreter()) as string;
const response = await runShellCommand(interpreterFpath, ["-m","bentoml", "delete", object.tag, "-y"]);
console.log(response.logs);
return response.logs;
}
102 changes: 59 additions & 43 deletions src/common/bentoml/models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,47 +83,63 @@ export interface IDObject {
export interface HyperParams {
[section: string]: Record<string, HyperParamValue>;
}

export interface Model {
id: string;
company: Company;
user: User;

export interface ModelSignatureDict {
batchable?: boolean; // Optional flag for batchability
batch_dim?: number | [number, number]; // Optional batch dimensions
input_spec?: any | any[]; // Optional input specification (flexible typing)
output_spec?: any; // Optional output specification (flexible typing)
}

//batchable: bool
//batch_dim: t.Union[t.Tuple[int, int], int]
//input_spec: t.Optional[t.Union[t.Tuple[AnyType], AnyType]]
//output_spec: t.Optional[AnyType]

// create function in bentoml cli
// cls,
//name: Tag | str,
//module: str,
//api_version: str,
//signatures: ModelSignaturesType,
//labels: dict[str, str] | None = None,
//options: ModelOptions | None = None,
//custom_objects: dict[str, t.Any] | None = None,
//metadata: dict[str, t.Any] | None = None,
//context: ModelContext,


// https://github.com/bentoml/BentoML/blob/064e08759fc4f52ed46ec249208d802031186ac6/src/bentoml/_internal/models/model.py#L183

export interface ModelInfo {
tag: string;
module: string;
api_version: string;
signatures: string;
labels: any[];
options: any[];
metadata: string;
context: string;
creation_time: string; }

export interface Model {
name: string;
type: string;
status: string;
status_reason: string;
status_message: string;
status_changed: string;
comment: string;
report_assets: any[];
created: string;
started: string;
active_duration: number;
project: Project;
input: Input;
output: Record<string, any>;
execution: Execution;
tags: any[];
system_tags: string[];
script: Script;
last_worker: string;
last_worker_report: string;
last_update: string;
last_change: string;
last_iteration: number;
last_metrics: LastMetrics;
metric_stats: Record<string, MetricStats>;
hyperparams: HyperParams;
configuration: Record<string, any>;
runtime: Record<string, any>;
//models: {
// input: any[];
// output: any[];
//};
container: {
image: string;
arguments: string;
setup_shell_script: string;
};
last_changed_by: string;
}
model_fs: string;
model_info: ModelInfo;
custom_objects: string;
_internal: boolean;
}

export interface SimpleModel {
tag: string;
module: string;
size: string;
creation_time: string;
}

export interface Bento {
tag: string;
size: string;
model_size: string;
creation_time: string;
}
4 changes: 2 additions & 2 deletions src/common/shell.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ import { traceError, traceInfo } from './logging';
export async function runShellCommand(
cmd: string,
args: string[],
logFn: (msg: string) => void,
errorLogFn: (msg: string) => void
logFn: (msg: string) => void = traceInfo,
errorLogFn: (msg: string) => void = traceError,
): Promise<{ logs: string; exitCode: number }> {
const process = spawn(cmd, args);
let logs = '';
Expand Down

0 comments on commit 5f45c93

Please sign in to comment.