mt-eval-harness 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- mt_eval_harness/__init__.py +99 -0
- mt_eval_harness/__main__.py +6 -0
- mt_eval_harness/_dashboard_charts.py +148 -0
- mt_eval_harness/_dashboard_css.py +657 -0
- mt_eval_harness/_dashboard_js.py +462 -0
- mt_eval_harness/airgap_transport.py +832 -0
- mt_eval_harness/api.py +671 -0
- mt_eval_harness/auth.py +453 -0
- mt_eval_harness/cache.py +200 -0
- mt_eval_harness/card_reader.py +200 -0
- mt_eval_harness/champollion_config.py +516 -0
- mt_eval_harness/cli.py +3095 -0
- mt_eval_harness/compare.py +308 -0
- mt_eval_harness/confidence.py +499 -0
- mt_eval_harness/config.py +1499 -0
- mt_eval_harness/config_exporter.py +418 -0
- mt_eval_harness/connection_quality.py +596 -0
- mt_eval_harness/contamination.py +130 -0
- mt_eval_harness/contest.py +556 -0
- mt_eval_harness/contest_intake.py +380 -0
- mt_eval_harness/contest_node.py +831 -0
- mt_eval_harness/contest_prep.py +629 -0
- mt_eval_harness/corpora_browse.py +209 -0
- mt_eval_harness/corpus_build/__init__.py +35 -0
- mt_eval_harness/corpus_build/adapters/__init__.py +18 -0
- mt_eval_harness/corpus_build/adapters/alt_adapter.py +367 -0
- mt_eval_harness/corpus_build/adapters/americasnlp_adapter.py +86 -0
- mt_eval_harness/corpus_build/adapters/arabench_adapter.py +338 -0
- mt_eval_harness/corpus_build/adapters/base.py +148 -0
- mt_eval_harness/corpus_build/adapters/bouquet_adapter.py +352 -0
- mt_eval_harness/corpus_build/adapters/edtekla_adapter.py +604 -0
- mt_eval_harness/corpus_build/adapters/globalvoices_adapter.py +274 -0
- mt_eval_harness/corpus_build/adapters/in22_adapter.py +283 -0
- mt_eval_harness/corpus_build/adapters/lineparallel_adapter.py +489 -0
- mt_eval_harness/corpus_build/adapters/opus_adapter.py +406 -0
- mt_eval_harness/corpus_build/adapters/smol_adapter.py +295 -0
- mt_eval_harness/corpus_build/adapters/tatoeba_adapter.py +698 -0
- mt_eval_harness/corpus_build/adapters/tatoeba_api_adapter.py +220 -0
- mt_eval_harness/corpus_build/adapters/tatoeba_challenge_adapter.py +612 -0
- mt_eval_harness/corpus_build/adapters/tatoeba_opus_adapter.py +430 -0
- mt_eval_harness/corpus_build/adapters/tico19_adapter.py +278 -0
- mt_eval_harness/corpus_build/adapters/turkicxwmt_adapter.py +274 -0
- mt_eval_harness/corpus_build/adapters/wmt24pp_adapter.py +277 -0
- mt_eval_harness/corpus_build/adapters/wmt_general_adapter.py +257 -0
- mt_eval_harness/corpus_build/difficulty_estimator.py +240 -0
- mt_eval_harness/corpus_build/domain_classifier.py +303 -0
- mt_eval_harness/corpus_build/hf_download.py +361 -0
- mt_eval_harness/corpus_build/licensing.py +152 -0
- mt_eval_harness/corpus_build/sampling.py +186 -0
- mt_eval_harness/corpus_build/schema.py +238 -0
- mt_eval_harness/corpus_fetch.py +1450 -0
- mt_eval_harness/corpus_loader.py +566 -0
- mt_eval_harness/dashboard.py +296 -0
- mt_eval_harness/data/registry.json +345199 -0
- mt_eval_harness/exporter.py +453 -0
- mt_eval_harness/external_scoring.py +543 -0
- mt_eval_harness/interactive.py +364 -0
- mt_eval_harness/language_cards.py +1486 -0
- mt_eval_harness/language_cards_remote.py +203 -0
- mt_eval_harness/license_use.py +328 -0
- mt_eval_harness/method_bundle.py +653 -0
- mt_eval_harness/method_card_wizard.py +179 -0
- mt_eval_harness/method_loader.py +188 -0
- mt_eval_harness/method_manifest.py +72 -0
- mt_eval_harness/methods/__init__.py +68 -0
- mt_eval_harness/methods/amazon_translate.py +122 -0
- mt_eval_harness/methods/apertium.py +135 -0
- mt_eval_harness/methods/base_http_mt.py +411 -0
- mt_eval_harness/methods/deepl.py +133 -0
- mt_eval_harness/methods/google_translate.py +141 -0
- mt_eval_harness/methods/libretranslate.py +151 -0
- mt_eval_harness/methods/local_model.py +353 -0
- mt_eval_harness/methods/microsoft_translator.py +191 -0
- mt_eval_harness/methods/registry.py +71 -0
- mt_eval_harness/methods/tilde.py +122 -0
- mt_eval_harness/methods/translated.py +123 -0
- mt_eval_harness/metric_manifest.py +92 -0
- mt_eval_harness/metrics_comet.py +384 -0
- mt_eval_harness/metrics_fuse.py +162 -0
- mt_eval_harness/metrics_metricx.py +367 -0
- mt_eval_harness/model_bundle.py +472 -0
- mt_eval_harness/model_runner.py +647 -0
- mt_eval_harness/net_json.py +72 -0
- mt_eval_harness/pipeline.py +274 -0
- mt_eval_harness/plugin_discovery.py +819 -0
- mt_eval_harness/plugins/__init__.py +9 -0
- mt_eval_harness/plugins/champollion_prompts.py +93 -0
- mt_eval_harness/plugins/code_switching.py +342 -0
- mt_eval_harness/plugins/double_pass_compliance.py +129 -0
- mt_eval_harness/plugins/fst_installer.py +825 -0
- mt_eval_harness/plugins/giellalt_fst.py +351 -0
- mt_eval_harness/plugins/hallucination.py +343 -0
- mt_eval_harness/plugins/hooks.py +59 -0
- mt_eval_harness/plugins/igt_gloss.py +173 -0
- mt_eval_harness/plugins/metrics.py +72 -0
- mt_eval_harness/plugins/morph_segmentation.py +101 -0
- mt_eval_harness/plugins/prompts.py +54 -0
- mt_eval_harness/plugins/terminology.py +198 -0
- mt_eval_harness/plugins/tools.py +71 -0
- mt_eval_harness/plugins/writing_style.py +400 -0
- mt_eval_harness/power.py +318 -0
- mt_eval_harness/providers/__init__.py +28 -0
- mt_eval_harness/providers/anthropic_provider.py +294 -0
- mt_eval_harness/providers/base.py +106 -0
- mt_eval_harness/providers/gemini_provider.py +302 -0
- mt_eval_harness/providers/local_provider.py +98 -0
- mt_eval_harness/providers/openai_provider.py +276 -0
- mt_eval_harness/providers/openrouter.py +73 -0
- mt_eval_harness/providers/registry.py +102 -0
- mt_eval_harness/publish.py +3158 -0
- mt_eval_harness/qualifier_gate.py +181 -0
- mt_eval_harness/queue_runner.py +2215 -0
- mt_eval_harness/recommend.py +512 -0
- mt_eval_harness/reputation.py +492 -0
- mt_eval_harness/run_card.py +440 -0
- mt_eval_harness/runner.py +968 -0
- mt_eval_harness/sandbox_runner.py +1021 -0
- mt_eval_harness/scoring.py +473 -0
- mt_eval_harness/setup_wizard.py +611 -0
- mt_eval_harness/shared_task.py +111 -0
- mt_eval_harness/significance.py +678 -0
- mt_eval_harness/sovereign/__init__.py +44 -0
- mt_eval_harness/sovereign/airgap_ops.py +406 -0
- mt_eval_harness/sovereign/ceremony.py +524 -0
- mt_eval_harness/sovereign/local_ledger.py +307 -0
- mt_eval_harness/sovereign/score_manifest.py +194 -0
- mt_eval_harness/sovereign/sealed_run.py +231 -0
- mt_eval_harness/sovereign/secret_buffer.py +119 -0
- mt_eval_harness/sovereign/shamir_gf256.py +206 -0
- mt_eval_harness/sovereign/threshold_seal.py +436 -0
- mt_eval_harness/sovereign_service.py +138 -0
- mt_eval_harness/strategies/__init__.py +97 -0
- mt_eval_harness/strategies/batch.py +233 -0
- mt_eval_harness/strategies/method_strategy.py +60 -0
- mt_eval_harness/strategies/plugin_process.py +10 -0
- mt_eval_harness/strategies/single.py +129 -0
- mt_eval_harness/strategies/tool_call.py +238 -0
- mt_eval_harness/tester.py +1090 -0
- mt_eval_harness/transmission_policy.py +392 -0
- mt_eval_harness/verifier.py +1285 -0
- mt_eval_harness/watch.py +122 -0
- mt_eval_harness-0.1.0.dist-info/METADATA +408 -0
- mt_eval_harness-0.1.0.dist-info/RECORD +148 -0
- mt_eval_harness-0.1.0.dist-info/WHEEL +5 -0
- mt_eval_harness-0.1.0.dist-info/entry_points.txt +3 -0
- mt_eval_harness-0.1.0.dist-info/licenses/LICENSE +661 -0
- mt_eval_harness-0.1.0.dist-info/licenses/LICENSE-EXCEPTION.md +53 -0
- mt_eval_harness-0.1.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
"""
|
|
2
|
+
mt-eval — A configurable, language-agnostic evaluation
|
|
3
|
+
harness for machine translation pipelines.
|
|
4
|
+
|
|
5
|
+
Two-component architecture:
|
|
6
|
+
Run Harness: Executes translation experiments with configurable
|
|
7
|
+
model, prompt, tools, batching, and caching.
|
|
8
|
+
Test Harness: Analyzes run results offline with deterministic
|
|
9
|
+
linguistic metrics (chrF++, BLEU, COMET, exact match),
|
|
10
|
+
bootstrap confidence intervals, significance testing,
|
|
11
|
+
and extensible plugin metrics.
|
|
12
|
+
|
|
13
|
+
Any translation method can plug into the harness for regularized,
|
|
14
|
+
apple-to-apple comparison. See GUIDE.md for full documentation.
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
__version__ = "0.1.0"
|
|
18
|
+
|
|
19
|
+
# Public API — importable from the top-level package
|
|
20
|
+
from mt_eval_harness.config import (
|
|
21
|
+
RunConfig,
|
|
22
|
+
load_registry,
|
|
23
|
+
resolve_dataset,
|
|
24
|
+
load_method_card,
|
|
25
|
+
validate_method_card,
|
|
26
|
+
)
|
|
27
|
+
from mt_eval_harness.exporter import ExportConfig, export_plugin
|
|
28
|
+
from mt_eval_harness.corpus_loader import load_corpus
|
|
29
|
+
from mt_eval_harness.champollion_config import (
|
|
30
|
+
ChampollionRunConfig,
|
|
31
|
+
ChampollionPromptConfig, # Back-compat alias for ChampollionRunConfig
|
|
32
|
+
load_champollion_config,
|
|
33
|
+
build_champollion_system_prompt,
|
|
34
|
+
)
|
|
35
|
+
from mt_eval_harness.plugins.metrics import MetricPlugin
|
|
36
|
+
from mt_eval_harness.plugins.prompts import PromptProvider
|
|
37
|
+
from mt_eval_harness.plugins.champollion_prompts import ChampollionPromptProvider
|
|
38
|
+
from mt_eval_harness.plugins.hooks import PostTranslationHook
|
|
39
|
+
from mt_eval_harness.plugins.tools import ToolProvider
|
|
40
|
+
from mt_eval_harness.significance import (
|
|
41
|
+
SignificanceResult,
|
|
42
|
+
paired_bootstrap,
|
|
43
|
+
paired_approximate_randomization,
|
|
44
|
+
)
|
|
45
|
+
from mt_eval_harness.confidence import ConfidenceInterval, bootstrap_ci, compute_all_cis
|
|
46
|
+
from mt_eval_harness.metrics_comet import (
|
|
47
|
+
HAS_COMET,
|
|
48
|
+
COMETResult,
|
|
49
|
+
compute_comet,
|
|
50
|
+
corpus_comet,
|
|
51
|
+
DEFAULT_COMET_MODEL,
|
|
52
|
+
resolve_comet_model,
|
|
53
|
+
)
|
|
54
|
+
from mt_eval_harness.metrics_metricx import (
|
|
55
|
+
HAS_METRICX,
|
|
56
|
+
MetricXResult,
|
|
57
|
+
compute_metricx,
|
|
58
|
+
corpus_metricx,
|
|
59
|
+
DEFAULT_METRICX_MODEL,
|
|
60
|
+
METRICX_LOWER_IS_BETTER,
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
__all__ = [
|
|
64
|
+
"RunConfig",
|
|
65
|
+
"ExportConfig",
|
|
66
|
+
"export_plugin",
|
|
67
|
+
"load_corpus",
|
|
68
|
+
"ChampollionRunConfig",
|
|
69
|
+
"ChampollionPromptConfig", # Back-compat alias
|
|
70
|
+
"load_champollion_config",
|
|
71
|
+
"build_champollion_system_prompt",
|
|
72
|
+
"ChampollionPromptProvider",
|
|
73
|
+
"MetricPlugin",
|
|
74
|
+
"PromptProvider",
|
|
75
|
+
"PostTranslationHook",
|
|
76
|
+
"ToolProvider",
|
|
77
|
+
"SignificanceResult",
|
|
78
|
+
"paired_bootstrap",
|
|
79
|
+
"paired_approximate_randomization",
|
|
80
|
+
"ConfidenceInterval",
|
|
81
|
+
"bootstrap_ci",
|
|
82
|
+
"compute_all_cis",
|
|
83
|
+
"HAS_COMET",
|
|
84
|
+
"COMETResult",
|
|
85
|
+
"compute_comet",
|
|
86
|
+
"corpus_comet",
|
|
87
|
+
"DEFAULT_COMET_MODEL",
|
|
88
|
+
"resolve_comet_model",
|
|
89
|
+
"HAS_METRICX",
|
|
90
|
+
"MetricXResult",
|
|
91
|
+
"compute_metricx",
|
|
92
|
+
"corpus_metricx",
|
|
93
|
+
"DEFAULT_METRICX_MODEL",
|
|
94
|
+
"METRICX_LOWER_IS_BETTER",
|
|
95
|
+
"load_registry",
|
|
96
|
+
"resolve_dataset",
|
|
97
|
+
"load_method_card",
|
|
98
|
+
"validate_method_card",
|
|
99
|
+
]
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Chart.js chart-builder functions, injected into the dashboard JS.
|
|
3
|
+
Separated from _dashboard_js.py to keep files manageable.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
CHART_JS = r"""
|
|
7
|
+
// ── Shared Global State ─────────────────────────────────
|
|
8
|
+
// These are hoisted to global scope so both chart builders and the
|
|
9
|
+
// core IIFE can share R (reports), activeIdx, and helpers.
|
|
10
|
+
const R = window.__REPORTS || [];
|
|
11
|
+
let activeIdx = 0;
|
|
12
|
+
const $ = id => document.getElementById(id);
|
|
13
|
+
function runLabel(r, i) {
|
|
14
|
+
const c = r.config || {};
|
|
15
|
+
return (c.run_name || c.model || r.run_id || 'Run '+(i+1)).substring(0, 35);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// ── Chart.js Builders ───────────────────────────────────
|
|
19
|
+
const COLORS = ['#6366f1','#34d399','#f59e0b','#f87171','#a78bfa','#22d3ee','#fb923c','#e879f9'];
|
|
20
|
+
let barChart = null, histChart = null, radarChart = null;
|
|
21
|
+
|
|
22
|
+
function destroyCharts() {
|
|
23
|
+
[barChart, histChart, radarChart].forEach(c => { if (c) c.destroy(); });
|
|
24
|
+
barChart = histChart = radarChart = null;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// Grouped bar chart: Exact Match % and chrF++ per run
|
|
28
|
+
function buildBarChart() {
|
|
29
|
+
const sec = $('barchart-section');
|
|
30
|
+
if (R.length < 2) { sec.style.display = 'none'; return; }
|
|
31
|
+
sec.style.display = '';
|
|
32
|
+
const canvas = $('bar-canvas');
|
|
33
|
+
if (barChart) barChart.destroy();
|
|
34
|
+
const labels = R.map((r, i) => runLabel(r, i).substring(0, 22));
|
|
35
|
+
const isDark = document.documentElement.getAttribute('data-theme') !== 'light';
|
|
36
|
+
const gridColor = isDark ? 'rgba(255,255,255,0.06)' : 'rgba(0,0,0,0.06)';
|
|
37
|
+
const textColor = isDark ? 'rgba(255,255,255,0.5)' : 'rgba(0,0,0,0.5)';
|
|
38
|
+
barChart = new Chart(canvas, {
|
|
39
|
+
type: 'bar',
|
|
40
|
+
data: {
|
|
41
|
+
labels,
|
|
42
|
+
datasets: [
|
|
43
|
+
{
|
|
44
|
+
label: 'Exact Match %',
|
|
45
|
+
data: R.map(r => ((r.overall || {}).exact_match_rate || 0) * 100),
|
|
46
|
+
backgroundColor: COLORS[0] + 'cc',
|
|
47
|
+
borderRadius: 4,
|
|
48
|
+
barPercentage: 0.7,
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
label: 'chrF++',
|
|
52
|
+
data: R.map(r => (r.overall || {}).corpus_chrf || 0),
|
|
53
|
+
backgroundColor: COLORS[1] + 'cc',
|
|
54
|
+
borderRadius: 4,
|
|
55
|
+
barPercentage: 0.7,
|
|
56
|
+
}
|
|
57
|
+
]
|
|
58
|
+
},
|
|
59
|
+
options: {
|
|
60
|
+
responsive: true,
|
|
61
|
+
maintainAspectRatio: true,
|
|
62
|
+
plugins: {
|
|
63
|
+
legend: { labels: { color: textColor, font: { size: 11 } } },
|
|
64
|
+
tooltip: { mode: 'index', intersect: false }
|
|
65
|
+
},
|
|
66
|
+
scales: {
|
|
67
|
+
x: { ticks: { color: textColor, font: { size: 10 } }, grid: { color: gridColor } },
|
|
68
|
+
y: { beginAtZero: true, max: 100, ticks: { color: textColor }, grid: { color: gridColor } }
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// chrF++ distribution histogram for active run
|
|
75
|
+
function buildHistogram() {
|
|
76
|
+
const entries = R[activeIdx].entries || [];
|
|
77
|
+
const sec = $('histogram-section');
|
|
78
|
+
if (!entries.length) { sec.style.display = 'none'; return; }
|
|
79
|
+
sec.style.display = '';
|
|
80
|
+
const canvas = $('hist-canvas');
|
|
81
|
+
if (histChart) histChart.destroy();
|
|
82
|
+
const bins = new Array(10).fill(0);
|
|
83
|
+
entries.forEach(e => { const b = Math.min(9, Math.floor((e.chrf_score || 0) / 10)); bins[b]++; });
|
|
84
|
+
const isDark = document.documentElement.getAttribute('data-theme') !== 'light';
|
|
85
|
+
const gridColor = isDark ? 'rgba(255,255,255,0.06)' : 'rgba(0,0,0,0.06)';
|
|
86
|
+
const textColor = isDark ? 'rgba(255,255,255,0.5)' : 'rgba(0,0,0,0.5)';
|
|
87
|
+
histChart = new Chart(canvas, {
|
|
88
|
+
type: 'bar',
|
|
89
|
+
data: {
|
|
90
|
+
labels: ['0-10','10-20','20-30','30-40','40-50','50-60','60-70','70-80','80-90','90-100'],
|
|
91
|
+
datasets: [{
|
|
92
|
+
label: 'Entries',
|
|
93
|
+
data: bins,
|
|
94
|
+
backgroundColor: COLORS[activeIdx % COLORS.length] + 'aa',
|
|
95
|
+
borderRadius: 3,
|
|
96
|
+
}]
|
|
97
|
+
},
|
|
98
|
+
options: {
|
|
99
|
+
responsive: true,
|
|
100
|
+
maintainAspectRatio: true,
|
|
101
|
+
plugins: {
|
|
102
|
+
legend: { display: false },
|
|
103
|
+
tooltip: { callbacks: { title: ctx => 'chrF++ ' + ctx[0].label, label: ctx => ctx.raw + ' entries' } }
|
|
104
|
+
},
|
|
105
|
+
scales: {
|
|
106
|
+
x: { title: { display: true, text: 'chrF++ Score Range', color: textColor }, ticks: { color: textColor }, grid: { display: false } },
|
|
107
|
+
y: { beginAtZero: true, ticks: { color: textColor, stepSize: 1 }, grid: { color: gridColor } }
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// Radar chart: multi-metric comparison across runs
|
|
114
|
+
function buildRadar() {
|
|
115
|
+
const sec = $('radar-section');
|
|
116
|
+
if (R.length < 2) { sec.style.display = 'none'; return; }
|
|
117
|
+
sec.style.display = '';
|
|
118
|
+
const canvas = $('radar-canvas');
|
|
119
|
+
if (radarChart) radarChart.destroy();
|
|
120
|
+
const isDark = document.documentElement.getAttribute('data-theme') !== 'light';
|
|
121
|
+
const gridColor = isDark ? 'rgba(255,255,255,0.08)' : 'rgba(0,0,0,0.08)';
|
|
122
|
+
const textColor = isDark ? 'rgba(255,255,255,0.5)' : 'rgba(0,0,0,0.5)';
|
|
123
|
+
const metrics = ['exact_match_rate', 'corpus_chrf', 'corpus_bleu'];
|
|
124
|
+
const labels = ['Exact Match %', 'chrF++', 'BLEU'];
|
|
125
|
+
const datasets = R.map((r, i) => ({
|
|
126
|
+
label: runLabel(r, i).substring(0, 20),
|
|
127
|
+
data: metrics.map(k => {
|
|
128
|
+
let v = (r.overall || {})[k] || 0;
|
|
129
|
+
if (k === 'exact_match_rate') v *= 100;
|
|
130
|
+
return v;
|
|
131
|
+
}),
|
|
132
|
+
borderColor: COLORS[i % COLORS.length],
|
|
133
|
+
backgroundColor: COLORS[i % COLORS.length] + '22',
|
|
134
|
+
pointBackgroundColor: COLORS[i % COLORS.length],
|
|
135
|
+
pointRadius: 3,
|
|
136
|
+
}));
|
|
137
|
+
radarChart = new Chart(canvas, {
|
|
138
|
+
type: 'radar',
|
|
139
|
+
data: { labels, datasets },
|
|
140
|
+
options: {
|
|
141
|
+
responsive: true,
|
|
142
|
+
maintainAspectRatio: true,
|
|
143
|
+
plugins: { legend: { labels: { color: textColor, font: { size: 10 } } } },
|
|
144
|
+
scales: { r: { beginAtZero: true, max: 100, ticks: { color: textColor, backdropColor: 'transparent' }, grid: { color: gridColor }, pointLabels: { color: textColor } } }
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
"""
|