boostcampaitech4lv23nlp1 / final-project-level3-nlp-03

Multi-Modal Model for DocVQA(Document Visual Question Answering)
3 stars 0 forks source link

Faster access to dataset while preprocessing #23

Closed chanmuzi closed 1 year ago

chanmuzi commented 1 year ago

기존에 dataset에 접근하던 방식은 다음과 같다.

이런 방식은 각 데이터의 크기가 큰 image와 같은 데이터에 접근할 때 시간이 지나치게 오래 걸린다는 문제점이 확인되었다.

for i, example_index in enumerate(overflow_to_sample_mapping):
    input_ids = tokenized_sentences["input_ids"][i]
    words_idx_mapping = tokenized_sentences.word_ids(i)
    sequence_ids = tokenized_sentences.sequence_ids(i)

    # cls_token의 인덱스를 찾음
    if self.tokenizer._cls_token:
        cls_index = input_ids.index(self.tokenizer.cls_token_id)
    elif 't5' in self.tokenizer.name_or_path:
        cls_index = input_ids.index(self.tokenizer('question')['input_ids'][0]) # t5의 question 토큰을 cls 토큰이라 가정
    else:
        cls_index = input_ids[0] # 첫번째 토큰

    # sequence가 속하는 example을 찾는다.
    answers = train_data['answers'][example_index]
    words = train_data['words'][example_index]
    question = train_data['question'][example_index]
    boxes = train_data['boxes'][example_index]
    tokenized_sentences['image'].append(train_data['image'][example_index])

흥미로운 것은 dataset에 key가 아닌 index로 먼저 접근이 가능하다는 것이다. 즉, 필요한 index로 먼저 dataset을 잘라내고 key로 접근하면 훨씬 빠르게 데이터를 불러올 수 있게 된다. 따라서 train_data[index][key] 방식으로 쓰거나 index별로 train_data_tmp 를 만들어 데이터를 불러오는 것이 효율적이다.

실제 기존의 방식(train_data[key][index])과 train_data[index][key]의 실행 속도를 비교한 결과는 다음과 같다.

import time

start = time.time()
print(train_data['answers'][0])
end = time.time()
print(end-start)

start = time.time()
print(train_data[0]['answers'])
end = time.time()
print(end-start)

# 결과
# ['1/8/93']
# 0.2811601161956787
# ['1/8/93']
# 0.07437682151794434

매번 그 결과가 달라지기는 하지만 최소 2배에서 많게는 네 배 정도 시간이 더 소요되는 것을 확인했다. 따라서 preprocess 시간을 단축시키기 위해 dataset에 접근하는 방식을 바꿔야 한다.

chanmuzi commented 1 year ago

fix:preprocess efficientize #23에 반영