Samin7479 commited on
Commit
7282eec
·
1 Parent(s): 1b0a510

First trial

Browse files
Dockerfile ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM python:3.9
2
+
3
+ RUN useradd -m -u 1000 user
4
+ USER user
5
+ ENV PATH="/home/user/.local/bin:$PATH"
6
+
7
+ WORKDIR /app
8
+
9
+ COPY --chown=user ./requirements.txt requirements.txt
10
+ RUN pip install --no-cache-dir --upgrade -r requirements.txt
11
+
12
+ COPY --chown=user . /app
13
+ CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "7860"]
__pycache__/translator_app.cpython-311.pyc ADDED
Binary file (7.82 kB). View file
 
requirements.txt ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ fastapi
2
+ uvicorn[standard]
3
+ numpy
4
+ Pillow
5
+ torch
translator_app.py ADDED
@@ -0,0 +1,155 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # app.py — EN→BN MT API (cleaned)
2
+
3
+ import os
4
+ import torch
5
+ from typing import List, Optional
6
+ from fastapi import FastAPI, HTTPException
7
+ from fastapi.middleware.cors import CORSMiddleware # optional
8
+ from pydantic import BaseModel, Field
9
+ from transformers import AutoTokenizer, AutoModelForSeq2SeqLM
10
+
11
+ # -------------------------
12
+ # Device + model name (COPIED)
13
+ # -------------------------
14
+ device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
15
+ mt_pretrained_model_name = "shhossain/opus-mt-en-to-bn"
16
+
17
+ # -------------------------
18
+ # Load tokenizer/model with clear error if it fails
19
+ # -------------------------
20
+ try:
21
+ tokenizer = AutoTokenizer.from_pretrained(mt_pretrained_model_name)
22
+ model = AutoModelForSeq2SeqLM.from_pretrained(mt_pretrained_model_name).to(device)
23
+ model.eval()
24
+ except Exception as e:
25
+ raise RuntimeError(f"Failed to load model/tokenizer '{mt_pretrained_model_name}': {e}")
26
+
27
+ # Optional: be gentle on CPU-only machines
28
+ torch.set_num_threads(max(1, (os.cpu_count() or 1)))
29
+
30
+ # -------------------------
31
+ # FastAPI app + (optional) CORS
32
+ # -------------------------
33
+ app = FastAPI(title="EN→BN MT API", version="1.0.0")
34
+
35
+ # If you’ll call from a browser (localhost dev or a web app), enable CORS:
36
+ app.add_middleware(
37
+ CORSMiddleware,
38
+ allow_origins=["*"], # replace with your domain(s) in production
39
+ allow_credentials=True,
40
+ allow_methods=["*"],
41
+ allow_headers=["*"],
42
+ )
43
+
44
+ # -------------------------
45
+ # Schemas (COPIED/NEW mix)
46
+ # -------------------------
47
+ class TranslateIn(BaseModel):
48
+ text: str = Field(..., description="English sentence")
49
+ max_new_tokens: int = Field(128, ge=1, le=512)
50
+ num_beams: int = Field(4, ge=1, le=10)
51
+ do_sample: bool = Field(False, description="Use sampling instead of pure beam search")
52
+ temperature: Optional[float] = Field(1.0, ge=0.1, le=5.0)
53
+ top_p: Optional[float] = Field(1.0, ge=0.1, le=1.0)
54
+
55
+ class TranslateOut(BaseModel):
56
+ translation: str
57
+
58
+ class BatchTranslateIn(BaseModel):
59
+ texts: List[str] = Field(..., description="List of English sentences")
60
+ max_new_tokens: int = Field(128, ge=1, le=512)
61
+ num_beams: int = Field(4, ge=1, le=10)
62
+ do_sample: bool = Field(False)
63
+ temperature: Optional[float] = Field(1.0, ge=0.1, le=5.0)
64
+ top_p: Optional[float] = Field(1.0, ge=0.1, le=1.0)
65
+
66
+ class BatchTranslateOut(BaseModel):
67
+ translations: List[str]
68
+
69
+
70
+ MAX_INPUT_CHARS = 2000
71
+
72
+ def generate_translation(
73
+ inputs: List[str],
74
+ max_new_tokens: int,
75
+ num_beams: int,
76
+ do_sample: bool,
77
+ temperature: Optional[float],
78
+ top_p: Optional[float],
79
+ ) -> List[str]:
80
+ # input length guard
81
+ for s in inputs:
82
+ if len(s) > MAX_INPUT_CHARS:
83
+ raise ValueError(f"Input too long (> {MAX_INPUT_CHARS} chars).")
84
+
85
+ batch = tokenizer(
86
+ inputs,
87
+ return_tensors="pt",
88
+ padding=True,
89
+ truncation=True
90
+ ).to(device)
91
+
92
+ gen_kwargs = {
93
+ "max_new_tokens": max_new_tokens,
94
+ "num_beams": num_beams,
95
+ "do_sample": do_sample,
96
+ }
97
+ if do_sample:
98
+ if temperature is not None:
99
+ gen_kwargs["temperature"] = float(temperature)
100
+ if top_p is not None:
101
+ gen_kwargs["top_p"] = float(top_p)
102
+
103
+ with torch.no_grad():
104
+ outputs = model.generate(**batch, **gen_kwargs)
105
+
106
+ return tokenizer.batch_decode(outputs, skip_special_tokens=True)
107
+
108
+
109
+ @app.get("/greet")
110
+ def greet():
111
+ return {
112
+ "message": "Welcome to EN→BN MT API",
113
+ "device": "cuda" if torch.cuda.is_available() else "cpu",
114
+ "model": mt_pretrained_model_name,
115
+ }
116
+
117
+ @app.post("/translate", response_model=TranslateOut)
118
+ def translate(payload: TranslateIn):
119
+ try:
120
+ out = generate_translation(
121
+ [payload.text],
122
+ payload.max_new_tokens,
123
+ payload.num_beams,
124
+ payload.do_sample,
125
+ payload.temperature,
126
+ payload.top_p,
127
+ )[0]
128
+ return {"translation": out}
129
+ except Exception as e:
130
+ raise HTTPException(status_code=500, detail=str(e))
131
+
132
+ @app.post("/translate_batch", response_model=BatchTranslateOut)
133
+ def translate_batch(payload: BatchTranslateIn):
134
+ try:
135
+ if not payload.texts:
136
+ raise ValueError("texts list is empty.")
137
+ outs = generate_translation(
138
+ payload.texts,
139
+ payload.max_new_tokens,
140
+ payload.num_beams,
141
+ payload.do_sample,
142
+ payload.temperature,
143
+ payload.top_p,
144
+ )
145
+ return {"translations": outs}
146
+ except Exception as e:
147
+ raise HTTPException(status_code=500, detail=str(e))
148
+
149
+
150
+ if __name__ == "__main__":
151
+ if __name__ == "__main__":
152
+ import uvicorn
153
+
154
+ uvicorn.run(app, host="0.0.0.0", port=8000, reload=True)
155
+