Support evaluation-local configuration and names overrides
This commit is contained in:
1 parent
0bb6f7d97c
commit
d4404e4c27
36 files changed
+409
-184
No files matched your search
@@ -41,9 +41,6 @@ from copienator.utils import enonce_total, read_all_labels
|
||||
NB_THREADS = 12
|
||||
|
||||
# PROXY_URL = "http://192.168.241.1:3128"
|
||||
MODEL_ID_pro = config.MODEL_PRO_ID
|
||||
MODEL_ID_flash = config.MODEL_FLASH_ID
|
||||
api_key = config.API_KEY
|
||||
|
||||
# Runtime globals retained while the processing helpers are migrated incrementally.
|
||||
INPUT_DIR = Path()
|
||||
@@ -270,13 +267,18 @@ def reset_workspace(workspace: EvaluationWorkspace) -> None:
|
||||
"_new PDFs from 'Par label'."
|
||||
)
|
||||
|
||||
_DEFAULT_FALLBACK = object()
|
||||
|
||||
|
||||
def call_gemini_with_retries(model_id, contents, config,
|
||||
fallback_model_id=MODEL_ID_flash):
|
||||
fallback_model_id=_DEFAULT_FALLBACK):
|
||||
"""Handles requests to Gemini with a 1min and 5min retry mechanism, and quota fallback."""
|
||||
global pro_quota_exhausted
|
||||
delays = [60, 300]
|
||||
request_seed = None
|
||||
# Own the retries here so the SDK cannot silently resend a fixed seed.
|
||||
if fallback_model_id is _DEFAULT_FALLBACK:
|
||||
fallback_model_id = settings.MODEL_FLASH_ID
|
||||
http_options = config.http_options or types.HttpOptions()
|
||||
config = config.model_copy(update={"http_options": http_options.model_copy(
|
||||
update={"retry_options": types.HttpRetryOptions(attempts=1)}
|
||||
@@ -289,7 +291,7 @@ def call_gemini_with_retries(model_id, contents, config,
|
||||
config = config.model_copy(update={"seed": request_seed})
|
||||
tprint(f"\tGemini attempt {attempt + 1}/3: seed={request_seed}")
|
||||
# Switch to fallback immediately if quota was exhausted by another thread
|
||||
if model_id == MODEL_ID_pro and pro_quota_exhausted and fallback_model_id:
|
||||
if model_id == settings.MODEL_PRO_ID and pro_quota_exhausted and fallback_model_id:
|
||||
model_id = fallback_model_id
|
||||
config = config.model_copy(update={"thinking_config": thinking_config(
|
||||
settings.THINKING_LEVEL_FLASH
|
||||
@@ -324,7 +326,7 @@ def call_gemini_with_retries(model_id, contents, config,
|
||||
continue # Retry same model
|
||||
|
||||
# Immediately fallback to Flash without waiting if it's a Pro quota error
|
||||
if is_quota_error and model_id == MODEL_ID_pro and fallback_model_id:
|
||||
if is_quota_error and model_id == settings.MODEL_PRO_ID and fallback_model_id:
|
||||
tprint(f"\tGemini Pro quota hit ({e}). \n\n\tFalling back to Flash permanently...")
|
||||
model_id = fallback_model_id
|
||||
config = config.model_copy(update={"thinking_config": thinking_config(
|
||||
@@ -347,7 +349,7 @@ def correct_boxes_with_gemini(pid, label, pdf_path, original_feedbacks,
|
||||
# pdf_path = COPIES_DIR / f"Copie{pid}" / f"{label}.pdf"
|
||||
|
||||
contents, config = prompting.request_for_box_correction(pdf_path, original_feedbacks)
|
||||
response_text = call_gemini_with_retries(MODEL_ID_flash, contents, config)
|
||||
response_text = call_gemini_with_retries(settings.MODEL_FLASH_ID, contents, config)
|
||||
corrected_feedbacks = parse_correction_response(response_text)
|
||||
|
||||
global_feedbacks = [f for f in original_feedbacks if not f["box_2d"]]
|
||||
@@ -404,7 +406,7 @@ def handle_label_errors(pid, label, res, pdf_path, *, group_geometry=None):
|
||||
if error_type == "wrong-label":
|
||||
tprint(f"\tHandling wrong-label for {pid} {label}")
|
||||
contents, config = prompting.request_for_wrong_label(pdf_path, label, enonce, labels_txt)
|
||||
new_label = call_gemini_with_retries(MODEL_ID_flash, contents, config).strip().strip('"\'')
|
||||
new_label = call_gemini_with_retries(settings.MODEL_FLASH_ID, contents, config).strip().strip('"\'')
|
||||
if new_label not in all_labels:
|
||||
tprint(f"\t\tCopie{pid} returned an incorrect label {new_label} from an initial wrong label {label}. Ignoring")
|
||||
res["error"] = "wrg-lbl:cldtfix"
|
||||
@@ -413,7 +415,7 @@ def handle_label_errors(pid, label, res, pdf_path, *, group_geometry=None):
|
||||
tprint(f"\t\tLabel confirmed for Copie{pid}: regrading {label}.")
|
||||
contents, config = prompting.request_for_confirmed_label(INPUT_DIR, pdf_path, label, pid)
|
||||
response = parse_correction_response(
|
||||
call_gemini_with_retries(MODEL_ID_flash, contents, config)
|
||||
call_gemini_with_retries(settings.MODEL_FLASH_ID, contents, config)
|
||||
)
|
||||
if not isinstance(response, list) or len(response) != 1 or response[0].get("id") != pid:
|
||||
raise ValueError(f"Confirmed-label regrading must return exactly Copie{pid}")
|
||||
@@ -469,7 +471,7 @@ def handle_label_errors(pid, label, res, pdf_path, *, group_geometry=None):
|
||||
contents, config = prompting.request_for_additional_answer(pdf_path, label, enonce, labels_txt)
|
||||
tprint(f"\tHandling additional-answer for {pid} {label}")
|
||||
try:
|
||||
add_labels = json.loads(call_gemini_with_retries(MODEL_ID_flash, contents, config))
|
||||
add_labels = json.loads(call_gemini_with_retries(settings.MODEL_FLASH_ID, contents, config))
|
||||
except CorrectionStopRequested:
|
||||
raise
|
||||
except Exception: # noqa: BLE001 - invalid auxiliary model response
|
||||
@@ -555,7 +557,7 @@ def process_single_task(task_tuple, precomputed_response=None):
|
||||
thinking_level=(settings.THINKING_LEVEL_FLASH if use_flash
|
||||
else settings.THINKING_LEVEL_PRO),
|
||||
)
|
||||
model_to_use = MODEL_ID_flash if use_flash else MODEL_ID_pro
|
||||
model_to_use = settings.MODEL_FLASH_ID if use_flash else settings.MODEL_PRO_ID
|
||||
|
||||
if precomputed_response:
|
||||
tprint(f"Using saved response for: {label} {group_name}")
|
||||
@@ -810,7 +812,7 @@ def run_configured(args: argparse.Namespace) -> ExitCode:
|
||||
global client, tasks_to_process
|
||||
workers = request_workers(args)
|
||||
if client is None:
|
||||
client = genai.Client(api_key=api_key)
|
||||
client = genai.Client(api_key=settings.API_KEY)
|
||||
if args.refaire:
|
||||
refaire_path = INPUT_DIR / "refaire.json"
|
||||
overwritten_path = INPUT_DIR / "overwritten_correction.json"
|
||||
@@ -979,8 +981,8 @@ def run_configured(args: argparse.Namespace) -> ExitCode:
|
||||
)
|
||||
|
||||
print("Batch generation complete.")
|
||||
print(f" - {count_flash} requests saved to {batch_flash_file} (for {MODEL_ID_flash})")
|
||||
print(f" - {count_pro} requests saved to {batch_pro_file} (for {MODEL_ID_pro})")
|
||||
print(f" - {count_flash} requests saved to {batch_flash_file} (for {settings.MODEL_FLASH_ID})")
|
||||
print(f" - {count_pro} requests saved to {batch_pro_file} (for {settings.MODEL_PRO_ID})")
|
||||
print("Upload these files via the File API and create two separate batch jobs.")
|
||||
|
||||
# If there's no live tasks to do, and we aren't doing a batched ingestion, exit right away
|
||||
|
||||
Reference in new issue
Block a user