rtx-csm: emotional_speech_guide — CREMA-D vs RAVDESS firdhokk verdict

8-gen bench (4 emotions × 2 corpora) at seed=42 against firdhokk
Whisper-LV3:

  target    RAVDESS              CREMA-D
  happy     happy (0.999) ✓      happy (0.999) ✓
  angry     neutral (0.92)       sad (0.99)
  fearful   happy (0.998)        fearful (0.984) ✓
  sad       angry (0.99)         fearful (0.99)

CREMA-D 2/4 vs RAVDESS 1/4. Larger / more naturalistic corpus
produces more class-pure fearful direction. Neither corpus solves
angry or sad — recipe shifts into 'vague expressivity' rather than
class-specific corners.

Practical: prefer CREMA-D when available; A/B both per emotion if
class precision matters.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
This commit is contained in:
osobh
2026-04-30 00:01:02 -07:00
co-authored by Claude Opus 4.7
parent f4d8268381
commit a5cedfb46a
69 changed files with 1026 additions and 734 deletions
+17 -10
View File
@@ -25,8 +25,8 @@
//! `candle_core::pickle::read_all` reads the `.bin` directly. No Python
//! step needed in the conversion pipeline.
use anyhow::{anyhow, Context, Result};
use candle_core::{pickle, safetensors as ct_safetensors, Tensor};
use anyhow::{Context, Result, anyhow};
use candle_core::{Tensor, pickle, safetensors as ct_safetensors};
use std::collections::HashMap;
use std::path::Path;
@@ -119,9 +119,7 @@ pub fn merge_weight_norm_auto(v: &Tensor, g: &Tensor) -> Result<Tensor> {
pub fn merge_weight_norm_dim(v: &Tensor, g: &Tensor, kept_dim: usize) -> Result<Tensor> {
let rank = v.rank();
if kept_dim >= rank {
return Err(anyhow!(
"kept_dim {kept_dim} out of range for rank {rank}"
));
return Err(anyhow!("kept_dim {kept_dim} out of range for rank {rank}"));
}
let mut norm_sq = v.sqr().context("v.sqr")?;
for axis in (0..rank).rev() {
@@ -151,8 +149,12 @@ mod tests {
let n0 = (1.0f32 + 4.0 + 9.0).sqrt();
let n1 = (16.0f32 + 25.0 + 36.0).sqrt();
let expected = [
2.0 * 1.0 / n0, 2.0 * 2.0 / n0, 2.0 * 3.0 / n0,
3.0 * 4.0 / n1, 3.0 * 5.0 / n1, 3.0 * 6.0 / n1,
2.0 * 1.0 / n0,
2.0 * 2.0 / n0,
2.0 * 3.0 / n0,
3.0 * 4.0 / n1,
3.0 * 5.0 / n1,
3.0 * 6.0 / n1,
];
for (a, b) in m.iter().zip(expected.iter()) {
assert!((a - b).abs() < 1e-6);
@@ -165,7 +167,9 @@ mod tests {
// (norm taken over axes 0,1). Per-kernel-position scale.
let device = Device::Cpu;
let v = Tensor::from_slice(
&[1.0f32, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0],
&[
1.0f32, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0,
],
(2, 2, 3),
&device,
)
@@ -188,8 +192,11 @@ mod tests {
for j in 0..2 {
let idx = i * 6 + j * 3 + k;
let want = g_flat[k] * v_flat[idx] / norm;
assert!((m_flat[idx] - want).abs() < 1e-5,
"k={k} i={i} j={j}: got {} want {want}", m_flat[idx]);
assert!(
(m_flat[idx] - want).abs() < 1e-5,
"k={k} i={i} j={j}: got {} want {want}",
m_flat[idx]
);
}
}
}