harshil-code commited on
Commit
5ba8994
·
1 Parent(s): 4297fe3

feat: Add streaming translation endpoint and implementation.

Browse files
Files changed (2) hide show
  1. main.py +7 -1
  2. model_loader.py +43 -5
main.py CHANGED
@@ -1,6 +1,7 @@
1
  from fastapi import FastAPI
 
2
  from pydantic import BaseModel
3
- from model_loader import translate
4
 
5
  app = FastAPI(title="NLLB Translation API")
6
 
@@ -10,3 +11,8 @@ class TranslationRequest(BaseModel):
10
  @app.post("/translate")
11
  def translate_text(req: TranslationRequest):
12
  return {"translated_text": translate(req.text)}
 
 
 
 
 
 
1
  from fastapi import FastAPI
2
+ from fastapi.responses import StreamingResponse
3
  from pydantic import BaseModel
4
+ from model_loader import translate, stream_translate
5
 
6
  app = FastAPI(title="NLLB Translation API")
7
 
 
11
  @app.post("/translate")
12
  def translate_text(req: TranslationRequest):
13
  return {"translated_text": translate(req.text)}
14
+
15
+ @app.post("/translate/stream")
16
+ def translate_stream(req: TranslationRequest):
17
+ generator = stream_translate(req.text)
18
+ return StreamingResponse(generator, media_type="text/plain")
model_loader.py CHANGED
@@ -1,5 +1,10 @@
1
  import torch
2
- from transformers import AutoTokenizer, AutoModelForSeq2SeqLM
 
 
 
 
 
3
 
4
  MODEL_NAME = "facebook/nllb-200-distilled-600M"
5
 
@@ -12,15 +17,48 @@ device = "cuda" if torch.cuda.is_available() else "cpu"
12
  model.to(device)
13
  model.eval()
14
 
 
15
  def translate(text: str):
16
  inputs = tokenizer(text, return_tensors="pt").to(device)
17
 
18
  lang_id = tokenizer.convert_tokens_to_ids("arb_Arab")
19
 
20
- outputs = model.generate(
21
- inputs["input_ids"],
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22
  forced_bos_token_id=lang_id,
23
- max_length=300
 
24
  )
25
 
26
- return tokenizer.decode(outputs[0], skip_special_tokens=True)
 
 
 
 
 
 
 
 
 
 
1
  import torch
2
+ import threading
3
+ from transformers import (
4
+ AutoTokenizer,
5
+ AutoModelForSeq2SeqLM,
6
+ TextIteratorStreamer,
7
+ )
8
 
9
  MODEL_NAME = "facebook/nllb-200-distilled-600M"
10
 
 
17
  model.to(device)
18
  model.eval()
19
 
20
+ # -------- normal (non-streaming) ----------
21
  def translate(text: str):
22
  inputs = tokenizer(text, return_tensors="pt").to(device)
23
 
24
  lang_id = tokenizer.convert_tokens_to_ids("arb_Arab")
25
 
26
+ with torch.no_grad():
27
+ outputs = model.generate(
28
+ inputs["input_ids"],
29
+ forced_bos_token_id=lang_id,
30
+ max_length=300,
31
+ )
32
+
33
+ return tokenizer.decode(outputs[0], skip_special_tokens=True)
34
+
35
+
36
+ # -------- streaming ----------
37
+ def stream_translate(text: str):
38
+ inputs = tokenizer(text, return_tensors="pt").to(device)
39
+
40
+ lang_id = tokenizer.convert_tokens_to_ids("arb_Arab")
41
+
42
+ streamer = TextIteratorStreamer(
43
+ tokenizer,
44
+ skip_special_tokens=True,
45
+ skip_prompt=True,
46
+ )
47
+
48
+ generation_kwargs = dict(
49
+ input_ids=inputs["input_ids"],
50
  forced_bos_token_id=lang_id,
51
+ max_length=300,
52
+ streamer=streamer,
53
  )
54
 
55
+ # Run generation in background thread
56
+ thread = threading.Thread(
57
+ target=model.generate,
58
+ kwargs=generation_kwargs,
59
+ )
60
+ thread.start()
61
+
62
+ # Yield tokens as they are generated
63
+ for token in streamer:
64
+ yield token