Skip to content

Commit 4f501f9

Browse files
Merge pull request #87 from espoirMur/feat/integrate-m2m-models
Feat/integrate m2m models
2 parents 1c7ad22 + 2f1053a commit 4f501f9

30 files changed

+2905
-13
lines changed

.gitignore

+8-1
Original file line numberDiff line numberDiff line change
@@ -102,4 +102,11 @@ src/server/core/models/joeynmt
102102

103103
.env.prod
104104

105-
*.sqlite
105+
*.sqlite
106+
107+
### ignore model export
108+
109+
onnx/
110+
*.onnx
111+
model_store/
112+
logs/

.python-version

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
3.10.7

docker-compose.yml

+2-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ services:
1010
command: python manage.py run -h 0.0.0.0
1111
volumes:
1212
- './src/server:/usr/src/app'
13+
- './models/joeynmt:/usr/src/app/models/joeynmt'
1314
ports:
1415
- 5000:5000
1516

@@ -45,4 +46,4 @@ services:
4546
# we configured a volume. This config will bind
4647
# postgres_data to the "/var/lib/postgresql/data/" directory in the container.
4748
volumes:
48-
postgres_data:
49+
postgres_data:

kubernetes/ingress-def.yml

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
apiVersion: networking.k8s.io/v1
2+
kind: Ingress
3+
metadata:
4+
name: seldon-ingress
5+
namespace: seldon
6+
spec:
7+
rules:
8+
- host: seldon-ingress.com
9+
http:
10+
paths:
11+
- path: "/"
12+
pathType: Prefix
13+
backend:
14+
service:
15+
name: iris-model-sklearn-iris-predictor
16+
port:
17+
number: 8000

kubernetes/sample-server.yaml

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
apiVersion: machinelearning.seldon.io/v1
2+
kind: SeldonDeployment
3+
metadata:
4+
name: iris-model
5+
namespace: seldon
6+
spec:
7+
name: iris
8+
annotations:
9+
prometheus.io/scrape: "false"
10+
predictors:
11+
- componentSpecs:
12+
- spec:
13+
containers:
14+
- env:
15+
- name: SELDON_LOG_LEVEL
16+
value: DEBUG
17+
- name: SELDON_DEBUG
18+
value: 'True'
19+
- name: FLASK_DEBUG
20+
value: 'True'
21+
image: seldonio/sklearn-iris:0.3
22+
imagePullPolicy: IfNotPresent
23+
name: sklearn-iris-classifier
24+
graph:
25+
endpoint:
26+
type: REST
27+
name: sklearn-iris-classifier
28+
type: MODEL
29+
name: sklearn-iris-predictor
30+
replicas: 1

onnx-export.ipynb

+851
Large diffs are not rendered by default.

requirements-python3.10.txt

+113
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
aiohttp==3.8.4
2+
aiosignal==1.3.1
3+
appnope==0.1.3
4+
asttokens==2.2.1
5+
async-timeout==4.0.2
6+
attrs==22.2.0
7+
backcall==0.2.0
8+
captum==0.6.0
9+
certifi==2022.12.7
10+
cffi==1.15.1
11+
charset-normalizer==3.0.1
12+
click==8.0.4
13+
coloredlogs==15.0.1
14+
comm==0.1.2
15+
contourpy==1.0.7
16+
cryptography==3.4.8
17+
cycler==0.11.0
18+
datasets==2.10.0
19+
debugpy==1.6.6
20+
decorator==5.1.1
21+
dill==0.3.6
22+
enum-compat==0.0.3
23+
executing==1.2.0
24+
filelock==3.9.0
25+
Flask==2.2.3
26+
Flask-Cors==3.0.10
27+
Flask-OpenTracing==1.1.0
28+
flatbuffers==1.12
29+
fonttools==4.38.0
30+
frozenlist==1.3.3
31+
fsspec==2023.1.0
32+
grpcio==1.51.3
33+
grpcio-opentracing==1.1.4
34+
grpcio-reflection==1.34.1
35+
gunicorn==20.1.0
36+
huggingface-hub==0.12.1
37+
humanfriendly==10.0
38+
idna==3.4
39+
ipykernel==6.21.2
40+
ipython==8.10.0
41+
itsdangerous==2.1.2
42+
jaeger-client==4.4.0
43+
jedi==0.18.2
44+
Jinja2==3.1.2
45+
jsonschema==3.2.0
46+
jupyter_client==8.0.3
47+
jupyter_core==5.2.0
48+
kiwisolver==1.4.4
49+
MarkupSafe==2.1.2
50+
matplotlib==3.7.0
51+
matplotlib-inline==0.1.6
52+
mpmath==1.2.1
53+
multidict==6.0.4
54+
multiprocess==0.70.14
55+
nest-asyncio==1.5.6
56+
numpy==1.23.5
57+
onnx==1.13.1
58+
onnxruntime==1.13.1
59+
onnxruntime-tools==1.7.0
60+
opentracing==2.4.0
61+
optimum==1.6.4
62+
ort-nightly==1.11.0.dev20220320001
63+
packaging==23.0
64+
pandas==1.5.3
65+
parso==0.8.3
66+
pexpect==4.8.0
67+
pickleshare==0.7.5
68+
Pillow==9.4.0
69+
platformdirs==3.0.0
70+
prometheus-client==0.8.0
71+
prompt-toolkit==3.0.37
72+
protobuf==3.20.3
73+
psutil==5.9.4
74+
ptyprocess==0.7.0
75+
pure-eval==0.2.2
76+
py-cpuinfo==9.0.0
77+
py3nvml==0.2.7
78+
pyarrow==11.0.0
79+
pycodestyle==2.10.0
80+
pycparser==2.21
81+
Pygments==2.14.0
82+
pyparsing==3.0.9
83+
pyrsistent==0.19.3
84+
python-dateutil==2.8.2
85+
pytz==2022.7.1
86+
PyYAML==5.4.1
87+
pyzmq==25.0.0
88+
regex==2022.10.31
89+
requests==2.28.2
90+
responses==0.18.0
91+
seldon-core==1.15.0
92+
sentencepiece==0.1.97
93+
six==1.16.0
94+
stack-data==0.6.2
95+
sympy==1.11.1
96+
threadloop==1.0.2
97+
thrift==0.16.0
98+
tokenizers==0.13.2
99+
torch==1.13.1
100+
torch-model-archiver==0.7.1
101+
torch-workflow-archiver==0.2.7
102+
torchserve==0.7.1
103+
tornado==6.2
104+
tqdm==4.64.1
105+
traitlets==5.9.0
106+
transformers==4.26.1
107+
typing_extensions==4.5.0
108+
urllib3==1.26.14
109+
wcwidth==0.2.6
110+
Werkzeug==2.2.3
111+
xmltodict==0.13.0
112+
xxhash==3.2.0
113+
yarl==1.8.2

src/client/src/components/translateCard.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ export default function TranslateCard() {
7777
})
7878
.then(res => res.json())
7979
.then(data => {
80-
// console.log({ data })
80+
console.log({ data })
8181
// do something here
8282
setTranslation(data.output)
8383
})
@@ -385,4 +385,4 @@ export default function TranslateCard() {
385385
</div>
386386
</Container>
387387
)
388-
}
388+
}

src/client/webpack.config.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ module.exports = {
2626
proxy: {
2727
'/': {
2828
// target: 'http://[::1]:5000',
29-
target: 'http://localhost:5000',
29+
// todo: make the ip a configuration environment variable
30+
target: 'http://45.147.99.147:5000',
3031
// target: 'http://127.0.0.1:5000',
3132
bypass: function (req, res, proxyOptions) {
3233
if (req.headers.accept.indexOf('html') !== -1) {

src/m_to_m_models/Dockerfile

+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
FROM python:3.10 as base
2+
LABEL maintainer="Espoir Murhabazi<espoir.mur [] gmail>"
3+
4+
5+
# Never prompt the user for choices on installation/configuration of packages
6+
ENV DEBIAN_FRONTEND noninteractive
7+
ENV PYTHONUNBUFFERED=1 \
8+
PORT=9000 \
9+
PYTHONDONTWRITEBYTECODE=1 \
10+
PIP_NO_CACHE_DIR=off \
11+
PIP_DISABLE_PIP_VERSION_CHECK=on \
12+
PIP_DEFAULT_TIMEOUT=100
13+
14+
15+
FROM base AS python-deps
16+
RUN apt-get update \
17+
&& apt-get install --no-install-recommends -y \
18+
curl \
19+
build-essential\
20+
software-properties-common
21+
22+
RUN python -m venv /opt/venv
23+
# Make sure we use the virtualenv:
24+
ENV PATH="/opt/venv/bin:$PATH"
25+
26+
# Install pip
27+
COPY requirements.txt ./
28+
RUN pip install --upgrade pip
29+
RUN pip install -r requirements.txt
30+
31+
32+
33+
FROM base AS runtime
34+
# copy nltk data
35+
COPY --from=python-deps /opt/venv /opt/venv
36+
37+
38+
RUN useradd --create-home masakhane
39+
RUN usermod -aG sudo masakhane
40+
RUN mkdir /home/masakhane/translation_app/
41+
ENV WORKING_DIR=/home/masakhane/translation_app/
42+
ENV PATH="${WORKING_DIR}:$PATH"
43+
ENV PATH="/opt/venv/bin:$PATH"
44+
ENV PYTHONPATH="/opt/venv/bin:$PYTHONPATH"
45+
ENV PYTHONPATH="${PYTHONPATH}:${WORKING_DIR}"
46+
47+
ENV MODEL_NAME model_handlers.OptimizedM100Model
48+
49+
ENV SERVICE_TYPE MODEL
50+
51+
COPY model_handlers.py ${WORKING_DIR}
52+
WORKDIR ${WORKING_DIR}
53+
RUN chown -R masakhane:masakhane ${WORKING_DIR}
54+
RUN chmod -R 777 ${WORKING_DIR}
55+
USER masakhane
56+
EXPOSE 9000 5000
57+
58+
CMD exec seldon-core-microservice $MODEL_NAME --service-type $SERVICE_TYPE

src/m_to_m_models/app.py

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
from flask import Flask, jsonify, request
2+
from flask_cors import CORS
3+
import logging
4+
5+
6+
logger = logging.getLogger(__name__)
7+
8+
def create_app(model_handler):
9+
app = Flask(__name__, static_url_path="")
10+
CORS(app)
11+
12+
@app.route("/predict", methods=["GET", "POST"])
13+
def predict():
14+
request_data = request.get_json()
15+
logger.debug("REST Request: %s", request)
16+
response = model_handler.predict_raw(request_data)
17+
18+
json_response = jsonify(response)
19+
if (
20+
isinstance(response, dict)
21+
and "status" in response
22+
and "code" in response["status"]
23+
):
24+
json_response.status_code = response["status"]["code"]
25+
26+
logger.debug("REST Response: %s", response)
27+
return json_response
28+
29+
return app
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
apiVersion: machinelearning.seldon.io/v1
2+
kind: SeldonDeployment
3+
metadata:
4+
name: translation-deployment
5+
namespace: masakhane
6+
spec:
7+
name: translation-worker
8+
predictors:
9+
- componentSpecs:
10+
- spec:
11+
containers:
12+
- image: masakhane/translation:alpha
13+
name: translation-container
14+
imagePullPolicy: IfNotPresent
15+
env:
16+
- name: TRANSFORMERS_CACHE
17+
value: "/models_datastore/.cache"
18+
- name: GUNICORN_WORKERS
19+
value: '1'
20+
- name: GRPC_WORKERS
21+
value: '0'
22+
- name: SELDON_LOG_LEVEL
23+
value: DEBUG
24+
- name: SELDON_DEBUG
25+
value: 'True'
26+
- name: FLASK_DEBUG
27+
value: 'True'
28+
volumeMounts:
29+
- mountPath: "/models_datastore/" # mount the cache volume here
30+
name: translation-volume-storage
31+
resources:
32+
requests:
33+
memory: 8Gi
34+
cpu: 3
35+
limits:
36+
memory: 9Gi
37+
cpu: 4
38+
terminationGracePeriodSeconds: 1
39+
volumes:
40+
- name: translation-volume-storage
41+
persistentVolumeClaim:
42+
claimName: masakhane-model-cache-volume-claim
43+
graph:
44+
envSecretRefName: masakhane-container-secret
45+
children: []
46+
endpoint:
47+
type: REST
48+
name: translation-container
49+
type: MODEL
50+
parameters:
51+
- name: model_path
52+
type: STRING
53+
value: "/models_datastore/" # this should come form volume.
54+
- name: src_lang
55+
type: STRING
56+
value: "en"
57+
- name: tgt_lang
58+
type: STRING
59+
value: "sw"
60+
labels:
61+
version: v1
62+
name: translation-predictor
63+
replicas: 1
+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
apiVersion: v1
2+
kind: Secret
3+
metadata:
4+
name: masakhane-container-secret
5+
namespace: masakhane
6+
type: Opaque
7+
stringData:
8+
RCLONE_CONFIG_S3_TYPE: s3
9+
RCLONE_CONFIG_S3_PROVIDER: minio
10+
RCLONE_CONFIG_S3_ENV_AUTH: "false"
11+
RCLONE_CONFIG_S3_ACCESS_KEY_ID: minioadmin
12+
RCLONE_CONFIG_S3_SECRET_ACCESS_KEY: minioadmin
13+
RCLONE_CONFIG_S3_ENDPOINT: http://minio.minio-system.svc.cluster.local:9000

0 commit comments

Comments
 (0)