Skip to content

Commit 619ed3c

Browse files
committed
hot fix fast mode
1 parent a56af9d commit 619ed3c

File tree

10 files changed

+385
-64
lines changed

10 files changed

+385
-64
lines changed

.env.example

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ OPENROUTER_MODEL=anthropic/claude-sonnet-4
2626
# Translation Settings
2727
DEFAULT_SOURCE_LANGUAGE=English # Default source language (can be any language name)
2828
DEFAULT_TARGET_LANGUAGE=Chinese # Default target language (can be any language name)
29-
MAIN_LINES_PER_CHUNK=25 # Target lines per chunk (may be auto-adjusted)
29+
MAIN_LINES_PER_CHUNK=50 # Target lines per chunk (may be auto-adjusted)
3030
MAIN_CHUNK_SIZE=1000 # Maximum characters per chunk
3131
REQUEST_TIMEOUT=900 # API timeout in seconds
3232

@@ -59,7 +59,7 @@ SIGNATURE_ENABLED=true
5959
# Images are inserted between paragraphs at their original positions.
6060
# Set to 'false' to strip all images (reduces output file size).
6161
# Can also be disabled via CLI with --no-images flag.
62-
FAST_MODE_PRESERVE_IMAGES=true
62+
FAST_MODE_PRESERVE_IMAGES=false
6363

6464
# Debug Mode
6565
# Enable verbose logging for troubleshooting configuration and connection issues.

benchmark/cli.py

Lines changed: 115 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
from benchmark.runner import BenchmarkRunner, quick_benchmark, full_benchmark
1717
from benchmark.results.storage import ResultsStorage
1818
from benchmark.wiki.generator import WikiGenerator
19-
from benchmark.translator import get_available_ollama_models
19+
from benchmark.translator import get_available_ollama_models, get_available_openrouter_models
2020

2121

2222
# ANSI color codes for terminal output
@@ -68,11 +68,15 @@ def cmd_run(args: argparse.Namespace) -> int:
6868
"""Execute benchmark run command."""
6969
print_banner()
7070

71+
# Determine provider
72+
provider = getattr(args, 'provider', 'ollama') or 'ollama'
73+
7174
# Build configuration
7275
config = BenchmarkConfig.from_cli_args(
7376
openrouter_key=args.openrouter_key,
7477
evaluator_model=args.evaluator,
7578
ollama_endpoint=args.ollama_endpoint,
79+
translation_provider=provider,
7680
)
7781

7882
# Validate configuration
@@ -82,15 +86,28 @@ def cmd_run(args: argparse.Namespace) -> int:
8286
log_callback("error", error)
8387
return 1
8488

85-
# Get models
89+
# Get models based on provider
8690
models = args.models
8791
if not models:
88-
print(colored("Detecting available Ollama models...", Colors.CYAN))
89-
models = asyncio.run(get_available_ollama_models(config))
90-
if not models:
91-
log_callback("error", "No Ollama models found. Run 'ollama pull <model>' first.")
92-
return 1
93-
print(colored(f"Found {len(models)} models: {', '.join(models[:5])}...", Colors.GREEN))
92+
if provider == "openrouter":
93+
print(colored("Fetching available OpenRouter models...", Colors.CYAN))
94+
models_data = asyncio.run(get_available_openrouter_models(config))
95+
if not models_data:
96+
log_callback("error", "No OpenRouter models available.")
97+
return 1
98+
# Extract model IDs
99+
models = [m["id"] if isinstance(m, dict) else m for m in models_data[:10]]
100+
print(colored(f"Found {len(models_data)} models. Using top 10: {', '.join(models[:3])}...", Colors.GREEN))
101+
else:
102+
print(colored("Detecting available Ollama models...", Colors.CYAN))
103+
models = asyncio.run(get_available_ollama_models(config))
104+
if not models:
105+
log_callback("error", "No Ollama models found. Run 'ollama pull <model>' first.")
106+
return 1
107+
print(colored(f"Found {len(models)} models: {', '.join(models[:5])}...", Colors.GREEN))
108+
109+
# Show provider info
110+
print(colored(f"Translation provider: {provider.upper()}", Colors.YELLOW))
94111

95112
# Determine languages
96113
if args.full:
@@ -264,6 +281,63 @@ def cmd_export(args: argparse.Namespace) -> int:
264281
return 1
265282

266283

284+
def cmd_models(args: argparse.Namespace) -> int:
285+
"""List available models for benchmarking."""
286+
print_banner()
287+
288+
config = BenchmarkConfig.from_cli_args(openrouter_key=args.openrouter_key)
289+
provider = args.provider
290+
291+
if provider == "openrouter":
292+
print(colored("Fetching OpenRouter models...\n", Colors.CYAN))
293+
models = asyncio.run(get_available_openrouter_models(config))
294+
295+
if not models:
296+
log_callback("error", "Failed to fetch OpenRouter models")
297+
return 1
298+
299+
print(colored(f"Available OpenRouter Models ({len(models)} text-only models):\n", Colors.BOLD))
300+
301+
# Table header
302+
print(f"{'Model ID':<50} {'Price (per 1M tokens)':<25}")
303+
print("-" * 75)
304+
305+
for model in models[:50]: # Limit to 50 for readability
306+
if isinstance(model, dict):
307+
model_id = model.get("id", "unknown")
308+
pricing = model.get("pricing", {})
309+
prompt_price = pricing.get("prompt_per_million", 0)
310+
completion_price = pricing.get("completion_per_million", 0)
311+
price_str = f"${prompt_price:.2f} / ${completion_price:.2f}"
312+
else:
313+
model_id = model
314+
price_str = "N/A"
315+
316+
print(f"{model_id:<50} {price_str:<25}")
317+
318+
print()
319+
print(colored("Tip: Use -m to specify models, e.g.:", Colors.YELLOW))
320+
print(" python -m benchmark.cli run -p openrouter -m anthropic/claude-sonnet-4 openai/gpt-4o")
321+
322+
else:
323+
print(colored("Detecting Ollama models...\n", Colors.CYAN))
324+
models = asyncio.run(get_available_ollama_models(config))
325+
326+
if not models:
327+
log_callback("error", "No Ollama models found. Is Ollama running? Try 'ollama pull <model>'")
328+
return 1
329+
330+
print(colored(f"Available Ollama Models ({len(models)}):\n", Colors.BOLD))
331+
for model in models:
332+
print(f" - {model}")
333+
334+
print()
335+
print(colored("Tip: Use -m to specify models, e.g.:", Colors.YELLOW))
336+
print(" python -m benchmark.cli run -m llama3:8b qwen2.5:14b")
337+
338+
return 0
339+
340+
267341
def cmd_delete(args: argparse.Namespace) -> int:
268342
"""Delete a benchmark run."""
269343
config = BenchmarkConfig()
@@ -489,15 +563,21 @@ def create_parser() -> argparse.ArgumentParser:
489563
formatter_class=argparse.RawDescriptionHelpFormatter,
490564
epilog="""
491565
Examples:
492-
# Quick benchmark (7 test languages)
566+
# Quick benchmark with Ollama (local models)
493567
python -m benchmark.cli run --openrouter-key YOUR_KEY
494568
569+
# Quick benchmark with OpenRouter (cloud models)
570+
python -m benchmark.cli run --provider openrouter --openrouter-key YOUR_KEY
571+
495572
# Full benchmark (all 40+ languages)
496573
python -m benchmark.cli run --full --openrouter-key YOUR_KEY
497574
498-
# Specific models and languages
575+
# Specific Ollama models and languages
499576
python -m benchmark.cli run -m llama3:8b qwen2.5:14b -l fr de ja zh
500577
578+
# Specific OpenRouter models
579+
python -m benchmark.cli run -p openrouter -m anthropic/claude-sonnet-4 openai/gpt-4o -l fr de ja
580+
501581
# Generate wiki pages
502582
python -m benchmark.cli wiki
503583
@@ -513,7 +593,9 @@ def create_parser() -> argparse.ArgumentParser:
513593
run_parser.add_argument(
514594
"-m", "--models",
515595
nargs="+",
516-
help="Ollama models to benchmark. If not specified, uses all available models."
596+
help="Models to benchmark. For Ollama: model names (e.g., llama3:8b). "
597+
"For OpenRouter: model IDs (e.g., anthropic/claude-sonnet-4). "
598+
"If not specified, auto-detects available models."
517599
)
518600
run_parser.add_argument(
519601
"-l", "--languages",
@@ -525,9 +607,16 @@ def create_parser() -> argparse.ArgumentParser:
525607
action="store_true",
526608
help="Run full benchmark with all 40+ languages"
527609
)
610+
run_parser.add_argument(
611+
"-p", "--provider",
612+
choices=["ollama", "openrouter"],
613+
default="ollama",
614+
help="Translation provider: 'ollama' (local, default) or 'openrouter' (cloud, 200+ models)"
615+
)
528616
run_parser.add_argument(
529617
"--openrouter-key",
530-
help="OpenRouter API key for evaluation. Can also be set via OPENROUTER_API_KEY env var."
618+
help="OpenRouter API key (for evaluation, and translation if using --provider openrouter). "
619+
"Can also be set via OPENROUTER_API_KEY env var."
531620
)
532621
run_parser.add_argument(
533622
"--evaluator",
@@ -591,6 +680,20 @@ def create_parser() -> argparse.ArgumentParser:
591680
list_parser = subparsers.add_parser("list", help="List available benchmark runs")
592681
list_parser.set_defaults(func=cmd_list)
593682

683+
# Models command
684+
models_parser = subparsers.add_parser("models", help="List available models for benchmarking")
685+
models_parser.add_argument(
686+
"-p", "--provider",
687+
choices=["ollama", "openrouter"],
688+
default="ollama",
689+
help="Provider to list models for (default: ollama)"
690+
)
691+
models_parser.add_argument(
692+
"--openrouter-key",
693+
help="OpenRouter API key (required for listing OpenRouter models)"
694+
)
695+
models_parser.set_defaults(func=cmd_models)
696+
594697
# Show command
595698
show_parser = subparsers.add_parser("show", help="Show details of a benchmark run")
596699
show_parser.add_argument("run_id", help="Run ID to show")

benchmark/config.py

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,9 @@ class BenchmarkConfig:
143143
source_language: str = "English"
144144
quick_languages: list = field(default_factory=lambda: DEFAULT_QUICK_LANGUAGES.copy())
145145

146+
# Translation provider ("ollama" or "openrouter")
147+
translation_provider: str = "ollama"
148+
146149
# Retry settings
147150
max_retries: int = 3
148151
retry_delay: float = 2.0
@@ -158,6 +161,7 @@ def from_cli_args(
158161
openrouter_key: Optional[str] = None,
159162
evaluator_model: Optional[str] = None,
160163
ollama_endpoint: Optional[str] = None,
164+
translation_provider: Optional[str] = None,
161165
**kwargs
162166
) -> "BenchmarkConfig":
163167
"""Create configuration from CLI arguments with env fallbacks."""
@@ -172,24 +176,39 @@ def from_cli_args(
172176
if ollama_endpoint:
173177
config.ollama.endpoint = ollama_endpoint
174178

179+
if translation_provider:
180+
config.translation_provider = translation_provider.lower()
181+
175182
return config
176183

177184
def validate(self) -> list[str]:
178185
"""Validate configuration and return list of errors."""
179186
errors = []
180187

188+
# OpenRouter API key is required for evaluation (always)
189+
# and for translation if using OpenRouter provider
181190
if not self.openrouter.api_key:
182-
errors.append(
183-
"OpenRouter API key not configured. "
184-
"Set OPENROUTER_API_KEY in .env or use --openrouter-key"
185-
)
191+
if self.translation_provider == "openrouter":
192+
errors.append(
193+
"OpenRouter API key not configured. Required for both translation and evaluation. "
194+
"Set OPENROUTER_API_KEY in .env or use --openrouter-key"
195+
)
196+
else:
197+
errors.append(
198+
"OpenRouter API key not configured. Required for evaluation. "
199+
"Set OPENROUTER_API_KEY in .env or use --openrouter-key"
200+
)
186201

187202
if not self.paths.languages_file.exists():
188203
errors.append(f"Languages file not found: {self.paths.languages_file}")
189204

190205
if not self.paths.reference_texts_file.exists():
191206
errors.append(f"Reference texts file not found: {self.paths.reference_texts_file}")
192207

208+
# Validate translation provider
209+
if self.translation_provider not in ("ollama", "openrouter"):
210+
errors.append(f"Invalid translation provider: {self.translation_provider}. Must be 'ollama' or 'openrouter'")
211+
193212
return errors
194213

195214

benchmark/runner.py

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@
2424
)
2525
from benchmark.translator import (
2626
BenchmarkTranslator, TranslationRequest,
27-
test_ollama_connection, get_available_ollama_models
27+
test_ollama_connection, get_available_ollama_models,
28+
test_openrouter_translation_connection, get_available_openrouter_models
2829
)
2930
from benchmark.evaluator import (
3031
TranslationEvaluator, test_openrouter_connection
@@ -197,19 +198,28 @@ async def validate_setup(self) -> tuple[bool, list[str]]:
197198
config_errors = self.config.validate()
198199
errors.extend(config_errors)
199200

200-
# Test Ollama connection
201-
ollama_ok, ollama_msg = await test_ollama_connection(self.config)
202-
if not ollama_ok:
203-
errors.append(f"Ollama: {ollama_msg}")
201+
# Test translation provider connection
202+
if self.config.translation_provider == "openrouter":
203+
# Test OpenRouter for translation
204+
or_trans_ok, or_trans_msg = await test_openrouter_translation_connection(self.config)
205+
if not or_trans_ok:
206+
errors.append(f"OpenRouter (translation): {or_trans_msg}")
207+
else:
208+
self._log("info", f"OpenRouter (translation): {or_trans_msg}")
204209
else:
205-
self._log("info", f"Ollama: {ollama_msg}")
206-
207-
# Test OpenRouter connection
210+
# Test Ollama connection
211+
ollama_ok, ollama_msg = await test_ollama_connection(self.config)
212+
if not ollama_ok:
213+
errors.append(f"Ollama: {ollama_msg}")
214+
else:
215+
self._log("info", f"Ollama: {ollama_msg}")
216+
217+
# Test OpenRouter connection (for evaluation - always required)
208218
openrouter_ok, openrouter_msg = await test_openrouter_connection(self.config)
209219
if not openrouter_ok:
210-
errors.append(f"OpenRouter: {openrouter_msg}")
220+
errors.append(f"OpenRouter (evaluation): {openrouter_msg}")
211221
else:
212-
self._log("info", f"OpenRouter: {openrouter_msg}")
222+
self._log("info", f"OpenRouter (evaluation): {openrouter_msg}")
213223

214224
return len(errors) == 0, errors
215225

@@ -310,7 +320,11 @@ async def run(
310320
self._log("info", f"Total translations: {run.total_expected}")
311321

312322
# Initialize translator and evaluator
313-
self._translator = BenchmarkTranslator(self.config, self.log_callback)
323+
self._translator = BenchmarkTranslator(
324+
self.config,
325+
self.log_callback,
326+
provider_type=self.config.translation_provider
327+
)
314328
self._evaluator = TranslationEvaluator(self.config, self.log_callback)
315329

316330
try:

0 commit comments

Comments
 (0)