JaidedAI / EasyOCR

Ready-to-use OCR with 80+ supported languages and all popular writing scripts including Latin, Chinese, Arabic, Devanagari, Cyrillic and etc.
https://www.jaided.ai
Apache License 2.0
24.51k stars 3.16k forks source link

readtext fails when specifying a GPU other than cuda:0 #1159

Open deejai opened 1 year ago

deejai commented 1 year ago

reader = easyocr.Reader(['en'], gpu="cuda:3")

image_array = np.array(image)

readtext(image_array, detail=0)

I'm converting a pdf2image Pillow image object to a numpy array and passing it into readtext, but I'm getting this error:

RuntimeError: module must have its parameters and buffers on device cuda:0 (device_ids[0]) but found one of them on device: cuda:3

dhifafaz commented 11 months ago

i got the same error too, anyone already fix this?

syunar commented 11 months ago

I think the problem occurred because when initializing the model, torch.nn.DataParallel is used with the default device_ids value. So, even if you declare the gpu="cuda:3", the default device_ids is still equal to [0, 1, 2, 3].

Basically, I solved this issue by specifying the device_ids to only the given gpu. After running the following code, the device_ids should be [3] (I think it is equivalent to turning off parallel processing, so feel free to wait for everyone to provide a better solution).

Add the following code to the get_detector() function at <your_path>/python3.9/site-packages/easyocr/detection.py:

device_number = next((int(char) for char in device if char.isdigit()), None)
net = torch.nn.DataParallel(net, device_ids=[device_number]).to(device) if device_number is not None else torch.nn.DataParallel(net).to(device)

So the entire function should be:

def get_detector(trained_model, device='cpu', quantize=True, cudnn_benchmark=False):
    net = CRAFT()

    if device == 'cpu':
        net.load_state_dict(copyStateDict(torch.load(trained_model, map_location=device)))
        if quantize:
            try:
                torch.quantization.quantize_dynamic(net, dtype=torch.qint8, inplace=True)
            except:
                pass
    else:
        net.load_state_dict(copyStateDict(torch.load(trained_model, map_location=device)))

        device_number = next((int(char) for char in device if char.isdigit()), None)
        net = torch.nn.DataParallel(net, device_ids=[device_number]).to(device) if device_number is not None else torch.nn.DataParallel(net).to(device)

        cudnn.benchmark = cudnn_benchmark

    net.eval()
    return net

note that if you want to use dbnet for detection model have to do this on <your_path>/python3.9/site-packages/easyocr/detection_db.py instead.

ljj7975 commented 9 months ago

Any updates on this? I think this can be easily fixed if the tensor loaded through readtext are simply moved to the same device.

RolandasRazma commented 9 months ago

as a workaround you can use export CUDA_VISIBLE_DEVICES=1

babyta commented 5 months ago

same error and os.environ["CUDA_VISIBLE_DEVIES"]="2" do not work

RolandasRazma commented 5 months ago

try setting before launching your script. It definitely works.