Skip to content

Commit

Permalink
Feature - Heavy Evaluation (#316)
Browse files Browse the repository at this point in the history
* New model for heavy inference implemented also in the frontEnd

* black changes

* include creation of model in DB
  • Loading branch information
shincap8 authored Dec 20, 2024
1 parent 6549677 commit 7d8b64e
Show file tree
Hide file tree
Showing 7 changed files with 122 additions and 23 deletions.
21 changes: 21 additions & 0 deletions backend/app/api/endpoints/base/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,27 @@ async def upload_model_to_s3_and_evaluate(
return "The model will be evaluated in the background"


@router.post("/heavy_evaluation")
def heavy_evaluation(
background_tasks: BackgroundTasks,
model: UploadModelToS3AndEvaluateRequest = Depends(
UploadModelToS3AndEvaluateRequest
),
):
return ModelService().upload_model_to_s3(
model.model_name,
model.description,
model.num_paramaters,
model.languages,
model.license,
model.file_name,
model.user_id,
model.task_code,
model.file_to_upload,
background_tasks,
)


@router.get("/initiate_lambda_models")
def initiate_lambda_models() -> None:
return ModelService().initiate_lambda_models()
Expand Down
3 changes: 2 additions & 1 deletion backend/app/domain/helpers/email.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ def send(
server.close()
return f"e-mail sended to {contact}"

except Exception:
except Exception as e:
print("Error sending e-mail")
print(e)
return False
65 changes: 64 additions & 1 deletion backend/app/domain/services/base/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@

import json
import os
import re
import secrets
import time

import boto3
import requests
import yaml
from fastapi import HTTPException, UploadFile
from fastapi import BackgroundTasks, HTTPException, UploadFile
from pydantic import Json

from app.domain.helpers.email import EmailHelper
Expand Down Expand Up @@ -174,6 +175,68 @@ def upload_model_to_s3_and_evaluate(
def single_model_prediction(self, model_url: str, model_input: dict):
return requests.post(model_url, json=model_input).json()

def upload_model_to_s3(
self,
model_name: str,
description: str,
num_paramaters: str,
languages: str,
license: str,
file_name: str,
user_id: str,
task_code: str,
file_to_upload: UploadFile,
background_tasks: BackgroundTasks,
):
task_id = self.task_repository.get_task_id_by_task_code(task_code)[0]
task_s3_bucket = self.task_repository.get_s3_bucket_by_task_id(task_id)[0]
user_email = self.user_repository.get_user_email(user_id)[0]

file_name = file_name.lower()
file_name = file_name.replace("/", ":")
file_name = re.sub(r"\s+", "_", file_name)
clean_file_name = re.sub(r"_+", "_", file_name)

model_name_clean = model_name.lower()
model_name_clean = model_name_clean.replace("/", ":")
model_name_clean = re.sub(r"\s+", "_", model_name_clean)
model_name_clean = re.sub(r"_+", "_", model_name_clean)

model_path = f"{task_code}/submited_models/{task_id}-{user_id}-{model_name}-{clean_file_name}"
try:
self.s3.put_object(
Body=file_to_upload.file,
Bucket=task_s3_bucket,
Key=model_path,
ContentType=file_to_upload.content_type,
)
self.user_repository.increment_model_submitted_count(user_id)
self.model_repository.create_new_model(
task_id=task_id,
user_id=user_id,
model_name=model_name,
shortname=model_name,
longdesc=description,
desc=description,
languages=languages,
license=license,
params=num_paramaters,
deployment_status="uploaded",
secret=secrets.token_hex(),
)
background_tasks.add_task(
self.email_helper.send,
contact=user_email,
cc_contact=self.email_sender,
template_name="model_upload_successful.txt",
msg_dict={"name": model_name},
subject=f"Model {model_name} upload succeeded.",
)
return "Model upload successfully"
except Exception as e:
print(f"An unexpected error occurred: {e}")
return "Model upload failed"

def single_model_prediction_submit(
self,
model_url: str,
Expand Down
7 changes: 7 additions & 0 deletions backend/app/infrastructure/repositories/task.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,13 @@ def get_task_id_by_task_code(self, task_code: str):
.first()
)

def get_s3_bucket_by_task_id(self, task_id: int):
return (
self.session.query(self.model.s3_bucket)
.filter(self.model.id == task_id)
.first()
)

def get_task_code_by_task_id(self, task_id: int):
return (
self.session.query(self.model.task_code)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ const CreateInterface = () => {
let { taskCode } = useParams<{ taskCode: string }>();
const { user } = useContext(UserContext);
const { updateAmountExamplesCreatedToday } = useContext(
CreateInterfaceContext,
CreateInterfaceContext
);
const history = useHistory();
const location = useLocation();
Expand All @@ -59,7 +59,7 @@ const CreateInterface = () => {
{
round_id: taskContextInfo?.real_round_id,
user_id: user.id!,
},
}
);
if (!stillAllowedToSubmit) {
Swal.fire({
Expand Down Expand Up @@ -89,13 +89,12 @@ const CreateInterface = () => {
setTaskInfo(taskInfo);
setTaskId(taskId);
setIsGenerativeContext(
taskConfiguration.context.generative_context?.is_generative,
taskConfiguration.context.generative_context?.is_generative
);
}
};

const loadTaskContext = async () => {
console.log("in new method");
const configContext = taskConfiguration?.context as any;
let needContext;
if ("context_for_start" in configContext) {
Expand All @@ -114,15 +113,15 @@ const CreateInterface = () => {
const isLogin = async (
assignmentId: string | null,
taskCode: string,
treatmentId: string | null,
treatmentId: string | null
) => {
if (!user.id) {
await checkUserIsLoggedIn(
history,
`/`,
assignmentId,
taskCode,
treatmentId,
treatmentId
);
}
};
Expand All @@ -146,7 +145,7 @@ const CreateInterface = () => {
if (taskContextInfo?.real_round_id) {
updateAmountExamplesCreatedToday(
taskContextInfo?.real_round_id,
user.id!,
user.id!
);
}
}, [taskContextInfo, user]);
Expand Down Expand Up @@ -250,7 +249,7 @@ const CreateInterface = () => {
isGenerativeContext={isGenerativeContext}
userId={user.id!}
accept_sandbox_creation={Boolean(
taskInfo.accept_sandbox_creation,
taskInfo.accept_sandbox_creation
)}
setModelOutput={setModelOutput}
setIsGenerativeContext={setIsGenerativeContext}
Expand Down
25 changes: 14 additions & 11 deletions frontends/web/src/new_front/pages/SubmitModel/SubmitModel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,15 +51,18 @@ const SubmitModel = () => {
formData.append("user_id", user.id);
formData.append("task_code", taskCode);
formData.append("file_to_upload", modelData.file);
sendModelData(formData).then(() => {
setLoading({ loading: true, text: "Done" });
Swal.fire({
title: "Good job!",
text: "Your model will be uploaded and soon you will be able to see the results in the dynaboard (you will receive an email!)",
icon: "success",
confirmButtonColor: "#007bff",
});
});

sendModelData(formData, configYaml.evaluation?.type === "heavy").then(
() => {
setLoading({ loading: true, text: "Done" });
Swal.fire({
title: "Good job!",
text: "Your model will be uploaded and soon you will be able to see the results in the dynaboard (you will receive an email!)",
icon: "success",
confirmButtonColor: "#007bff",
});
}
);
} else {
setLoadingFile(true);
alert("Please upload a model");
Expand All @@ -70,12 +73,12 @@ const SubmitModel = () => {
const getTaskData = async () => {
const taskId = await get(`/task/get_task_id_by_task_code/${taskCode}`);
const taskData = await get(
`/task/get_task_with_round_info_by_task_id/${taskId}`,
`/task/get_task_with_round_info_by_task_id/${taskId}`
);
const dynalabModel = await get(`/model/get_dynalab_model/${taskCode}`);
if (response.ok) {
setConfigYaml(
JSON.parse(JSON.stringify(yaml.load(taskData.config_yaml))),
JSON.parse(JSON.stringify(yaml.load(taskData.config_yaml)))
);
setDynalabModel(dynalabModel);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,16 @@ import Swal from "sweetalert2";
const useUploadFile = () => {
const [progress, setProgress] = useState(0);

const sendModelData = (formData: FormData) => {
const sendModelData = (formData: FormData, heavy: boolean = false) => {
const url = `${process.env.REACT_APP_API_HOST_2}${
heavy
? "/model/heavy_evaluation"
: "/model/upload_model_to_s3_and_evaluate"
}`;
return axios
.request({
method: "post",
url: `${process.env.REACT_APP_API_HOST_2}/model/upload_model_to_s3_and_evaluate`,
url: url,
data: formData,
onUploadProgress: (p) => {
setProgress(p.loaded / p.total);
Expand Down

0 comments on commit 7d8b64e

Please sign in to comment.