tonhowtf/omniget · error

não li a saída do modelo

Error message

não li a saída do modelo: {e}

What it means

This error wraps a failure from `outputs[0].try_extract_tensor::<f32>()` — the session output could not be read as an f32 tensor. ORT raises this when the output's element type is not f32 (e.g. int64, f16, f64) or the value cannot be viewed as a dense tensor of the requested type.

Solutions

  1. Check the model's declared output dtype and extract the matching type (f16 -> half crate, i64, u8) before converting to f32
  2. Inspect `session.outputs` to confirm index 0 is the mask tensor with f32 dtype
  3. Export/convert the model with output cast to float32 if you control the ONNX export
  4. Match outputs by name instead of positional index to avoid order surprises

Example fix

// before
let (shape, raw) = outputs[0].try_extract_tensor::<f32>()?;
// after
let out = &outputs[0];
let (shape, raw) = out.try_extract_tensor::<f32>()
    .or_else(|_| out.try_extract_tensor::<f64>().map(|(s, d)| (s, d.iter().map(|&v| v as f32).collect())))
    .map_err(|e| anyhow!("não li a saída do modelo: {e}"))?;
Defensive patterns

Strategy: type-guard

Validate before calling

let out_ty = session.outputs[0].output_type.tensor_type();
if out_ty != ort::tensor::TensorElementType::Float32 {
    return Err(anyhow!("saída do modelo não é f32: {:?}", out_ty));
}

Type guard

fn extract_f32(out: &ort::session::builder::DynValue) -> Option<(Vec<i64>, Vec<f32>)> {
    out.try_extract_tensor::<f32>().ok()
}

Try / catch

match outputs[0].try_extract_tensor::<f32>() {
    Ok((shape, raw)) => (shape, raw),
    Err(e) => return Err(anyhow!("não li a saída do modelo ({:?}): {e}", session.outputs[0].output_type)),
}

Prevention

When it happens

Trigger: Indexing `outputs[0]` and requesting an f32 tensor when the model's first output has a different dtype, or the output entry does not exist at index 0 (model exposes a different output order), or the output is a sequence/map rather than a tensor.

Common situations: Swapping in a different segmentation model whose output is f16 or uint8; an exporter that produced int64 masks; picking the wrong graph output index after a model conversion.

Related errors


AI-assisted analysis of tonhowtf/omniget@8600b91f42 (2026-09-12). Data as JSON: /api/errors/2f11942ad55b6fac. Report an issue: GitHub.

Appendix: source

Thrown at src-tauri/omniget-core/src/core/tools/img_bg.rs:385

/// original da imagem.
fn mask_for_image(
    session: &mut ort::session::Session,
    img: &DynamicImage,
    p: &BgParams,
) -> anyhow::Result<GrayImage> {
    let side = p.size as i64;
    // O `ort` traz um `ndarray` próprio (0.17) e o crate usa o 0.16, então o
    // tensor atravessa a fronteira como forma + dados contíguos, que é o que o
    // `Tensor::from_array` aceita sem depender de versão de crate nenhuma.
    let (data, _) = normalize_input(img, p).into_raw_vec_and_offset();
    let tensor = ort::value::Tensor::from_array((vec![1, 3, side, side], data))
        .map_err(|e| anyhow!("não montei o tensor de entrada: {e}"))?;
    let outputs = session
        .run(ort::inputs![tensor])
        .map_err(|e| anyhow!("a inferência falhou: {e}"))?;
    let (shape, raw) = outputs[0]
        .try_extract_tensor::<f32>()
        .map_err(|e| anyhow!("não li a saída do modelo: {e}"))?;
    if shape.len() < 2 {
        return Err(anyhow!(
            "saída do modelo com formato inesperado: {:?}",
            &shape[..]
        ));
    }
    let h = shape[shape.len() - 2].max(0) as u32;
    let w = shape[shape.len() - 1].max(0) as u32;
    let small = mask_from_raw(raw, w, h)?;
    let (ow, oh) = (img.width(), img.height());
    Ok(image::imageops::resize(
        &small,
        ow,
        oh,
        FilterType::Lanczos3,
    ))
}

View on GitHub (pinned to 8600b91f42)