[x] 2. 참고 자료 수집 및 분석하기(5강 실습코드, 스페셜 미션 3~4번, 구글링 자료)
[ ] 3. 베이스라인 코드에 적용
[x] 3-1. BertEncoder 부분의 오류 해결하기
RuntimeError: CUDA error: CUBLAS_STATUS_NOT_INITIALIZED when calling cublasCreate(handle)
[x] 3-2. query 1개 일 때 top-k개의 passage 얻어 오기 (get_relevant_doc)
[x] 3-3. train 부분 추가 하기 (argsment 추가 및 train model 저장 및 불러오는 부분 추가)
[x] 3-4. 학습이 끝난 p_encoder를 이용하여 wiki, dataset(train, valid)의 context 부분을 embedding하고 저장하기 (get_dense_embedding)
[x] 3-5. query 2개 이상 일 때 top-k개의 passage 얻어 오기 (get_question_embedding , get_relevant_doc_bulk)
3.5에서 학습을 시켰음에도 불구하고 top-k개의 paasage의 내용이 이상한 것만 가져오고 가져온 passage id도 똑같은 것만 가져온다. 해당 문제를 몇일 동안 해결하지 못해서 이것은 폐기하기 희락님 코드를 사용할 것 같습니다.
정리
1. MRC 5강 내용 및 구현할 것들 정리하기
DPR
Sparse Passage Retrieval보다 차원의 크기가 작음
-> SPR은 vacabulary size이지만 DPR은 model embedding size이기 때문이다.
DPR 동작 과정
Query embedding을 수행하는 모델(Dense encoder)에 question sequence를 넣어주며 embedding 값이 나온다. -> Wq(CLS token)
DB에 있는 각 passage를 input으로 넣어서 각 passage에 따른 embedding을 구해준다. -> Wp(CLS token)
위에서 구한 Wq와 Wp를 doc product를 해준다. 이때 Wp가 여러개일 수 있고 그러면 doc product의 값이 여러개 나올 것이다.
Doc product의 결과를 내림차순으로 하여 top - n개를 선택하고 이것을 MRC의 input으로 넣어준다.
DPR을 하기 위해서 구현해야 하는 요소
Query embedding 구하는 과정
Passage embedding 구하는 과정
각 encoder 학습시키는 과정
doc product 후 top - n 개의 passage 반환하는 부분
Negative sampling 을 위한 negative sample 들을 샘플링 과정 : negative sampling이 학습 데이터에 포함되어 있을 경우 성능이 더 좋다고 함
2. 참고 자료 수집 및 분석하기(5강 실습코드, 스페셜 미션 3~4번, 구글링 자료)
5강 실습 코드
Encoder 클래스
위의 부분과 같이 구현하면 될 것 같다.
그러나 huggingface의 Trainer 사용시 위의 커스텀모델의 forward의 부분을 수정해야 될 것 같다.
이유 : 아마도 Trainer 클래스 사용시 train에 맞는 output을 forward에서 출력해야 되지 않을까 싶다(형식 : loss, logits, hidden states, attentions).
그래서 이 부분은 huggingface의 Trainer 사용유무에 따라서 조금의 차이가 있을 것 같다.
Trainer 사용 : forward의 output을 Trainer에 맞게 해야 됨. + loss 구하는 부분도 forward에 포함시켜야 된다.
Trainer 사용 X : 커스텀 train 함수를 구현해야 된다.
train loss 구현
모델을 통한 output 얻어오기(Wq, Wp)
Wq 와 Wp를 doc production 해준다. == 유사도 구하는 과정
2에서 얻은 값에 log_softmax를 취해준다.
3에서 얻은 결과에 negative log likelihoode loss를 적용시켜준다.
=> 이때 강의 설명에서는 대각 원소를 구해주고 이것을 nll에 2번째 인자로 넣어주는데 음... 왜 그렇게 하는지 잘 이해가 안된다. <- 이 부분은 추가적으로 공부해서 이해하기
loss 구하는 과정
스페셜 미션 3번
Negative sampling 과정
아래와 같이 context와 임의의 context를 선택에서 append한다.
스페셜 미션에서 아래의 과정을 수행하면 baseline에 적용할 수 있는 DPR을 만들 수 있을 것 같다.
스페셜 미션 3 : class DenseRetrieval 구현해보기(스페셜 미션 코드 3에 구현할 것들에 대한 틀이 잡혀있다.)
=> 스페셜 미션 3번의 예시 코드가 공개 되었다. 이것을 참고하면 더 좋을 것 같다.
먼저 베이스라인 코드에 적용해보고 그 다음에 코드를 이해하는 걸로 해야겠다.
3. 베이스라인 코드에 적용
3-1. BertEncoder 부분의 오류 해결하기 RuntimeError: CUDA error: CUBLAS_STATUS_NOT_INITIALIZED when calling cublasCreate(handle)
위와 같은 오류는 tokenizer와 모델이 달라서 생긴 문제였다.
3-2. query 1개 일 때 top-k개의 passage 얻어 오기 (get_relevant_doc)
스페셜미션 코드에서 return부분만 고쳐주었다.
3-3. train 부분 추가 하기 (argsment 추가 및 train model 저장 및 불러오는 부분 추가)
retrieval.py에 args를 추가해줘서 분기시켰고 학습시킨 모델에 대해서 저장하도록 구현하였다.
3-4. 학습이 끝난 p_encoder를 이용하여 wiki, dataset(train, valid)의 context 부분을 embedding하고 저장하기 (get_dense_embedding)
문제 발생 : gpu out memory 발생하여 device를 cpu로 하여 돌렸다.
해결 : encoder모델을 거쳐서 나온 embedding 값에 계산 그래프를 분리하고 cpu 주소로 복사하여 append를 하니까 잘 동작하였다.
-> 희락님이 detach().cpu().numpy() 방법을 알려줬음
3-5 . query 2개 이상 일 때 top-k개의 passage 얻어 오기 (get_question_embedding , get_relevant_doc_bulk)
문제 : 아래와 같이 question embedding과 passage_embedding의 doc product의 결과가 매번 다르게 나오지만 정렬시 순서는 항상 같다. 그래서 question이 다른데도 항상 동일한 passage만 return하고 있다.
문제를 해결하기 위해서 살펴볼 것들
test의 question과 wiki의 passage를 사용하는게 아니라 train/valid만 사용해서 잘 나오는지 확인해보기
이때 train으로 encoder를 학습시키고 valid로 평가해보기 평가를 위한 metric도 정의하기
작업 시작일
2021.10.18
작업순서
RuntimeError: CUDA error: CUBLAS_STATUS_NOT_INITIALIZED when calling cublasCreate(handle)
3.5에서 학습을 시켰음에도 불구하고 top-k개의 paasage의 내용이 이상한 것만 가져오고 가져온 passage id도 똑같은 것만 가져온다. 해당 문제를 몇일 동안 해결하지 못해서 이것은 폐기하기 희락님 코드를 사용할 것 같습니다.
정리
1. MRC 5강 내용 및 구현할 것들 정리하기
DPR
Sparse Passage Retrieval보다 차원의 크기가 작음 -> SPR은 vacabulary size이지만 DPR은 model embedding size이기 때문이다.
DPR 동작 과정
DPR을 하기 위해서 구현해야 하는 요소
2. 참고 자료 수집 및 분석하기(5강 실습코드, 스페셜 미션 3~4번, 구글링 자료)
5강 실습 코드
위의 부분과 같이 구현하면 될 것 같다. 그러나 huggingface의 Trainer 사용시 위의 커스텀모델의 forward의 부분을 수정해야 될 것 같다. 이유 : 아마도 Trainer 클래스 사용시 train에 맞는 output을 forward에서 출력해야 되지 않을까 싶다(형식 : loss, logits, hidden states, attentions).
그래서 이 부분은 huggingface의 Trainer 사용유무에 따라서 조금의 차이가 있을 것 같다.
Trainer 사용 : forward의 output을 Trainer에 맞게 해야 됨. + loss 구하는 부분도 forward에 포함시켜야 된다. Trainer 사용 X : 커스텀 train 함수를 구현해야 된다.
train loss 구현
loss 구하는 과정
스페셜 미션 3번
Negative sampling 과정
스페셜 미션에서 아래의 과정을 수행하면 baseline에 적용할 수 있는 DPR을 만들 수 있을 것 같다.
먼저 베이스라인 코드에 적용해보고 그 다음에 코드를 이해하는 걸로 해야겠다.
3. 베이스라인 코드에 적용
3-1. BertEncoder 부분의 오류 해결하기
RuntimeError: CUDA error: CUBLAS_STATUS_NOT_INITIALIZED when calling cublasCreate(handle)
위와 같은 오류는 tokenizer와 모델이 달라서 생긴 문제였다.3-2. query 1개 일 때 top-k개의 passage 얻어 오기 (get_relevant_doc) 스페셜미션 코드에서 return부분만 고쳐주었다.
3-3. train 부분 추가 하기 (argsment 추가 및 train model 저장 및 불러오는 부분 추가) retrieval.py에 args를 추가해줘서 분기시켰고 학습시킨 모델에 대해서 저장하도록 구현하였다.
3-4. 학습이 끝난 p_encoder를 이용하여 wiki, dataset(train, valid)의 context 부분을 embedding하고 저장하기 (get_dense_embedding)
문제 발생 : gpu out memory 발생하여 device를 cpu로 하여 돌렸다. 해결 : encoder모델을 거쳐서 나온 embedding 값에 계산 그래프를 분리하고 cpu 주소로 복사하여 append를 하니까 잘 동작하였다. -> 희락님이 detach().cpu().numpy() 방법을 알려줬음
문제 : 아래와 같이 question embedding과 passage_embedding의 doc product의 결과가 매번 다르게 나오지만 정렬시 순서는 항상 같다. 그래서 question이 다른데도 항상 동일한 passage만 return하고 있다.![스크린샷 2021-10-21 오후 3 22 50](https://user-images.githubusercontent.com/22788924/138222757-3e40dc2e-3518-4e5d-ad19-fa5af810ca22.png)
문제를 해결하기 위해서 살펴볼 것들
4. 결과 정리