Spaces:
Running on Zero
Running on Zero
abinjoyal commited on
Commit ·
2ef1343
1
Parent(s): c5160ee
feat: enhance LocalNMTService to set target language and log sample outputs in TranslationService
Browse files
services/local_nmt_service.py
CHANGED
|
@@ -178,6 +178,8 @@ class LocalNMTService:
|
|
| 178 |
"""Runs a small mini-batch chunk on GPU using standard NLLB parameters."""
|
| 179 |
if hasattr(self.tokenizer, "src_lang"):
|
| 180 |
self.tokenizer.src_lang = src_code
|
|
|
|
|
|
|
| 181 |
|
| 182 |
# If on ZeroGPU and CUDA is now available, ensure model parameters are on CUDA
|
| 183 |
if torch.cuda.is_available() and self.model:
|
|
@@ -193,17 +195,25 @@ class LocalNMTService:
|
|
| 193 |
input_ids = inputs["input_ids"].to(target_device)
|
| 194 |
attention_mask = inputs["attention_mask"].to(target_device)
|
| 195 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 196 |
gen_kwargs = {
|
| 197 |
"input_ids": input_ids,
|
| 198 |
"attention_mask": attention_mask,
|
| 199 |
"max_new_tokens": 256,
|
| 200 |
"num_beams": 4,
|
| 201 |
-
"no_repeat_ngram_size": 3,
|
| 202 |
-
"repetition_penalty": 1.15,
|
| 203 |
"early_stopping": True
|
| 204 |
}
|
| 205 |
-
if
|
| 206 |
-
gen_kwargs["forced_bos_token_id"] =
|
| 207 |
|
| 208 |
with torch.no_grad():
|
| 209 |
generated_tokens = self.model.generate(**gen_kwargs)
|
|
@@ -243,7 +253,8 @@ class LocalNMTService:
|
|
| 243 |
# Process this small chunk safely within ZeroGPU decorator limit
|
| 244 |
chunk_outputs = self._generate_chunk_on_gpu(batch_chunk, src_code, tgt_code, forced_bos_id)
|
| 245 |
chunk_dur = time.time() - chunk_start
|
| 246 |
-
|
|
|
|
| 247 |
results.extend(chunk_outputs)
|
| 248 |
except Exception as chunk_err:
|
| 249 |
logger.warning(f"NLLB Batch chunk [{i}:{i+len(chunk)}] failed: {chunk_err}. Filling with None for controlled fallback.")
|
|
|
|
| 178 |
"""Runs a small mini-batch chunk on GPU using standard NLLB parameters."""
|
| 179 |
if hasattr(self.tokenizer, "src_lang"):
|
| 180 |
self.tokenizer.src_lang = src_code
|
| 181 |
+
if hasattr(self.tokenizer, "tgt_lang"):
|
| 182 |
+
self.tokenizer.tgt_lang = tgt_code
|
| 183 |
|
| 184 |
# If on ZeroGPU and CUDA is now available, ensure model parameters are on CUDA
|
| 185 |
if torch.cuda.is_available() and self.model:
|
|
|
|
| 195 |
input_ids = inputs["input_ids"].to(target_device)
|
| 196 |
attention_mask = inputs["attention_mask"].to(target_device)
|
| 197 |
|
| 198 |
+
# Retrieve exact target language token ID for decoder
|
| 199 |
+
target_bos = None
|
| 200 |
+
if hasattr(self.tokenizer, "convert_tokens_to_ids"):
|
| 201 |
+
try:
|
| 202 |
+
target_bos = self.tokenizer.convert_tokens_to_ids(tgt_code)
|
| 203 |
+
except Exception:
|
| 204 |
+
pass
|
| 205 |
+
if target_bos is None or target_bos < 0:
|
| 206 |
+
target_bos = forced_bos_id
|
| 207 |
+
|
| 208 |
gen_kwargs = {
|
| 209 |
"input_ids": input_ids,
|
| 210 |
"attention_mask": attention_mask,
|
| 211 |
"max_new_tokens": 256,
|
| 212 |
"num_beams": 4,
|
|
|
|
|
|
|
| 213 |
"early_stopping": True
|
| 214 |
}
|
| 215 |
+
if target_bos is not None:
|
| 216 |
+
gen_kwargs["forced_bos_token_id"] = target_bos
|
| 217 |
|
| 218 |
with torch.no_grad():
|
| 219 |
generated_tokens = self.model.generate(**gen_kwargs)
|
|
|
|
| 253 |
# Process this small chunk safely within ZeroGPU decorator limit
|
| 254 |
chunk_outputs = self._generate_chunk_on_gpu(batch_chunk, src_code, tgt_code, forced_bos_id)
|
| 255 |
chunk_dur = time.time() - chunk_start
|
| 256 |
+
sample_txt = chunk_outputs[0] if chunk_outputs else ""
|
| 257 |
+
logger.info(f"NLLB Batch chunk [{i}:{i+len(chunk)}] translated {len(chunk_outputs)} items in {chunk_dur:.2f}s. Sample: '{sample_txt[:70]}'")
|
| 258 |
results.extend(chunk_outputs)
|
| 259 |
except Exception as chunk_err:
|
| 260 |
logger.warning(f"NLLB Batch chunk [{i}:{i+len(chunk)}] failed: {chunk_err}. Filling with None for controlled fallback.")
|
services/translation_service.py
CHANGED
|
@@ -392,13 +392,18 @@ class TranslationService:
|
|
| 392 |
t_nmt = time.time()
|
| 393 |
batch_outputs = local_nmt_service.translate_batch(batch_texts, target_lang=target_lang)
|
| 394 |
dur_nmt = time.time() - t_nmt
|
|
|
|
|
|
|
| 395 |
for f_idx, out in zip(uncached_indices, batch_outputs):
|
| 396 |
-
|
|
|
|
| 397 |
cleaned_t = sanitize_translation_text(out)
|
| 398 |
raw_translations[f_idx] = cleaned_t
|
| 399 |
self._cache[f"{target_lang}:{merged_texts[f_idx].strip().lower()}"] = cleaned_t
|
| 400 |
provider_stats["local_nmt"] += 1
|
| 401 |
provider_timing["local_nmt"] += (dur_nmt / max(1, len(uncached_indices)))
|
|
|
|
|
|
|
| 402 |
except Exception as nmt_err:
|
| 403 |
logger.warning(f"Local NMT batch notice: {nmt_err}")
|
| 404 |
|
|
|
|
| 392 |
t_nmt = time.time()
|
| 393 |
batch_outputs = local_nmt_service.translate_batch(batch_texts, target_lang=target_lang)
|
| 394 |
dur_nmt = time.time() - t_nmt
|
| 395 |
+
if batch_outputs and len(batch_outputs) > 0 and batch_outputs[0]:
|
| 396 |
+
logger.info(f"🔍 NLLB Sample Output [0]: '{batch_outputs[0][:80]}'")
|
| 397 |
for f_idx, out in zip(uncached_indices, batch_outputs):
|
| 398 |
+
is_valid = contains_target_script(out, target_lang) if out else False
|
| 399 |
+
if is_valid:
|
| 400 |
cleaned_t = sanitize_translation_text(out)
|
| 401 |
raw_translations[f_idx] = cleaned_t
|
| 402 |
self._cache[f"{target_lang}:{merged_texts[f_idx].strip().lower()}"] = cleaned_t
|
| 403 |
provider_stats["local_nmt"] += 1
|
| 404 |
provider_timing["local_nmt"] += (dur_nmt / max(1, len(uncached_indices)))
|
| 405 |
+
else:
|
| 406 |
+
logger.warning(f"⚠️ NLLB output rejected for group [{f_idx}]: text='{out[:60] if out else '<empty/None>'}'")
|
| 407 |
except Exception as nmt_err:
|
| 408 |
logger.warning(f"Local NMT batch notice: {nmt_err}")
|
| 409 |
|