Compare commits
10
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ec4162e34d | ||
|
|
99b7067cfe | ||
|
|
e62435cf22 | ||
|
|
3560a61277 | ||
|
|
7f0cbea937 | ||
|
|
31156eea54 | ||
|
|
ef11c33675 | ||
|
|
89aecfdef7 | ||
|
|
68e04c7653 | ||
|
|
a12f8c46e8 |
@@ -9,3 +9,8 @@ services:
|
|||||||
- ../server.env
|
- ../server.env
|
||||||
environment:
|
environment:
|
||||||
- ENV=TEST
|
- ENV=TEST
|
||||||
|
deploy:
|
||||||
|
resources:
|
||||||
|
limits:
|
||||||
|
cpus: '2.000'
|
||||||
|
memory: 8G
|
||||||
|
|||||||
+25
-28
@@ -1,45 +1,42 @@
|
|||||||
"""Main script to be run by service."""
|
"""Main script to be run by service."""
|
||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
from hashlib import md5
|
import logging
|
||||||
from io import BytesIO
|
from pathlib import Path
|
||||||
|
|
||||||
import torch
|
import torch
|
||||||
from data_store import connect
|
from dotenv import load_dotenv
|
||||||
from data_store import put
|
|
||||||
from models import VisualCommunicationModel
|
from models import VisualCommunicationModel
|
||||||
from torchinfo import summary
|
from torchinfo import summary
|
||||||
from utils import check_env
|
from utils import get_model_name
|
||||||
|
|
||||||
|
from shared.data_store import connect, get_model
|
||||||
from shared.utils import setup_logging
|
from shared.utils import setup_logging
|
||||||
|
|
||||||
|
|
||||||
DEVICE = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
|
DEVICE = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
# check that environment variables are set
|
# load in env file
|
||||||
check_env()
|
env_path = Path(__file__).parent.parent.parent / 'server.env'
|
||||||
|
assert env_path.exists()
|
||||||
|
load_dotenv(env_path)
|
||||||
# setup logging
|
# setup logging
|
||||||
setup_logging()
|
setup_logging()
|
||||||
|
# connect to minio
|
||||||
|
minio_client = connect()
|
||||||
# instantiate model
|
# instantiate model
|
||||||
model = VisualCommunicationModel().to(DEVICE)
|
model = VisualCommunicationModel()
|
||||||
|
# get model object name
|
||||||
|
model_name_path = Path(__file__).parent / 'model_name.txt'
|
||||||
|
model_object_name = get_model_name(path=model_name_path)
|
||||||
|
logging.info('using model: %s', model_object_name)
|
||||||
|
# load model from minio
|
||||||
|
model_checkpoint = get_model(
|
||||||
|
client=minio_client,
|
||||||
|
object_name=model_object_name,
|
||||||
|
)
|
||||||
|
model.load_state_dict(model_checkpoint)
|
||||||
|
# move model to selected device
|
||||||
|
model = model.to(DEVICE)
|
||||||
# show model weights
|
# show model weights
|
||||||
summary(model)
|
summary(model)
|
||||||
# for param in model.parameters():
|
print('loaded model')
|
||||||
# logging.info(param.data)
|
|
||||||
# save model to buffer
|
|
||||||
buffer = BytesIO()
|
|
||||||
torch.save(model.state_dict(), buffer)
|
|
||||||
print(f"buffer size: {len(buffer.getvalue())}")
|
|
||||||
# calculate buffer hash
|
|
||||||
hash_str = md5(buffer.getbuffer()).hexdigest()
|
|
||||||
print(f"hash string: {hash_str}")
|
|
||||||
# connect to minio
|
|
||||||
client = connect()
|
|
||||||
# put buffer in minio bucket
|
|
||||||
put(
|
|
||||||
client=client,
|
|
||||||
buffer=buffer,
|
|
||||||
object_name=hash_str,
|
|
||||||
)
|
|
||||||
print('saved to Minio')
|
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
fb75db772ba8b280bdaf1774d5f73f58
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
from .get_model_name import get_model_name
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
"""Definition of get_model_name function."""
|
||||||
|
|
||||||
|
import logging
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
|
||||||
|
def get_model_name(
|
||||||
|
path: Path,
|
||||||
|
) -> str:
|
||||||
|
"""Get model name from model_name file."""
|
||||||
|
assert isinstance(path, Path)
|
||||||
|
assert path.exists(), f'{path} does not exist'
|
||||||
|
# read file contents
|
||||||
|
with open(file=path, encoding='utf-8') as fh:
|
||||||
|
model_name = fh.read()
|
||||||
|
# remove newline character
|
||||||
|
model_name = model_name.strip()
|
||||||
|
logging.debug('finished')
|
||||||
|
return model_name
|
||||||
@@ -2,5 +2,7 @@ from .connect import connect
|
|||||||
from .delete import delete
|
from .delete import delete
|
||||||
from .get import get
|
from .get import get
|
||||||
from .get_image import get_image
|
from .get_image import get_image
|
||||||
|
from .get_model import get_model
|
||||||
from .put import put
|
from .put import put
|
||||||
from .put_image import put_image
|
from .put_image import put_image
|
||||||
|
from .put_model import put_model
|
||||||
|
|||||||
@@ -34,14 +34,9 @@ def connect() -> Minio:
|
|||||||
secret_key=minio_secret_key,
|
secret_key=minio_secret_key,
|
||||||
secure=False,
|
secure=False,
|
||||||
)
|
)
|
||||||
# ensure buckets exists
|
# ensure bucket exists
|
||||||
bucket_name_list = [
|
if not client.bucket_exists(bucket_name=minio_bucket_name):
|
||||||
'images',
|
logging.info('creating bucket: %s', minio_bucket_name)
|
||||||
'models',
|
|
||||||
]
|
|
||||||
for bucket_name in bucket_name_list:
|
|
||||||
if not client.bucket_exists(bucket_name=bucket_name):
|
|
||||||
logging.info('creating bucket: %s', bucket_name)
|
|
||||||
client.make_bucket(bucket_name=minio_bucket_name)
|
client.make_bucket(bucket_name=minio_bucket_name)
|
||||||
logging.debug('finished')
|
logging.debug('finished')
|
||||||
return client
|
return client
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
"""Definition of get function."""
|
"""Definition of get function."""
|
||||||
|
|
||||||
|
import logging
|
||||||
import os
|
import os
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
|
from traceback import print_exc
|
||||||
|
|
||||||
from minio import Minio
|
from minio import Minio
|
||||||
|
|
||||||
@@ -16,10 +18,22 @@ def get(
|
|||||||
bucket_name = os.getenv('MINIO_BUCKET_NAME')
|
bucket_name = os.getenv('MINIO_BUCKET_NAME')
|
||||||
# get buffer
|
# get buffer
|
||||||
try:
|
try:
|
||||||
response = client.get_object(bucket_name, object_name)
|
response = client.get_object(
|
||||||
buffer = BytesIO(response.data)
|
bucket_name=bucket_name,
|
||||||
|
object_name=object_name,
|
||||||
|
)
|
||||||
|
assert response.status == 200
|
||||||
|
buffer = BytesIO()
|
||||||
|
chunk_size = 2**14
|
||||||
|
while chunk := response.read(chunk_size):
|
||||||
|
buffer.write(chunk)
|
||||||
|
buffer.seek(0)
|
||||||
|
logging.debug('got %s', object_name)
|
||||||
|
return buffer
|
||||||
|
except Exception as exc:
|
||||||
|
logging.error('failed getting data from MinIO')
|
||||||
|
print_exc()
|
||||||
|
raise exc
|
||||||
finally:
|
finally:
|
||||||
response.close()
|
response.close()
|
||||||
response.release_conn()
|
response.release_conn()
|
||||||
buffer.seek(0)
|
|
||||||
return buffer
|
|
||||||
|
|||||||
@@ -0,0 +1,31 @@
|
|||||||
|
"""Definition of get_model function."""
|
||||||
|
|
||||||
|
import logging
|
||||||
|
from collections import OrderedDict
|
||||||
|
|
||||||
|
import torch
|
||||||
|
from minio import Minio
|
||||||
|
|
||||||
|
from .get import get
|
||||||
|
|
||||||
|
|
||||||
|
def get_model(
|
||||||
|
client: Minio,
|
||||||
|
object_name: str,
|
||||||
|
) -> OrderedDict:
|
||||||
|
"""Get model from model subfolder in bucket in Minio."""
|
||||||
|
assert isinstance(client, Minio)
|
||||||
|
assert isinstance(object_name, str)
|
||||||
|
subfolder = 'models'
|
||||||
|
object_name = f'{subfolder}/{object_name}'
|
||||||
|
# get buffer
|
||||||
|
buffer = get(
|
||||||
|
client=client,
|
||||||
|
object_name=object_name,
|
||||||
|
)
|
||||||
|
logging.debug('buffer size: %s', buffer.getbuffer().nbytes)
|
||||||
|
# convert data to model checkpoint
|
||||||
|
buffer.seek(0)
|
||||||
|
model_content = torch.load(buffer)
|
||||||
|
logging.debug('finished')
|
||||||
|
return model_content
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
"""Definition of put_model function."""
|
||||||
|
|
||||||
|
import logging
|
||||||
|
import os
|
||||||
|
from hashlib import md5
|
||||||
|
from io import BytesIO
|
||||||
|
|
||||||
|
import torch
|
||||||
|
from minio import Minio
|
||||||
|
from torch.nn import Module
|
||||||
|
|
||||||
|
|
||||||
|
def put_model(
|
||||||
|
client: Minio,
|
||||||
|
model: Module,
|
||||||
|
) -> str:
|
||||||
|
"""Put model in model subfolder in bucket in Minio and return MD5 checksum
|
||||||
|
used as object name."""
|
||||||
|
assert isinstance(client, Minio)
|
||||||
|
assert isinstance(model, Module)
|
||||||
|
bucket_name = os.getenv('MINIO_BUCKET_NAME')
|
||||||
|
subfolder = 'models'
|
||||||
|
# save image to buffer
|
||||||
|
buffer = BytesIO()
|
||||||
|
torch.save(model.state_dict(), buffer)
|
||||||
|
# get md5 of image
|
||||||
|
checksum = md5(buffer.getbuffer()).hexdigest()
|
||||||
|
# prepare for saving
|
||||||
|
num_bytes = buffer.tell()
|
||||||
|
buffer.seek(0)
|
||||||
|
# send data to bucket
|
||||||
|
object_name = f'{subfolder}/{checksum}'
|
||||||
|
try:
|
||||||
|
client.put_object(
|
||||||
|
bucket_name=bucket_name,
|
||||||
|
object_name=object_name,
|
||||||
|
length=num_bytes,
|
||||||
|
data=buffer,
|
||||||
|
)
|
||||||
|
except Exception as exc:
|
||||||
|
logging.error('failed saving data to MinIO')
|
||||||
|
raise exc
|
||||||
|
logging.debug('saved data to %s', object_name)
|
||||||
|
return checksum
|
||||||
+12
-15
@@ -1,37 +1,34 @@
|
|||||||
"""Test that a model can be saved and loaded again."""
|
"""Test that a model can be saved and loaded again."""
|
||||||
|
|
||||||
from io import BytesIO
|
from pathlib import Path
|
||||||
|
|
||||||
import torch
|
import torch
|
||||||
|
from dotenv import load_dotenv
|
||||||
from torchinfo import summary
|
from torchinfo import summary
|
||||||
|
|
||||||
from model.src.models import VisualCommunicationModel
|
from model.src.models import VisualCommunicationModel
|
||||||
from shared.data_store import connect, put
|
from shared.data_store import connect, put_model
|
||||||
from shared.utils import check_env, setup_logging
|
from shared.utils import setup_logging
|
||||||
|
|
||||||
DEVICE = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
|
DEVICE = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
# check that environment variables are set
|
# load in env file
|
||||||
check_env()
|
env_path = Path(__file__).parent.parent / 'server.env'
|
||||||
|
assert env_path.exists()
|
||||||
|
load_dotenv(env_path)
|
||||||
# setup logging
|
# setup logging
|
||||||
setup_logging()
|
setup_logging()
|
||||||
|
# connect to minio
|
||||||
|
client = connect()
|
||||||
# instantiate model
|
# instantiate model
|
||||||
model = VisualCommunicationModel().to(DEVICE)
|
model = VisualCommunicationModel().to(DEVICE)
|
||||||
# show model weights
|
# show model weights
|
||||||
summary(model)
|
summary(model)
|
||||||
# for param in model.parameters():
|
|
||||||
# logging.info(param.data)
|
|
||||||
# save model to buffer
|
|
||||||
buffer = BytesIO()
|
|
||||||
torch.save(model.state_dict(), buffer)
|
|
||||||
print(f"buffer size: {len(buffer.getvalue())}")
|
|
||||||
# connect to minio
|
|
||||||
client = connect(bucket='models')
|
|
||||||
# put buffer in minio bucket
|
# put buffer in minio bucket
|
||||||
hash_str = put(
|
hash_str = put_model(
|
||||||
client=client,
|
client=client,
|
||||||
buffer=buffer,
|
model=model,
|
||||||
)
|
)
|
||||||
print(f"hash string: {hash_str}")
|
print(f"hash string: {hash_str}")
|
||||||
print('saved to Minio')
|
print('saved to Minio')
|
||||||
|
|||||||
Reference in New Issue
Block a user