Refactor: Remove unused Whisper variants
This commit removes the `whisper_variant` and `whisper_hotwords_variant` fields from the `run_id` generation and the `print_meta_summary` function. These variants are no longer used as the project is shifting focus to LLM-based generation. The `run_full_case.rs` example has also been updated to reflect this change.
This commit is contained in:
@@ -54,18 +54,13 @@ fn print_meta_summary(run: &Path) -> Result<()> {
|
||||
}
|
||||
};
|
||||
let v: serde_json::Value = serde_json::from_str(&raw).context("parsing meta.json")?;
|
||||
let w = v.get("whisper_variant").and_then(|x| x.as_str()).unwrap_or("?");
|
||||
let h = v
|
||||
.get("whisper_hotwords_variant")
|
||||
.and_then(|x| x.as_str())
|
||||
.unwrap_or("none");
|
||||
let l = v.get("llm_variant").and_then(|x| x.as_str()).unwrap_or("?");
|
||||
let model = v.get("llm_model").and_then(|x| x.as_str()).unwrap_or("?");
|
||||
let wallclock = v
|
||||
.pointer("/timings_ms/wallclock_ms")
|
||||
.and_then(|x| x.as_u64())
|
||||
.unwrap_or(0);
|
||||
println!(" whisper={w} hotwords={h} llm={l} model={model} wallclock={wallclock}ms");
|
||||
println!(" llm={l} model={model} wallclock={wallclock}ms");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
@@ -6,14 +6,12 @@
|
||||
//! Usage:
|
||||
//! run_full_case \
|
||||
//! --case-dir case_c414cf52 \
|
||||
//! --whisper-prompt prompts/whisper/v1_dosing_minimal.txt \
|
||||
//! --whisper-hotwords prompts/whisper_hotwords/v1_drugs.txt \
|
||||
//! --llm-prompt prompts/llm/baseline.txt \
|
||||
//! --runs 3
|
||||
//!
|
||||
//! Path conventions:
|
||||
//! - `--case-dir` is relative to the experiments/ working directory
|
||||
//! - `--*-prompt` and `--*-hotwords` are paths relative to `--case-dir`
|
||||
//! - `--llm-prompt` is a path relative to `--case-dir`
|
||||
//! - `--settings` defaults to `../server/settings.toml`
|
||||
//! - `--vocab-dir` defaults to `../server/vocab`
|
||||
|
||||
@@ -28,7 +26,6 @@ use doctate_experiments::{
|
||||
use doctate_server::analyze::llm::{self as srv_llm, LlmSettings as LlmCallSettings};
|
||||
use doctate_server::analyze::prompt::render_prompt;
|
||||
use doctate_server::analyze::{AnalysisInput, RecordingInput};
|
||||
use doctate_server::config::WhisperUserSettings;
|
||||
use doctate_server::gazetteer::{Gazetteer, SpellbookDict};
|
||||
use doctate_server::settings::Settings;
|
||||
use doctate_server::transcribe::ffmpeg::remux_faststart;
|
||||
@@ -42,17 +39,6 @@ struct Args {
|
||||
#[arg(long)]
|
||||
case_dir: PathBuf,
|
||||
|
||||
/// Path to a Whisper `initial_prompt` file. Empty file → no
|
||||
/// initial_prompt forwarded. Prompts are fall-übergreifend, typically
|
||||
/// under `prompts/whisper/`.
|
||||
#[arg(long)]
|
||||
whisper_prompt: PathBuf,
|
||||
|
||||
/// Optional Whisper `hotwords` file (handle with care — see
|
||||
/// `prompts/whisper_hotwords/README.md`).
|
||||
#[arg(long)]
|
||||
whisper_hotwords: Option<PathBuf>,
|
||||
|
||||
/// Path to the LLM system prompt file. Typically under `prompts/llm/`.
|
||||
#[arg(long)]
|
||||
llm_prompt: PathBuf,
|
||||
@@ -99,19 +85,8 @@ async fn main() -> Result<()> {
|
||||
);
|
||||
}
|
||||
|
||||
let whisper_prompt_text = load_prompt(&args.whisper_prompt)?;
|
||||
let whisper_hotwords_text = match args.whisper_hotwords.as_ref() {
|
||||
Some(p) => Some(load_prompt(p)?),
|
||||
None => None,
|
||||
};
|
||||
let llm_system_prompt = load_prompt(&args.llm_prompt)?;
|
||||
|
||||
let user_whisper = WhisperUserSettings {
|
||||
language: Some("de".to_string()),
|
||||
hotwords: whisper_hotwords_text.clone().filter(|s| !s.is_empty()),
|
||||
initial_prompt: Some(whisper_prompt_text.clone()).filter(|s| !s.is_empty()),
|
||||
};
|
||||
|
||||
let (gazetteer, dict_mode) = load_gazetteer(&args.vocab_dir, &args.hunspell_stem).await?;
|
||||
info!(
|
||||
vocab_dir = %args.vocab_dir.display(),
|
||||
@@ -129,14 +104,12 @@ async fn main() -> Result<()> {
|
||||
.build()
|
||||
.context("building reqwest client")?;
|
||||
|
||||
let whisper_variant_id = stem(&args.whisper_prompt);
|
||||
let hotwords_variant_id = args.whisper_hotwords.as_ref().map(stem);
|
||||
let llm_variant_id = stem(&args.llm_prompt);
|
||||
|
||||
let runs_root = data_runs_root(&case_dir)?;
|
||||
|
||||
for run_index in 1..=args.runs {
|
||||
let id = run_id(&whisper_variant_id, &llm_variant_id, run_index);
|
||||
let id = run_id(&llm_variant_id, run_index);
|
||||
let run_dir = runs_root.join(&id);
|
||||
std::fs::create_dir_all(run_dir.join("transcripts"))?;
|
||||
|
||||
@@ -149,21 +122,18 @@ async fn main() -> Result<()> {
|
||||
for audio in &audios {
|
||||
let recorded_at = stem(audio);
|
||||
let t_whisper = Instant::now();
|
||||
let raw = transcribe_one(
|
||||
&http,
|
||||
&settings,
|
||||
&user_whisper,
|
||||
audio,
|
||||
)
|
||||
.await
|
||||
.with_context(|| format!("transcribing {}", audio.display()))?;
|
||||
let raw = transcribe_one(&http, &settings, Some("de"), audio)
|
||||
.await
|
||||
.with_context(|| format!("transcribing {}", audio.display()))?;
|
||||
timings.whisper_total_ms += t_whisper.elapsed().as_millis() as u64;
|
||||
|
||||
let t_gaz = Instant::now();
|
||||
let cleaned = gazetteer.replace(&raw);
|
||||
timings.gazetteer_total_ms += t_gaz.elapsed().as_millis() as u64;
|
||||
|
||||
let transcript_path = run_dir.join("transcripts").join(format!("{recorded_at}.txt"));
|
||||
let transcript_path = run_dir
|
||||
.join("transcripts")
|
||||
.join(format!("{recorded_at}.txt"));
|
||||
atomic_write(&transcript_path, &cleaned)?;
|
||||
|
||||
recordings_meta.push(RecordingMeta {
|
||||
@@ -191,7 +161,8 @@ async fn main() -> Result<()> {
|
||||
|
||||
if !args.no_llm {
|
||||
let t_llm = Instant::now();
|
||||
let document_raw = call_llm(&http, &settings, &llm_system_prompt, &user_content).await?;
|
||||
let document_raw =
|
||||
call_llm(&http, &settings, &llm_system_prompt, &user_content).await?;
|
||||
timings.llm_ms = t_llm.elapsed().as_millis() as u64;
|
||||
// Post-LLM gazetteer pass — mirrors `server/src/analyze/worker.rs:150`.
|
||||
// Catches LLM-drift back to non-canonical forms (e.g. anglicization)
|
||||
@@ -212,8 +183,6 @@ async fn main() -> Result<()> {
|
||||
.file_name()
|
||||
.map(|s| s.to_string_lossy().into_owned())
|
||||
.unwrap_or_default(),
|
||||
whisper_variant: whisper_variant_id.clone(),
|
||||
whisper_hotwords_variant: hotwords_variant_id.clone(),
|
||||
llm_variant: llm_variant_id.clone(),
|
||||
whisper_url: settings.whisper.url.clone(),
|
||||
llm_url: settings.llm.url.clone(),
|
||||
@@ -280,9 +249,9 @@ async fn load_gazetteer(
|
||||
fn dict_mode_clone(m: &GazetteerDictMode) -> GazetteerDictMode {
|
||||
match m {
|
||||
GazetteerDictMode::NoDict => GazetteerDictMode::NoDict,
|
||||
GazetteerDictMode::SpellbookHunspell { stem } => GazetteerDictMode::SpellbookHunspell {
|
||||
stem: stem.clone(),
|
||||
},
|
||||
GazetteerDictMode::SpellbookHunspell { stem } => {
|
||||
GazetteerDictMode::SpellbookHunspell { stem: stem.clone() }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -325,16 +294,22 @@ fn stem<P: AsRef<Path>>(p: P) -> String {
|
||||
async fn transcribe_one(
|
||||
http: &reqwest::Client,
|
||||
settings: &Settings,
|
||||
user_whisper: &WhisperUserSettings,
|
||||
language: Option<&str>,
|
||||
audio: &Path,
|
||||
) -> Result<String> {
|
||||
let remuxed = remux_faststart(audio)
|
||||
.await
|
||||
.with_context(|| format!("ffmpeg remux failed for {}", audio.display()))?;
|
||||
let timeout = Duration::from_secs(settings.whisper.timeout_seconds);
|
||||
let text = srv_whisper::transcribe(http, &settings.whisper.url, remuxed.path(), timeout, user_whisper)
|
||||
.await
|
||||
.map_err(|e| anyhow::anyhow!("whisper transcribe failed: {e}"))?;
|
||||
let text = srv_whisper::transcribe(
|
||||
http,
|
||||
&settings.whisper.url,
|
||||
remuxed.path(),
|
||||
timeout,
|
||||
language,
|
||||
)
|
||||
.await
|
||||
.map_err(|e| anyhow::anyhow!("whisper transcribe failed: {e}"))?;
|
||||
Ok(text)
|
||||
}
|
||||
|
||||
|
||||
@@ -119,7 +119,7 @@ async fn main() -> Result<()> {
|
||||
let runs_root = data_runs_root(&case_dir)?;
|
||||
|
||||
for run_index in 1..=args.runs {
|
||||
let id = run_id("none", &llm_variant_id, run_index);
|
||||
let id = run_id(&llm_variant_id, run_index);
|
||||
let run_dir = runs_root.join(&id);
|
||||
std::fs::create_dir_all(&run_dir)?;
|
||||
|
||||
@@ -147,8 +147,6 @@ async fn main() -> Result<()> {
|
||||
.file_name()
|
||||
.map(|s| s.to_string_lossy().into_owned())
|
||||
.unwrap_or_default(),
|
||||
whisper_variant: "none".into(),
|
||||
whisper_hotwords_variant: None,
|
||||
llm_variant: llm_variant_id.clone(),
|
||||
whisper_url: String::new(),
|
||||
llm_url: settings.llm.url.clone(),
|
||||
|
||||
@@ -17,13 +17,15 @@ use time::OffsetDateTime;
|
||||
use time::format_description::well_known::Iso8601;
|
||||
|
||||
/// Generate a run identifier in the form
|
||||
/// `<UTC-ISO>_w-<wid>_l-<lid>_run<n>`. Used as the directory name under
|
||||
/// `<UTC-ISO>_l-<lid>_run<n>`. Used as the directory name under
|
||||
/// `case_<id>/runs/`.
|
||||
pub fn run_id(whisper_variant: &str, llm_variant: &str, run_index: u32) -> String {
|
||||
pub fn run_id(llm_variant: &str, run_index: u32) -> String {
|
||||
let now = OffsetDateTime::now_utc();
|
||||
let stamp = now.format(&Iso8601::DEFAULT).unwrap_or_else(|_| "unknown".into());
|
||||
let stamp = now
|
||||
.format(&Iso8601::DEFAULT)
|
||||
.unwrap_or_else(|_| "unknown".into());
|
||||
let safe_stamp = stamp.replace(':', "-").replace('.', "-");
|
||||
format!("{safe_stamp}_w-{whisper_variant}_l-{llm_variant}_run{run_index}")
|
||||
format!("{safe_stamp}_l-{llm_variant}_run{run_index}")
|
||||
}
|
||||
|
||||
/// Read a prompt file. Returns empty string for an empty file (used as
|
||||
@@ -61,8 +63,6 @@ pub struct RunMeta {
|
||||
pub run_id: String,
|
||||
pub created_at_utc: String,
|
||||
pub case: String,
|
||||
pub whisper_variant: String,
|
||||
pub whisper_hotwords_variant: Option<String>,
|
||||
pub llm_variant: String,
|
||||
pub whisper_url: String,
|
||||
pub llm_url: String,
|
||||
|
||||
Reference in New Issue
Block a user