Skip to content

Commit f7abb3c

Browse files
committed
Merge remote-tracking branch 'community/main' into odh modelmesh
Signed-off-by: Spolti <[email protected]>
2 parents 21a8cb1 + a997686 commit f7abb3c

24 files changed

+705
-99
lines changed

.github/workflows/codeql.yml

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
# For most projects, this workflow file will not need changing; you simply need
2+
# to commit it to your repository.
3+
#
4+
# You may wish to alter this file to override the set of languages analyzed,
5+
# or to provide custom queries or build logic.
6+
#
7+
# ******** NOTE ********
8+
# We have attempted to detect the languages in your repository. Please check
9+
# the `language` matrix defined below to confirm you have the correct set of
10+
# supported CodeQL languages.
11+
#
12+
name: "CodeQL"
13+
14+
on:
15+
push:
16+
branches: ["main"]
17+
pull_request:
18+
# The branches below must be a subset of the branches above
19+
branches: ["main"]
20+
schedule:
21+
- cron: '45 8 * * *'
22+
23+
jobs:
24+
analyze:
25+
name: Analyze
26+
# Runner size impacts CodeQL analysis time. To learn more, please see:
27+
# - https://gh.io/recommended-hardware-resources-for-running-codeql
28+
# - https://gh.io/supported-runners-and-hardware-resources
29+
# - https://gh.io/using-larger-runners
30+
# Consider using larger runners for possible analysis time improvements.
31+
runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' }}
32+
timeout-minutes: ${{ (matrix.language == 'swift' && 120) || 360 }}
33+
permissions:
34+
actions: read
35+
contents: read
36+
security-events: write
37+
38+
strategy:
39+
fail-fast: false
40+
matrix:
41+
language: ["java-kotlin", "python"]
42+
# CodeQL supports [ 'c-cpp', 'csharp', 'go', 'java-kotlin', 'javascript-typescript', 'python', 'ruby', 'swift' ]
43+
# Use only 'java-kotlin' to analyze code written in Java, Kotlin or both
44+
# Use only 'javascript-typescript' to analyze code written in JavaScript, TypeScript or both
45+
# Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
46+
47+
steps:
48+
- name: Checkout repository
49+
uses: actions/checkout@v3
50+
51+
- name: Set up Java 17
52+
uses: actions/setup-java@v3
53+
with:
54+
java-version: '17'
55+
distribution: 'temurin'
56+
57+
# Initializes the CodeQL tools for scanning.
58+
- name: Initialize CodeQL
59+
uses: github/codeql-action/init@v2
60+
with:
61+
languages: ${{ matrix.language }}
62+
# If you wish to specify custom queries, you can do so here or in a config file.
63+
# By default, queries listed here will override any specified in a config file.
64+
# Prefix the list here with "+" to use these queries and those in the config file.
65+
66+
# For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
67+
# queries: security-extended,security-and-quality
68+
69+
# Autobuild attempts to build any compiled languages (C/C++, C#, Go, Java, or Swift).
70+
# If this step fails, then you should remove it and run the build manually (see below)
71+
- name: Autobuild
72+
uses: github/codeql-action/autobuild@v2
73+
74+
# ℹ️ Command-line programs to run using the OS shell.
75+
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
76+
77+
# If the Autobuild fails above, remove it and uncomment the following three lines.
78+
# modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.
79+
80+
# - run: |
81+
# echo "Run, Build Application using script"
82+
# ./location_of_script_within_repo/buildscript.sh
83+
84+
- name: Perform CodeQL Analysis
85+
uses: github/codeql-action/analyze@v2
86+
with:
87+
category: "/language:${{matrix.language}}"

CONTRIBUTING.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@
33
We'd love to accept your patches and contributions to this project. There are
44
just a few small guidelines you need to follow.
55

6+
## Developer guide
7+
8+
Check out the [developer guide](developer-guide.md) to learn about development practices for the project.
9+
610
## Code reviews
711

812
All submissions, including submissions by project members, require review. We

README.md

Lines changed: 7 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,17 @@
1+
[![Build](https://github.com/kserve/modelmesh/actions/workflows/build.yml/badge.svg?branch=main)](https://github.com/kserve/modelmesh/actions/workflows/build.yml)
2+
13
# ModelMesh
24

35
The ModelMesh framework is a mature, general-purpose model serving management/routing layer designed for high-scale, high-density and frequently-changing model use cases. It works with existing or custom-built model servers and acts as a distributed LRU cache for serving runtime models.
46

5-
See these [these charts](https://github.com/kserve/modelmesh/files/8854091/modelmesh-jun2022.pdf) for more information on supported features and design details.
6-
77
For full Kubernetes-based deployment and management of ModelMesh clusters and models, see the [ModelMesh Serving](https://github.com/kserve/modelmesh-serving) repo. This includes a separate controller and provides K8s custom resource based management of ServingRuntimes and InferenceServices along with common, abstracted handling of model repository storage and ready-to-use integrations with some existing OSS model servers.
88

9-
### Quick-Start
10-
11-
1. Wrap your model-loading and invocation logic in this [model-runtime.proto](./src/main/proto/current/model-runtime.proto) gRPC service interface
12-
- `runtimeStatus()` - called only during startup to obtain some basic configuration parameters from the runtime, such as version, capacity, model-loading timeout
13-
- `loadModel()` - load the specified model into memory from backing storage, returning when complete
14-
- `modelSize()` - determine size (mem usage) of previously-loaded model. If very fast, can be omitted and provided instead in the response from `loadModel`
15-
- `unloadModel()` - unload previously loaded model, returning when complete
16-
- Use a separate, arbitrary gRPC service interface for model inferencing requests. It can have any number of methods and they are assumed to be idempotent. See [predictor.proto](src/test/proto/predictor.proto) for a very simple example.
17-
- The methods of your custom applier interface will be called only for already fully-loaded models.
18-
2. Build a grpc server docker container which exposes these interfaces on localhost port 8085 or via a mounted unix domain socket
19-
3. Extend the [Kustomize-based Kubernetes manifests](config) to use your docker image, and with appropriate mem and cpu resource allocations for your container
20-
4. Deploy to a Kubernetes cluster as a regular Service, which will expose [this grpc service interface](./src/main/proto/current/model-mesh.proto) via kube-dns (you do not implement this yourself), consume using grpc client of your choice from your upstream service components
21-
- `registerModel()` and `unregisterModel()` for registering/removing models managed by the cluster
22-
- Any custom inferencing interface methods to make a runtime invocation of previously-registered model, making sure to set a `mm-model-id` or `mm-vmodel-id` metadata header (or `-bin` suffix equivalents for UTF-8 ids)
23-
24-
### Deployment and Upgrades
25-
26-
Prerequisites:
27-
28-
- An etcd cluster (shared or otherwise)
29-
- A Kubernetes namespace with the etcd cluster connection details configured as a secret key in [this json format](https://github.com/IBM/etcd-java/blob/master/etcd-json-schema.md)
30-
- Note that if provided, the `root_prefix` attribute _is_ used as a key prefix for all of the framework's use of etcd
31-
32-
From an operational standpoint, ModelMesh behaves just like any other homogeneous clustered microservice. This means it can be deployed, scaled, migrated and upgraded as a regular Kubernetes deployment without any special coordination needed, and without any impact to live service usage.
33-
34-
In particular the procedure for live upgrading either the framework container or service runtime container is the same: change the image version in the deployment config yaml and then update it `kubectl apply -f model-mesh-deploy.yaml`
9+
For more information on supported features and design details, see [these charts](https://github.com/kserve/modelmesh/files/8854091/modelmesh-jun2022.pdf).
3510

36-
### Build
11+
## Get Started
3712

38-
Sample build:
13+
To learn more about and get started with the ModelMesh framework, check out [the documentation](/docs).
3914

40-
```bash
41-
GIT_COMMIT=$(git rev-parse HEAD)
42-
BUILD_ID=$(date '+%Y%m%d')-$(git rev-parse HEAD | cut -c -5)
43-
IMAGE_TAG_VERSION="dev"
44-
IMAGE_TAG=${IMAGE_TAG_VERSION}-$(git branch --show-current)_${BUILD_ID}
15+
## Developer guide
4516

46-
docker build -t modelmesh:${IMAGE_TAG} \
47-
--build-arg imageVersion=${IMAGE_TAG} \
48-
--build-arg buildId=${BUILD_ID} \
49-
--build-arg commitSha=${GIT_COMMIT} .
50-
```
17+
Use the [developer guide](developer-guide.md) to learn about development practices for the project.

developer-guide.md

Lines changed: 220 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,220 @@
1+
# Developer Guide
2+
3+
## Prerequisites
4+
5+
You need [Java](https://openjdk.org/) and [Maven](https://maven.apache.org/guides/getting-started/maven-in-five-minutes.html#running-maven-tools)
6+
to build ModelMesh from source and [`etcd`](https://etcd.io/) to run the unit tests.
7+
To build your custom `modelmesh` container image and deploy it to a ModelMesh Serving installation on a Kubernetes cluster,
8+
you need the [`docker`](https://docs.docker.com/engine/reference/commandline/cli/) and
9+
[`kubectl`](https://kubectl.docs.kubernetes.io/references/kubectl/) CLIs.
10+
On `macOS` you can install the required CLIs with [Homebrew](https://brew.sh/):
11+
12+
- Java: `brew install java`
13+
- Maven: `brew install maven`
14+
- Etcd: `brew install etcd`
15+
- Docker: `brew install docker`
16+
- Kubectl: `brew install kubectl`
17+
18+
## Generating sources
19+
20+
The gRPC stubs like the `ModelMeshGrpc` class have to be generated by the gRPC proto compiler from
21+
the `.proto` source files under `src/main/proto`.
22+
The generated sources should be created in the target directory `target/generated-sources/protobuf/grpc-java`.
23+
24+
To generate the sources run either of the following commands:
25+
26+
```shell
27+
mvn package -DskipTests
28+
mvn install -DskipTests
29+
```
30+
31+
## Project setup using an IDE
32+
33+
If you are using an IDE like [IntelliJ IDEA](https://www.jetbrains.com/idea/) or [Eclipse](https://eclipseide.org/)
34+
to help with your code development you should set up source and target folders so that the IDE's compiler can find all
35+
the source code including the generated sources (after running `mvn install -DskipTests`).
36+
37+
For IntelliJ this can be done by going to **File > Project Structure ... > Modules**:
38+
39+
- **Source Folders**
40+
- src/main/java
41+
- src/main/proto
42+
- target/generated-sources/protobuf/grpc-java (generated)
43+
- target/generated-sources/protobuf/java (generated)
44+
- **Test Source Folders**
45+
- src/test/java
46+
- target/generated-test-sources/protobuf/grpc-java (generated)
47+
- target/generated-test-sources/protobuf/java (generated)
48+
- **Resource Folders**
49+
- src/main/resources
50+
- **Test Resource Folders**
51+
- src/test/resources
52+
- **Excluded Folders**
53+
- target
54+
55+
You may also want to increase your Java Heap size to at least 1.5 GB.
56+
57+
## Testing code changes
58+
59+
**Note**, before running the test cases, make sure you have `etcd` installed (see #prerequisites):
60+
61+
```Bash
62+
$ etcd --version
63+
64+
etcd Version: 3.5.5
65+
Git SHA: 19002cfc6
66+
Go Version: go1.19.1
67+
Go OS/Arch: darwin/amd64
68+
```
69+
70+
You can either run all test suites at once. You can use the `-q` flag to reduce noise:
71+
72+
```Bash
73+
mvn test -q
74+
```
75+
76+
Or you can run individual test cases:
77+
78+
```Bash
79+
mvn test -Dtest=ModelMeshErrorPropagationTest
80+
mvn test -Dtest=SidecarModelMeshTest,ModelMeshFailureExpiryTest
81+
```
82+
83+
It can be handy to use `grep` to reduce output noise:
84+
85+
```Bash
86+
mvn test -Dtest=SidecarModelMeshTest,ModelMeshFailureExpiryTest | \
87+
grep -E " Running |\[ERROR\]|Failures|SUCCESS|Skipp|Total time|Finished"
88+
89+
[INFO] Running com.ibm.watson.modelmesh.ModelMeshFailureExpiryTest
90+
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 10.257 s - in com.ibm.watson.modelmesh.ModelMeshFailureExpiryTest
91+
[INFO] Running com.ibm.watson.modelmesh.SidecarModelMeshTest
92+
[INFO] Tests run: 3, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 17.302 s - in com.ibm.watson.modelmesh.SidecarModelMeshTest
93+
[INFO] Tests run: 4, Failures: 0, Errors: 0, Skipped: 0
94+
[INFO] BUILD SUCCESS
95+
[INFO] Total time: 39.916 s
96+
[INFO] Finished at: 2022-11-01T14:33:33-07:00
97+
```
98+
99+
## Building the container image
100+
101+
After testing your code changes locally, it's time to build a new `modelmesh` container image. Replace the value of the
102+
`DOCKER_USER` environment variable to your DockerHub user ID and change the `IMAGE_TAG` to something meaningful.
103+
104+
```bash
105+
export DOCKER_USER="<your-docker-userid>"
106+
export IMAGE_NAME="${DOCKER_USER}/modelmesh"
107+
export IMAGE_TAG="dev"
108+
export GIT_COMMIT=$(git rev-parse HEAD)
109+
export BUILD_ID=$(date '+%Y%m%d')-$(git rev-parse HEAD | cut -c -5)
110+
111+
docker build -t ${IMAGE_NAME}:${IMAGE_TAG} \
112+
--build-arg imageVersion=${IMAGE_TAG} \
113+
--build-arg buildId=${BUILD_ID} \
114+
--build-arg commitSha=${GIT_COMMIT} .
115+
116+
docker push ${IMAGE_NAME}:${IMAGE_TAG}
117+
```
118+
119+
## Updating the ModelMesh Serving deployment
120+
121+
In order to test the code changes in an existing [ModelMesh Serving](https://github.com/kserve/modelmesh-serving) deployment,
122+
the newly built container image needs to be added to the `model-serving-config` ConfigMap.
123+
124+
First, check if your ModelMesh Serving deployment already has an existing `model-serving-config` ConfigMap:
125+
126+
```Shell
127+
kubectl get configmap
128+
129+
NAME DATA AGE
130+
kube-root-ca.crt 1 4d2h
131+
model-serving-config 1 4m14s
132+
model-serving-config-defaults 1 4d2h
133+
tc-config 2 4d2h
134+
```
135+
136+
If the ConfigMap list contains `model-serving-config`, save the contents of your existing configuration
137+
in a local temp file:
138+
139+
```Bash
140+
mkdir -p temp
141+
kubectl get configmap model-serving-config -o yaml > temp/model-serving-config.yaml
142+
```
143+
144+
And add the `modelMeshImage` property to the `config.yaml` string property:
145+
```YAML
146+
modelMeshImage:
147+
name: <your-docker-userid>/modelmesh
148+
tag: dev
149+
```
150+
151+
Replace the `<your-docker-userid>` placeholder with your Docker username/login.
152+
153+
The complete ConfigMap YAML file might look like this:
154+
155+
```YAML
156+
apiVersion: v1
157+
kind: ConfigMap
158+
metadata:
159+
name: model-serving-config
160+
namespace: modelmesh-serving
161+
data:
162+
config.yaml: |
163+
podsPerRuntime: 1
164+
restProxy:
165+
enabled: true
166+
scaleToZero:
167+
enabled: false
168+
gracePeriodSeconds: 5
169+
modelMeshImage:
170+
name: <your-docker-userid>/modelmesh
171+
tag: dev
172+
```
173+
174+
Apply the ConfigMap to your cluster:
175+
176+
```Bash
177+
kubectl apply -f temp/model-serving-config.yaml
178+
```
179+
180+
If you are comfortable using vi, you can forgo creating a temp file and edit the ConfigMap directly in the terminal:
181+
182+
```Shell
183+
kubectl edit configmap model-serving-config
184+
```
185+
186+
If you did not already have a `model-serving-config` ConfigMap on your cluster, you can create one like this:
187+
188+
```shell
189+
# export DOCKER_USER="<your-docker-userid>"
190+
# export IMAGE_NAME="${DOCKER_USER}/modelmesh"
191+
# export IMAGE_TAG="dev"
192+
193+
kubectl apply -f - <<EOF
194+
---
195+
apiVersion: v1
196+
kind: ConfigMap
197+
metadata:
198+
name: model-serving-config
199+
data:
200+
config.yaml: |
201+
modelMeshImage:
202+
name: ${IMAGE_NAME}
203+
tag: ${IMAGE_TAG}
204+
EOF
205+
```
206+
207+
The `modelmesh-controller` watches the ConfigMap and responds to updates by automatically restarting the serving runtime
208+
pods using the newly built `modelmesh` container image.
209+
210+
You can check which container images are used by running the following command:
211+
212+
```Shell
213+
kubectl get pods -o jsonpath='{range .items[*]}{"\n"}{.metadata.name}{"\t"}{range .spec.containers[*]}{.image}{", "}{end}{end}' | sort | column -ts $'\t' | sed 's/, *$//g'
214+
215+
etcd-78ff7867d5-45svw quay.io/coreos/etcd:v3.5.4
216+
minio-6ddbfc9665-gtf7x kserve/modelmesh-minio-examples:latest
217+
modelmesh-controller-64f5c8d6d6-k6rzc kserve/modelmesh-controller:latest
218+
modelmesh-serving-mlserver-1.x-84884c6849-s8dw6 kserve/rest-proxy:latest, seldonio/mlserver:1.3.2, kserve/modelmesh-runtime-adapter:latest, kserve/modelmesh:dev
219+
modelmesh-serving-mlserver-1.x-84884c6849-xpdw4 kserve/rest-proxy:latest, seldonio/mlserver:1.3.2, kserve/modelmesh-runtime-adapter:latest, kserve/modelmesh:dev
220+
```

0 commit comments

Comments
 (0)