Ziad Meligy commited on
Commit
32458a9
·
1 Parent(s): 0682281

Adding files for docker build

Browse files
Files changed (5) hide show
  1. Dockerfile +22 -0
  2. app/main.py +54 -0
  3. app/maira2Service.py +43 -0
  4. app/readimageService.py +8 -0
  5. requirements.txt +0 -0
Dockerfile ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM python:3.11.4-slim
2
+
3
+ WORKDIR /app
4
+
5
+ # Create cache directory and set permissions as root
6
+ RUN mkdir -p /app/cache && \
7
+ useradd -m -u 1000 user && \
8
+ chown user:user /app/cache
9
+
10
+ # Switch to non-root user
11
+ USER user
12
+ ENV PATH="/home/user/.local/bin:$PATH"
13
+
14
+ # Copy and install requirements
15
+ COPY --chown=user ./requirements.txt requirements.txt
16
+ RUN pip install --no-cache-dir --upgrade -r requirements.txt
17
+
18
+ # Copy application code
19
+ COPY --chown=user . /app
20
+
21
+ # Run FastAPI app
22
+ CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "7860"]
app/main.py ADDED
@@ -0,0 +1,54 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import FastAPI, UploadFile, File, Form
2
+ from fastapi.responses import JSONResponse
3
+
4
+ from maira2Service import generate_report
5
+ from readimageService import read_image
6
+
7
+ app = FastAPI()
8
+
9
+ @app.post("/generate/frontal")
10
+ async def generate_frontal_report(frontal: UploadFile = File(...)):
11
+ try:
12
+ frontal_img = read_image(frontal)
13
+ report = generate_report(frontal_image=frontal_img)
14
+ return JSONResponse(content={"report": report})
15
+ except Exception as e:
16
+ return JSONResponse(status_code=500, content={"error": str(e)})
17
+
18
+ @app.post("/generate/lateral")
19
+ async def generate_lateral_report(
20
+ frontal: UploadFile = File(...),
21
+ lateral: UploadFile = File(...),
22
+ indication: str = Form(...),
23
+ technique: str = Form(...),
24
+ comparison: str = Form(...)
25
+ ):
26
+ try:
27
+ frontal_img = read_image(frontal)
28
+ lateral_img = read_image(lateral)
29
+ report = generate_report(
30
+ frontal_image=frontal_img,
31
+ lateral_image=lateral_img,
32
+ indication=indication,
33
+ technique=technique,
34
+ comparison=comparison
35
+ )
36
+ return JSONResponse(content={"report": report})
37
+ except Exception as e:
38
+ return JSONResponse(status_code=500, content={"error": str(e)})
39
+
40
+ @app.post("/generate/lateral/both")
41
+ async def generate_lateral_both_report(
42
+ frontal: UploadFile = File(...),
43
+ lateral: UploadFile = File(...),
44
+ ):
45
+ try:
46
+ frontal_img = read_image(frontal)
47
+ lateral_img = read_image(lateral)
48
+ report = generate_report(
49
+ frontal_image=frontal_img,
50
+ lateral_image=lateral_img,
51
+ )
52
+ return JSONResponse(content={"report": report})
53
+ except Exception as e:
54
+ return JSONResponse(status_code=500, content={"error": str(e)})
app/maira2Service.py ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from transformers import AutoModelForCausalLM, AutoProcessor
2
+ from pathlib import Path
3
+ import torch
4
+
5
+ model = AutoModelForCausalLM.from_pretrained("microsoft/maira-2", trust_remote_code=True)
6
+ processor = AutoProcessor.from_pretrained("microsoft/maira-2", trust_remote_code=True)
7
+
8
+ device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
9
+ if torch.cuda.is_available():
10
+ print("Using GPU for inference")
11
+ model = model.eval()
12
+ model = model.to(device)
13
+
14
+
15
+
16
+ def generate_report(frontal_image = None, lateral_image = None, indication="", technique="", comparison="" ):
17
+ inputs = processor.format_and_preprocess_reporting_input(
18
+ current_frontal=frontal_image,
19
+ current_lateral=lateral_image,
20
+ prior_frontal=None,
21
+ indication=indication,
22
+ technique=technique,
23
+ comparison=comparison,
24
+ prior_report=None,
25
+ return_tensors="pt",
26
+ get_grounding=False,
27
+ )
28
+ inputs = inputs.to(device)
29
+ with torch.no_grad():
30
+ output_decoding = model.generate(
31
+ **inputs,
32
+ max_new_tokens=300, # Set to 450 for grounded reporting
33
+ use_cache=True,
34
+ )
35
+ prompt_length = inputs["input_ids"].shape[-1]
36
+ decoded_text = processor.decode(output_decoding[0][prompt_length:], skip_special_tokens=True)
37
+ decoded_text = decoded_text.lstrip()
38
+ prediction = processor.convert_output_to_plaintext_or_grounded_sequence(decoded_text)
39
+ print("Parsed prediction:", prediction)
40
+ return prediction
41
+
42
+
43
+ print("Maira-2 service is ready to generate reports.")
app/readimageService.py ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ from fastapi import FastAPI, UploadFile, File, Form
2
+ from fastapi.responses import JSONResponse
3
+ import io
4
+ from PIL import Image
5
+
6
+
7
+ def read_image(upload: UploadFile) -> Image.Image:
8
+ return Image.open(io.BytesIO(upload.file.read()))
requirements.txt ADDED
Binary file (1.51 kB). View file