robertknight / ocrs

Rust library and CLI tool for OCR (extracting text from images)
Apache License 2.0
1.09k stars 44 forks source link

ocrs crashes one of my computers but runs fine on a weaker but more modern CPU #73

Closed Raj2032 closed 3 months ago

Raj2032 commented 3 months ago

This is my code

use std::{collections::VecDeque, path::PathBuf};

use image;
use ocrs::{OcrEngine, OcrEngineParams};
use rten;
use rten_imageio::read_image;
use rten_tensor::AsView;

const SAMPLE_CONTENTS_DIR: &str = "testing_images";
const MODELS_DIR: &str = "models";

mod ocrs_extras;
/// Read a file from a path that is relative to the crate root.
//fn read_file(path: &str) -> Result<Vec<u8>, std::io::Error>
fn read_file(path: &str) -> Vec<u8>
{
    //let mut abs_path = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
    let mut abs_path = PathBuf::new();
    abs_path.push(path);
    return std::fs::read(abs_path).unwrap();
}
struct Args
{
    image: String,
}
//fn parse_args() -> Result<Args, lexopt::Error>
fn parse_args() -> Result<Args, lexopt::Error>
{
    use lexopt::prelude::*;

    let mut values = VecDeque::new();
    let mut parser = lexopt::Parser::from_env();

    while let Some(arg) = parser.next()?
    {
        match arg
        {
            Value(val) => values.push_back(val.string()?),
            Long("help") =>
            {
                println!(
                    "Usage: {bin_name} <image>",
                    bin_name = parser.bin_name().unwrap_or("hello_ocrs")
                );
                std::process::exit(0);
            }
            _ => return Err(arg.unexpected()),
        }
    }

    let image = values.pop_front().ok_or("missing `image` arg")?;

    Ok(Args{image})
}
fn main()
{

    let detection_model_data = read_file(&format!("{}/text-detection.rten", MODELS_DIR));
    let rec_model_data = read_file(&format!("{}/text-recognition.rten", MODELS_DIR));

    let detection_model = rten::Model::load(&detection_model_data).unwrap();
    let recognition_model = rten::Model::load(&rec_model_data).unwrap();

    let engine = OcrEngine::new(OcrEngineParams
    {
        detection_model: Some(detection_model),
        recognition_model: Some(recognition_model),
        ..Default::default()
    }).unwrap();

    //let img = image::open(&format!("{}/image.jpeg", SAMPLE_CONTENTS_DIR)).map(|image| image.into_rgb8()).unwrap();
    let img = read_image(&format!("{}/image.jpeg", SAMPLE_CONTENTS_DIR)).unwrap();
    //ocrs_extras::preprocess::test();
    //let img_source = ocrs_extras::preprocess::ImageSource::from_bytes(img.as_raw(), img.dimensions()).unwrap();

    let ocr_input = engine.prepare_input(img.view()).unwrap();

    // Get oriented bounding boxes of text words in input image.
    let word_rects = engine.detect_words(&ocr_input).unwrap(); // Slow

    // Group words into lines. Each line is represented by a list of word
    // bounding boxes.
    let line_rects = engine.find_text_lines(&ocr_input, &word_rects);

    // Recognize the characters in each line.
    let line_texts = engine.recognize_text(&ocr_input, &line_rects).unwrap(); // Slow

    for line in line_texts
    .iter()
    .flatten()
    // Filter likely spurious detections. With future model improvements
    // this should become unnecessary.
    .filter(|l| l.to_string().len() > 1)
    {
        println!("for loop: {}", line);
    }

}

using the command cargo r runs fine but runs too slowly. I was suggestd to use --release flag as it runs much faster,

So after running cargo r --release my computer crashes the second it runs. The computer will switch itself off so this is at a hardware level rather than at OS level. I tested this on both Windows and Linux same issue.

After adding some extra code to pause before executing the next line until I press a key, it turns out it crashes when I end up right at this line:

 let word_rects = engine.detect_words(&ocr_input).unwrap(); // Slow

I am not too sure how to resolve this at all, especially when my PC shuts itself off immediately as soon as it reaches this line. Not too sure if this is doing GPU task or CPU task?

CPU is: Intel(R) Core(TM) i7-4790K CPU @ 4.00GHz

as mentioned in the title, this happens on my gaming desktop computer (10 years old) but not on my non gaming more modern laptop with a weaker CPU.

Does this have to do with some unstable version of cargo or some unstability on some CPUs out there?

robertknight commented 3 months ago

After adding some extra code to pause before executing the next line until I press a key, it turns out it crashes when I end up right at this line:

The detect_words call is the first function that actually does some machine learning inference. You can verify if this is the problem by using RTen's CLI tool to run the model directly with random inputs:

cargo install rten-cli
rten text-detection.rten

Does the machine that is crashing have any customization to the CPU settings in the BIOS, for example overclocking? Ocrs uses AVX instructions which apparently slightly increases the voltage if used. Tesseract also uses AVX instructions I believe, so it's interesting if that program does work.

As far as resolving the issue goes, there is not a whole lot I can do about hardware faults from my side, other than perhaps providing a way to disable usage of the more advanced instructions. The program will run more slowly (by ~2.5x or so) in that case.

Raj2032 commented 3 months ago

@robertknight I am using stock bios settings, no overclockong or anything.

AVX instructions which apparently slightly increases the voltage if used.

Maybe I should just overvolt (not overclock) my CPU then, as there is not enough voltage going to the CPU then and the current stock bios settings is limiting it?

I also found this:

https://www.reddit.com/r/apexlegends/comments/b9ygkj/pcif_you_are_crashing_it_might_be_the_game_using/?rdt=38139

I may need to offset AVX.

robertknight commented 3 months ago

Based on discussions elsewhere it seems like a hardware issue that is out of scope for this project to resolve. Per my last comment, I might add a way to disable the use of SIMD entirely in future (eg. via setting an environment variable or something).

Raj2032 commented 3 months ago

it might be to do with a powersupply issue but yeah, anyways thanks! On Monday, 3 June 2024 at 16:31, Robert Knight @.***> wrote:

Based on discussions elsewhere it seems like a hardware issue that is out of scope for this project to resolve. Per my last comment, I might add a way to disable the use of SIMD entirely in future (eg. via setting an environment variable or something).

— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you authored the thread.Message ID: @.***>