nemotron-ocr-v1 / nemotron-ocr /tests /test_quad_rectify.py
BoLiu's picture
Rename NeMo Retriever references to Nemotron (#3)
ea7747b verified
Raw
History Blame
4.66 kB
# SPDX-FileCopyrightText: Copyright (c) 2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
import shutil
import torch
import torch.nn.functional as F
from torch.autograd import gradcheck
from torchvision.transforms import ToTensor, ToPILImage
from PIL import Image
from nemotron_ocr.inference.post_processing.quad_rectify import QuadRectify
example = 3
isotropic = True
# root_dir = '/mnt/fsx-datasets-a-1-new/mranzinger/ocr/scene-text/icdar/incidental_text/train'
root_dir = "/home/dcg-adlr-mranzinger-data.cosmos1100/ocr/scene-text/icdar/incidental_text/train"
# root_dir = '/raid/local_datasets/scene-text/icdar/focused_text/train'
image_path = "{}/images/img_{}.jpg".format(root_dir, example)
label_path = "{}/gt/gt_img_{}.txt".format(root_dir, example)
shutil.copyfile(image_path, "original.jpg")
image = Image.open(image_path)
image = ToTensor()(image)
print("image", image.shape)
quads = []
with open(label_path, "r") as fd:
for i, line in enumerate(fd.readlines()):
line = line.strip()
print(line)
# Skip the unicode character
if i == 0:
line = line[1:]
line = line.split(",")
coords = [float(t) for t in line[:8]]
word = line[-1]
if word != "###":
quads.append(coords)
quads = torch.tensor(quads).reshape(-1, 4, 2)
# quads[:,:,0] /= image.shape[-1]
# quads[:,:,1] /= image.shape[-2]
# print(quads)
image = image.unsqueeze(0).repeat(quads.shape[0], 1, 1, 1)
image = image.cuda()
quads = quads.cuda()
aspect = image.shape[-1] / image.shape[-2]
qr = QuadRectify(60, 400, 0, isotropic=isotropic)
# qr = QuadRectify(60, -1000, aspect)
grid = qr(quads, *image.shape[2:])
print("grid", grid.shape)
resampled = F.grid_sample(image, grid, align_corners=False)
print(resampled.shape)
resampled = resampled.permute(1, 0, 2, 3).contiguous().reshape(3, -1, resampled.shape[-1])
resampled = resampled.cpu()
pilOutput = ToPILImage()(resampled)
pilOutput.save("rectified.jpg")
# sys.exit(0)
print("checking gradients")
quads = quads.double()
cuda_quads = quads.cuda()
quads.requires_grad_()
cuda_quads.requires_grad_()
qr = QuadRectify(9, 12, isotropic=isotropic)
print("check GPU gradients:")
# gradcheck(qr.forward, cuda_quads, eps=1e-3, atol=1e-3)
gradcheck(qr.forward, (cuda_quads, *image.shape[2:]))
print("check CPU gradients:")
gradcheck(qr.forward, (quads, *image.shape[2:]))
# #gradcheck(qr.forward, quads, eps=1e-3, atol=1e-3)
# gradcheck(qr.forward, quads)
print("checking performance...")
quads = quads.detach()
quads = torch.rand(256, 4, 2, dtype=torch.float64)
cuda_quads = quads.cuda()
qr = QuadRectify(8, 60, isotropic=isotropic)
# num_passes = 500
# for target_device in [torch.device('cuda:0'), torch.device('cpu')]:
# for target_type in [torch.float16, torch.float32, torch.float64]:
# test_quads = quads.to(target_type).to(target_device).clone()
# test_quads.requires_grad_()
# print('type:', target_type, 'device:', target_device)
# try:
# with torch.autograd.profiler.profile(use_cuda=test_quads.is_cuda) as prof:
# for _ in range(num_passes):
# g = qr(test_quads)
# l = (1 - g.mean())
# l.backward()
# print(prof.key_averages().table(sort_by="cuda_time_total", row_limit=10))
# # print('\tforward...')
# # torch.cuda.synchronize()
# # start_time = time.time()
# # for i in range(num_passes):
# # qr(test_quads).sum()
# # torch.cuda.synchronize()
# # end_time = time.time()
# # fp_sec_per_call = (end_time - start_time) / num_passes
# # print('\t\tTook', fp_sec_per_call, "sec/call")
# # print('\tbackward...')
# # torch.cuda.synchronize()
# # start_time = time.time()
# # for i in range(num_passes):
# # g = qr(test_quads)
# # g.sum().backward()
# # torch.cuda.synchronize()
# # end_time = time.time()
# # bp_sec_per_call = (end_time - start_time) / num_passes - fp_sec_per_call
# # print('\t\tTook', bp_sec_per_call, "sec/call")
# except Exception as e:
# print('\t\t', e)
# # for target_type in [torch.float16, torch.float32]:
# # print('DType:', target_type)
# # h_cuda_quads = cuda_quads.clone().to(target_type)
# # h_cuda_quads.requires_grad_()
# # v = qr(h_cuda_quads).sum()
# # v.backward()
# # print(h_cuda_quads.grad)