├── MDMMT_HVU_CVPR_2021.pdf ├── README.md ├── create_capts.py ├── data_loader ├── activitynet_dataset.py ├── base.py ├── lsmdc_dataset.py ├── msrvtt_dataset.py └── rbmixin.py ├── dumper.py ├── duplicate_lists ├── README.md ├── dup1.jpg ├── dup2.jpg ├── lists │ ├── ActivityNet_ActivityNet.lst │ ├── ActivityNet_Kinetics700.lst │ ├── ActivityNet_LSMDC.lst │ ├── ActivityNet_MSRVTT.lst │ ├── ActivityNet_MSVD.lst │ ├── ActivityNet_TGIF.lst │ ├── ActivityNet_TwitterVines.lst │ ├── ActivityNet_YouCook2.lst │ ├── LSMDC_ActivityNet.lst │ ├── LSMDC_Kinetics700.lst │ ├── LSMDC_MSRVTT.lst │ ├── LSMDC_MSVD.lst │ ├── LSMDC_TGIF.lst │ ├── LSMDC_TwitterVines.lst │ ├── LSMDC_YouCook2.lst │ ├── MSRVTT_ActivityNet.lst │ ├── MSRVTT_HowTo100M.lst │ ├── MSRVTT_Kinetics700.lst │ ├── MSRVTT_LSMDC.lst │ ├── MSRVTT_MSRVTT.lst │ ├── MSRVTT_MSVD.lst │ ├── MSRVTT_TGIF.lst │ ├── MSRVTT_TwitterVines.lst │ └── MSRVTT_YouCook2.lst ├── pseudo_dup1.jpg └── pseudo_dup2.jpg ├── lists ├── ActivityNet │ ├── fnames.lst │ └── val.vids ├── LSMDC │ ├── fnames.lst │ └── test.vids └── msrvtt │ ├── fnames.lst │ └── test_list_full.txt ├── mdata ├── lsmdc_mdata_test.json ├── mdata_val.json └── msrvtt_mdata_test.json ├── models ├── clip_model.py ├── mmt │ ├── __init__.py │ └── bert_mmt.py ├── pt_utils.py ├── vggish_model.py ├── vmz │ ├── __init__.py │ ├── csn.py │ ├── r2plus1d.py │ └── utils.py └── vmz_model.py ├── mp_utils.py ├── test.py └── validate.py /MDMMT_HVU_CVPR_2021.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/papermsucode/mdmmt/1741ce301037d4ddfa9836854cdca1fade364d1b/MDMMT_HVU_CVPR_2021.pdf -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | In this repository we present the testing code for article 4 | [MDMMT: Multidomain Multimodal Transformer for Video Retrieval](https://arxiv.org/abs/2103.10699). 5 | 6 | [Presentation](./MDMMT_HVU_CVPR_2021.pdf) from CVPR-2021 Workshop "[Large Scale Holistic Video Understanding](https://holistic-video-understanding.github.io/workshops/cvpr2021.html)". 7 | 8 | This code helps: 9 | 1. Create embeddings with CLIP, irCSN152 and VGGish; 10 | 2. Create caption index files; 11 | 3. Run test with created embeddings and captions index files. 12 | 13 | Our pretrained model is available [here](https://drive.google.com/file/d/1dVDouFZFEDrjqhvtjNFP633y0JjHf4Ya/view?usp=sharing). 14 | 15 | 16 | # Citation 17 | ``` 18 | @misc{dzabraev2021mdmmt, 19 | title={MDMMT: Multidomain Multimodal Transformer for Video Retrieval}, 20 | author={Maksim Dzabraev and Maksim Kalashnikov and Stepan Komkov and Aleksandr Petiushko}, 21 | year={2021}, 22 | eprint={2103.10699}, 23 | archivePrefix={arXiv}, 24 | primaryClass={cs.CV} 25 | } 26 | ``` 27 | 28 | Expected testing results: 29 | 30 | ``` 31 | MSRVTT 32 | t2v/R1: 22.87123745819398 33 | t2v/R5: 49.67056856187291 34 | t2v/R10: 61.66722408026756 35 | t2v/R50: 83.95819397993311 36 | t2v/MedR: 6.0 37 | t2v/MeanR: 53.69550323486328 38 | v2t/R1: 5.075250836120401 39 | v2t/R5: 13.777591973244148 40 | v2t/R10: 19.695652173913043 41 | v2t/R50: 41.44314381270903 42 | v2t/MedR: 84.0 43 | v2t/MeanR: 695.3896484375 44 | 45 | 46 | LSMDC 47 | t2v/R1: 17.31731731731732 48 | t2v/R5: 38.23823823823824 49 | t2v/R10: 47.447447447447445 50 | t2v/R50: 72.87287287287288 51 | t2v/MedR: 12.0 52 | t2v/MeanR: 59.398399353027344 53 | v2t/R1: 16.716716716716718 54 | v2t/R5: 37.73773773773774 55 | v2t/R10: 45.545545545545544 56 | v2t/R50: 72.27227227227228 57 | v2t/MedR: 14.0 58 | v2t/MeanR: 60.97697448730469 59 | 60 | ActivityNet 61 | t2v/R1: 19.673503557974048 62 | t2v/R5: 45.22812892423608 63 | t2v/R10: 56.7182921724571 64 | t2v/R50: 80.8915864378401 65 | t2v/MedR: 7.0 66 | t2v/MeanR: 72.35956573486328 67 | v2t/R1: 19.715362076182505 68 | v2t/R5: 44.72582670573462 69 | v2t/R10: 57.157806613645874 70 | v2t/R50: 80.87065717873587 71 | v2t/MedR: 7.0 72 | v2t/MeanR: 68.22499084472656 73 | ``` 74 | 75 | 76 | 77 | # Downloads 78 | 79 | ```bash 80 | mkdir -p ckpts 81 | # https://github.com/facebookresearch/VMZ/ 82 | wget https://github.com/bjuncek/VMZ/releases/download/test_models/irCSN_152_ig65m_from_scratch_f125286141.pth -O ckpts/irCSN_152_ig65m_from_scratch_f125286141.pth 83 | 84 | # https://github.com/tensorflow/models/tree/master/research/audioset/vggish 85 | wget https://storage.googleapis.com/audioset/vggish_model.ckpt -O ckpts/vggish_model.ckpt 86 | 87 | git clone https://github.com/openai/CLIP models/CLIP 88 | git clone https://github.com/tensorflow/models/ models/tensorflow_models 89 | ``` 90 | 91 | # Environment 92 | It is recommended to use conda to install packages. 93 | It is recommended to create two environments. The first one for audio dumping, and the second for video 94 | 95 | ## Audio environment 96 | 97 | Use this environment for producing embeddings with `tf_vggish` 98 | 99 | ``` 100 | tqdm 101 | ffmpeg=4.2.2 102 | tensorflow-gpu 103 | tf_slim 104 | resampy 105 | six 106 | pysoundfile 107 | numpy=1.20.2 # !!! Make sure that intel-mkl is not used. It causes segfault in np.fft.rfft !!! 108 | ``` 109 | 110 | ## Video environment 111 | 112 | Use this environment for producing embeddings with `CLIP` and `irCSN152` 113 | 114 | ```bash 115 | tqdm 116 | pytorch=1.7.1 # !!! It is recommended to use pytorch=1.7.1; 1.8+ is not working with CLIP !!! 117 | torchvision 118 | ffmpeg=4.2.2 119 | ftfy 120 | regex 121 | ``` 122 | 123 | 124 | 125 | # Create lists 126 | 127 | Replace `"<*_DATASET_ROOT>/` with directory where raw video files are located. 128 | 129 | ```bash 130 | cat lists/LSMDC/fnames.lst | awk '{print "/" $0}' > LSMDC.lst 131 | cat lists/ActivityNet/fnames.lst | awk '{print "/" $0}' > ActivityNet_val.lst 132 | cat lists/msrvtt/fnames.lst | awk '{print "/" $0}' > msrvtt_test.lst 133 | ``` 134 | 135 | 136 | # Embeddings 137 | 138 | ```bash 139 | python dumper.py \ 140 | --model_type=VMZ_irCSN_152 \ 141 | --gpus=0,1,2,3,4,5,6,7 \ 142 | --dst_prefix=/ssd/ssd_srv79/dza/dumps/msrvtt/VMZ_irCSN_152/test \ 143 | --lst=msrvtt_test.lst \ 144 | --nworker_per_gpu=2 \ 145 | --per_batch_size=8 \ 146 | --fps=32 \ 147 | --frame_size=224 \ 148 | --frame_crop_size=224 \ 149 | --frames_per_clip=32 150 | 151 | python dumper.py \ 152 | --model_type=CLIP \ 153 | --gpus=0,1,2,3,4,5,6,7 \ 154 | --dst_prefix=/ssd/ssd_srv79/dza/dumps/msrvtt/CLIP/test \ 155 | --lst=msrvtt_test.lst \ 156 | --nworker_per_gpu=8 \ 157 | --per_batch_size=128 \ 158 | --fps=1 \ 159 | --frame_size=228 \ 160 | --frame_crop_size=228 \ 161 | --frames_per_clip=1 162 | 163 | PYTHONPATH=\ 164 | models/tensorflow_models/research/audioset/vggish:\ 165 | models/tensorflow_models/research/audioset/:\ 166 | $PYTHONPATH \ 167 | python dumper.py \ 168 | --model_type=tf_vggish \ 169 | --gpus=0,1,2,3,4,5,6,7 \ 170 | --dst_prefix=/ssd/ssd_srv79/dza/dumps/msrvtt/tf_vggish/test \ 171 | --lst=msrvtt_test.lst \ 172 | --nworker_per_gpu=2 173 | 174 | 175 | 176 | python dumper.py \ 177 | --model_type=VMZ_irCSN_152 \ 178 | --gpus=0,1,2,3,4,5,6,7 \ 179 | --dst_prefix=/ssd/ssd_srv79/dza/dumps/ActivityNet/VMZ_irCSN_152/test \ 180 | --lst=ActivityNet_val.lst \ 181 | --nworker_per_gpu=3 \ 182 | --per_batch_size=8 \ 183 | --fps=32 \ 184 | --frame_size=224 \ 185 | --frame_crop_size=224 \ 186 | --frames_per_clip=32 187 | 188 | python dumper.py \ 189 | --model_type=CLIP \ 190 | --gpus=0,1,2,3,4,5,6,7 \ 191 | --dst_prefix=/ssd/ssd_srv79/dza/dumps/ActivityNet/CLIP/test \ 192 | --lst=ActivityNet_val.lst \ 193 | --nworker_per_gpu=3 \ 194 | --per_batch_size=128 \ 195 | --fps=1 \ 196 | --frame_size=228 \ 197 | --frame_crop_size=228 \ 198 | --frames_per_clip=1 \ 199 | --num_readers=8 200 | 201 | PYTHONPATH=\ 202 | models/tensorflow_models/research/audioset/vggish:\ 203 | models/tensorflow_models/research/audioset/:\ 204 | $PYTHONPATH \ 205 | python dumper.py \ 206 | --model_type=tf_vggish \ 207 | --gpus=0,1,2,3,4,5,6,7 \ 208 | --dst_prefix=/ssd/ssd_srv79/dza/dumps/ActivityNet/tf_vggish/test \ 209 | --lst=ActivityNet_val.lst \ 210 | --nworker_per_gpu=3 \ 211 | --per_batch_size=32 212 | 213 | 214 | 215 | python dumper.py \ 216 | --model_type=VMZ_irCSN_152 \ 217 | --gpus=0,1,2,3,4,5,6,7 \ 218 | --dst_prefix=/ssd/ssd_srv79/dza/dumps/LSMDC/VMZ_irCSN_152/test \ 219 | --lst=LSMDC.lst \ 220 | --nworker_per_gpu=2 \ 221 | --per_batch_size=8 \ 222 | --fps=32 \ 223 | --frame_size=224 \ 224 | --frame_crop_size=224 \ 225 | --frames_per_clip=32 226 | 227 | python dumper.py \ 228 | --model_type=CLIP \ 229 | --gpus=0,1,2,3,4,5,6,7 \ 230 | --dst_prefix=/ssd/ssd_srv79/dza/dumps/LSMDC/CLIP/test \ 231 | --lst=LSMDC.lst \ 232 | --nworker_per_gpu=2 \ 233 | --per_batch_size=128 \ 234 | --fps=1 \ 235 | --frame_size=228 \ 236 | --frame_crop_size=228 \ 237 | --frames_per_clip=1 \ 238 | --num_readers=8 239 | 240 | PYTHONPATH=\ 241 | models/tensorflow_models/research/audioset/vggish:\ 242 | models/tensorflow_models/research/audioset/:\ 243 | $PYTHONPATH \ 244 | python dumper.py \ 245 | --model_type=tf_vggish \ 246 | --gpus=0,1,2,3,4,5,6,7 \ 247 | --dst_prefix=/ssd/ssd_srv79/dza/dumps/LSMDC/tf_vggish/test \ 248 | --lst=LSMDC.lst \ 249 | --nworker_per_gpu=2 \ 250 | --per_batch_size=32 251 | 252 | 253 | ``` 254 | 255 | # Create caption index 256 | 257 | ```bash 258 | python create_capts.py \ 259 | --dataset=msrvtt \ 260 | --output_root=/tmp/capts/msrvtt/ \ 261 | --modality=VIDEO:2048:/ssd/ssd_srv79/dza/dumps/msrvtt/VMZ_irCSN_152/test \ 262 | --modality=CLIP:512:/ssd/ssd_srv79/dza/dumps/msrvtt/CLIP/test \ 263 | --modality=tf_vggish:128:/ssd/ssd_srv79/dza/dumps/msrvtt/tf_vggish/test 264 | mkdir -p /tmp/capts/msrvtt/symlinked-feats/ 265 | cp lists/msrvtt/test_list_full.txt /tmp/capts/msrvtt/symlinked-feats/test_list_full.txt 266 | 267 | python create_capts.py \ 268 | --dataset=ActivityNet \ 269 | --output_root=/tmp/capts/ActivityNet/ \ 270 | --modality=VIDEO:2048:/ssd/ssd_srv79/dza/dumps/ActivityNet/VMZ_irCSN_152/test \ 271 | --modality=CLIP:512:/ssd/ssd_srv79/dza/dumps/ActivityNet/CLIP/test \ 272 | --modality=tf_vggish:128:/ssd/ssd_srv79/dza/dumps/ActivityNet/tf_vggish/test 273 | mkdir -p /tmp/capts/ActivityNet/symlinked-feats/ 274 | cp lists/ActivityNet/val.vids /tmp/capts/ActivityNet/symlinked-feats/val.vids 275 | 276 | python create_capts.py \ 277 | --dataset=lsmdc_publictest \ 278 | --output_root=/tmp/capts/LSMDC/ \ 279 | --modality=VIDEO:2048:/ssd/ssd_srv79/dza/dumps/LSMDC/VMZ_irCSN_152/test \ 280 | --modality=CLIP:512:/ssd/ssd_srv79/dza/dumps/LSMDC/CLIP/test \ 281 | --modality=tf_vggish:128:/ssd/ssd_srv79/dza/dumps/LSMDC/tf_vggish/test 282 | mkdir -p /tmp/capts/LSMDC/symlinked-feats/ 283 | cp lists/LSMDC/test.vids /tmp/capts/LSMDC/symlinked-feats/test.vids 284 | ``` 285 | 286 | 287 | # Test 288 | 289 | ```bash 290 | python test.py --dataset_root=/tmp/capts/msrvtt/ --checkpoint=/mdmmt_3mod.pth --dataset_name=MSRVTT_full --gpu=2 291 | python test.py --dataset_root=/tmp/capts/LSMDC/ --checkpoint=/mdmmt_3mod.pth --dataset_name=lsmdc_publictest --gpu=2 292 | python test.py --dataset_root=/tmp/capts/ActivityNet/ --checkpoint=/mdmmt_3mod.pth --dataset_name=ActivityNet --gpu=2 293 | 294 | ``` 295 | 296 | # WARNING 297 | 298 | Do not use numpy with mkl backend. Sometimes np.fft.rfft produce segmentation fault. 299 | -------------------------------------------------------------------------------- /create_capts.py: -------------------------------------------------------------------------------- 1 | import os 2 | import json 3 | import numpy as np 4 | from collections import defaultdict, OrderedDict 5 | from tqdm import tqdm 6 | import re 7 | import subprocess 8 | import argparse 9 | 10 | def find_segment_t0(arr, t): 11 | if arr[0][0] >= t: 12 | return 0 13 | prev_idx = 0 14 | for idx, s in enumerate(arr): 15 | if s[0] <= t and t <= s[1]: 16 | return idx 17 | elif t < s[0]: 18 | return prev_idx 19 | prev_idx = idx 20 | assert False, (arr, t) 21 | 22 | def find_segment_t1(arr, t): 23 | if arr[-1][1] <= t: 24 | return len(arr) - 1 25 | prev_idx = None 26 | 27 | for idx, s in enumerate(arr): 28 | if s[0] <= t and t <= s[1]: 29 | return idx 30 | elif t < s[0]: 31 | return idx 32 | prev_idx = idx 33 | assert False, (arr, t) 34 | 35 | class IdxIter: 36 | def __init__(self, fname_idx, emb_bsz, skip_pred=None): 37 | self.fname_idx = fname_idx 38 | self.emb_bsz = emb_bsz 39 | self.prev_video_path = None 40 | self.skip_pred = skip_pred 41 | 42 | def __iter__(self): 43 | offt_idx = 0 44 | offt_emb = 0 45 | with open(self.fname_idx) as f: 46 | for line in f.readlines(): 47 | if line.startswith('VIDEO\t'): 48 | offt_idx += len(line) 49 | if self.prev_video_path is not None and skip_flag == False: 50 | yield self.prev_video_path, self.prev_offt_idx, self.prev_offt_emb, np.array(timings), timings_offt 51 | timings = [] 52 | timings_offt = [] 53 | video_path = line.strip().split('\t')[1] 54 | if self.skip_pred: 55 | skip_flag = self.skip_pred(video_path) 56 | else: 57 | skip_flag = False 58 | 59 | self.prev_video_path = video_path 60 | self.prev_offt_idx = offt_idx 61 | self.prev_offt_emb = offt_emb 62 | 63 | else: 64 | if skip_flag == False: 65 | timings_offt.append(offt_idx) 66 | a, b = line.strip().split('\t') 67 | timings.append((float(a), float(b))) 68 | offt_idx += len(line) 69 | offt_emb += self.emb_bsz 70 | 71 | if len(timings) > 0 and skip_flag == False: 72 | # check case when there is no embeddings 73 | yield self.prev_video_path, self.prev_offt_idx, self.prev_offt_emb, np.array(timings), timings_offt 74 | 75 | 76 | def arg_modality(x): 77 | mod_name, dim, prefix = x.split(":") 78 | dim = int(dim) 79 | return mod_name, dim, prefix 80 | 81 | 82 | def find_shards(prefix): 83 | shards = [] 84 | root = os.path.dirname(prefix) 85 | for fname in os.listdir(root): 86 | fname = os.path.join(root, fname) 87 | if fname.startswith(prefix) and fname.endswith('.idx'): 88 | path_idx = os.path.join(root, fname) 89 | path_emb = path_idx.replace('.idx', '.emb') 90 | shards.append((path_emb, path_idx)) 91 | return shards 92 | 93 | 94 | def main(): 95 | parser = argparse.ArgumentParser() 96 | parser.add_argument('--modality', action='append', help='mod_name:dim:prefix', type=arg_modality) 97 | parser.add_argument('--output_root', required=True) 98 | parser.add_argument('--dataset', required=True, choices=['msrvtt', 'ActivityNet', 'lsmdc_publictest']) 99 | args = parser.parse_args() 100 | 101 | j = {} 102 | if args.dataset == 'msrvtt': 103 | with open('mdata/msrvtt_mdata_test.json') as f: 104 | jtest = json.load(f) 105 | j.update(jtest) 106 | #with open('/ssd/ssd_srv79/datasets/msrvtt/msrvtt_mdata_val.json') as f: 107 | # jval = json.load(f) 108 | # j.update(jval) 109 | #with open('/ssd/ssd_srv79/datasets/msrvtt/msrvtt_mdata_train.json') as f: 110 | # jtrain = json.load(f) 111 | # j.update(jtrain) 112 | elif args.dataset == 'ActivityNet': 113 | with open('mdata/mdata_val.json') as f: 114 | jval = json.load(f) 115 | j.update(jval) 116 | #with open('/ssd/ssd_srv79/datasets/ActivityNet/mdata_train.json') as f: 117 | # jtrain = json.load(f) 118 | # j.update(jtrain) 119 | elif args.dataset == 'lsmdc_publictest': 120 | with open('mdata/lsmdc_mdata_test.json') as f: 121 | jtest = json.loads(f.read()) 122 | j.update(jtest) 123 | else: 124 | raise NotImplementedError(args.dataset) 125 | 126 | 127 | mod_dim = {} 128 | mod_names = [] 129 | dump_prefs = [] 130 | for mod_name, dim, prefix in args.modality: 131 | mod_dim[mod_name] = dim 132 | mod_names.append(mod_name) 133 | dump_prefs.append(prefix) 134 | out_root = os.path.join(args.output_root, 'capts') 135 | os.makedirs(out_root, exist_ok=True) 136 | 137 | index = dict() # vid --> {modK --> offt_idx, offt_emb, timings, timings_offt, ...} 138 | for mod_name, prefix in zip(mod_names, dump_prefs): 139 | shards = find_shards(prefix) 140 | assert len(shards) > 0, prefix 141 | for emb_fname, idx_fname in tqdm(shards): 142 | embdim = mod_dim[mod_name] 143 | for vid_path, offt_idx, offt_emb, timings, timings_offt in iter(IdxIter(idx_fname, embdim*4, skip_pred=None)): 144 | if args.dataset in ['msrvtt', 'ActivityNet', 'lsmdc_publictest']: 145 | vid = os.path.splitext(os.path.basename(vid_path))[0] 146 | else: 147 | raise NotImplementedError(f'unknown dataset {args.dataset}') 148 | if vid not in index: 149 | index[vid] = {} 150 | index[vid][mod_name] = (emb_fname, idx_fname, offt_emb, offt_idx, timings, timings_offt) 151 | print('Len index', len(index)) 152 | K = len( set(index.keys()) & set(j.keys()) ) 153 | #import pdb; pdb.set_trace() 154 | print() 155 | print('Len intersection index and mdata', K) 156 | assert K > 0, args.dataset 157 | 158 | skept = [] 159 | processed = set() 160 | all_mdata = {} 161 | verbose = False 162 | for vid_idx, (vid, mdata) in enumerate(tqdm(j.items())): 163 | if vid not in index: 164 | skept.append(vid) 165 | if verbose: 166 | print(f'SKIP[{len(skept)} | {vid_idx}]. not in index', vid) 167 | continue 168 | I = index[vid] 169 | 170 | fnames_l2 = [] 171 | dims = [] 172 | offts_l3 = [] 173 | duration = 0 174 | for mod_name in mod_names: 175 | if mod_name in I: 176 | emb_fname, idx_fname, offt_emb, offt_idx, timings, timings_offt = I[mod_name] 177 | else: 178 | emb_fname, idx_fname, offt_emb, offt_idx, timings, timings_offt = '', '', -1, -1, [], [] 179 | fnames_l2.append(emb_fname) 180 | fnames_l2.append(idx_fname) 181 | dims.append(mod_dim[mod_name]) 182 | offts_l3.append(str(offt_emb)) 183 | offts_l3.append(str(offt_idx)) 184 | offts_l3.append(str(len(timings))) 185 | if len(timings) > 0: 186 | duration = max(duration, timings.max()) 187 | #fnames_l2 = [x.replace('/ssd/ssd_srv79/dumps/', 's3://bucket-7769-huanan/dza/dumps/') for x in fnames_l2] 188 | 189 | all_text = [] 190 | all_start = [] 191 | all_end = [] 192 | 193 | cap_fname = os.path.join(out_root, str(vid)+'.capts') 194 | with open(cap_fname, 'w') as fout: 195 | fout.write('\t'.join(mod_names) + '\n') 196 | fout.write('\t'.join(map(str, dims)) + '\n') 197 | fout.write('\t'.join(fnames_l2) + '\n') 198 | fout.write('\t'.join(offts_l3) + '\n') 199 | used = set() 200 | for text, t_start, t_end in zip(mdata['text'], mdata['start'], mdata['end']): 201 | if t_end == -1: 202 | t_end = duration 203 | if t_start >= t_end: 204 | continue 205 | text = re.sub('\s+', ' ', text).strip() 206 | item = (text, t_start, t_end) 207 | if item in used: 208 | continue 209 | #assert t_start < t_end 210 | offsets = [] 211 | for mod_name in mod_names: 212 | if mod_name in I: 213 | embdim = mod_dim[mod_name] 214 | emb_fname, idx_fname, offt_emb, offt_idx, timings, timings_offt = I[mod_name] 215 | if t_start > timings[-1][1]: 216 | # incorrect caption 217 | break 218 | if t_end < timings[0][0]: 219 | # incorrect caption 220 | break 221 | #if vid == 'video2551': 222 | # import pdb; pdb.set_trace() 223 | idx1 = find_segment_t0(timings, t_start) 224 | idx2 = find_segment_t1(timings, t_end)+1 225 | offsets.append(offt_emb + idx1 * embdim * 4) 226 | offsets.append(timings_offt[idx1]) 227 | offsets.append(idx2 - idx1) 228 | else: 229 | offsets.append(-1) 230 | offsets.append(-1) 231 | offsets.append(0) 232 | #import pdb; pdb.set_trace() 233 | if len(offsets) < len(mod_names): 234 | continue 235 | 236 | joined_offsets = "\t".join(list(map(str, offsets))) 237 | fout.write(f'{text}\t{t_start}\t{t_end}\t{joined_offsets}\n') 238 | all_text.append(text) 239 | all_start.append(t_start) 240 | all_end.append(t_end) 241 | if len(all_text) == 0: 242 | os.remove(cap_fname) 243 | else: 244 | all_mdata[vid] = dict(text=all_text, start=all_start, end=all_end) 245 | processed.add(vid) 246 | 247 | 248 | 249 | if __name__ == "__main__": 250 | main() 251 | -------------------------------------------------------------------------------- /data_loader/activitynet_dataset.py: -------------------------------------------------------------------------------- 1 | # Copyright 2020 Valentin Gabeur 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | """ActivityNet captions dataset.""" 15 | import os 16 | 17 | from data_loader.base import RandCapMixin 18 | 19 | data_mode = os.environ.get('DATA_MODE') 20 | if data_mode == 'h5': 21 | from data_loader.base_h5 import BaseDataset 22 | else: 23 | from data_loader.base import BaseDataset 24 | import numpy as np 25 | 26 | 27 | class ActivityNet(RandCapMixin, BaseDataset): 28 | """ActivityNet captions dataset.""" 29 | 30 | def configure_train_test_splits(self, cut_name, split_name): 31 | if cut_name in ["val1"]: 32 | train_list_path = "symlinked-feats/train_list.txt" 33 | test_list_path = "symlinked-feats/val_1_list.txt" 34 | 35 | test_list_path = os.path.join(self.data_dir, test_list_path) 36 | with open(test_list_path) as f: 37 | test_vid_list = f.readlines() 38 | nb_test_samples = len(test_vid_list) 39 | 40 | if split_name in ["train", "trn", "val", "trainval"]: 41 | train_list_path = os.path.join(self.data_dir, train_list_path) 42 | with open(train_list_path) as f: 43 | train_vid_list = f.readlines() 44 | nb_train_samples = len(train_vid_list) 45 | 46 | cross_vid_list = train_vid_list 47 | cross_vid_list = [x.strip() for x in cross_vid_list] 48 | 49 | # The cross seed is used to split training videos into different 50 | # cross validation splits. 51 | rng = np.random.RandomState(self.cross_seed) 52 | rng.shuffle(cross_vid_list) 53 | 54 | if split_name in ["train", "trn", "trainval"]: 55 | if split_name in ["trainval"]: 56 | self.vid_list = cross_vid_list 57 | elif split_name in ["train", "trn"]: 58 | self.vid_list = cross_vid_list[nb_test_samples:] 59 | if split_name in ["trn"]: 60 | self.vid_list = self.vid_list[:nb_test_samples] 61 | 62 | elif split_name in ["val"]: 63 | self.vid_list = cross_vid_list[:nb_test_samples] 64 | 65 | elif split_name == "test": 66 | self.vid_list = test_vid_list 67 | self.vid_list = [x.strip() for x in self.vid_list] 68 | elif cut_name == "mrc": 69 | self.vid_list = [] 70 | if split_name == 'train': 71 | list_path = os.path.join(self.data_dir, 'symlinked-feats/train.vids') 72 | elif split_name == 'val': 73 | list_path = os.path.join(self.data_dir, 'symlinked-feats/val.vids') 74 | else: 75 | raise NotImplementedError(f'Unknown split_name={split_name}') 76 | with open(list_path) as f: 77 | for line in f: 78 | vid = line.strip() 79 | self.vid_list.append(vid) 80 | elif cut_name in ["c"]: 81 | self.expert_paths = get_expert_paths(self.data_dir) 82 | if split_name in ["train", "trn", "val", "trainval"]: 83 | train_list_path = "train_list.txt" 84 | train_list_path = os.path.join(self.data_dir, train_list_path) 85 | with open(train_list_path) as f: 86 | train_vid_list = f.readlines() 87 | nb_train_samples = len(train_vid_list) 88 | 89 | val_list_path = "val_list.txt" 90 | val_list_path = os.path.join(self.data_dir, val_list_path) 91 | with open(val_list_path) as f: 92 | val_vid_list = f.readlines() 93 | nb_val_samples = len(val_vid_list) 94 | 95 | cross_vid_list = train_vid_list + val_vid_list 96 | cross_vid_list = [x.strip() for x in cross_vid_list] 97 | 98 | if self.cross_seed != 0: 99 | # The cross seed is used to split training videos into different 100 | # cross validation splits. 101 | rng = np.random.RandomState(self.cross_seed) 102 | rng.shuffle(cross_vid_list) 103 | 104 | if split_name in ["train", "trn", "trainval"]: 105 | if split_name in ["trainval"]: 106 | self.vid_list = cross_vid_list 107 | elif split_name in ["train", "trn"]: 108 | self.vid_list = cross_vid_list[:nb_train_samples] 109 | if split_name in ["trn"]: 110 | # In order to monitor performance on the training set, we sample 111 | # from it as many samples as there are validation samples. 112 | rng = np.random.RandomState(0) 113 | rng.shuffle(self.vid_list) 114 | self.vid_list = self.vid_list[:nb_val_samples] 115 | 116 | elif split_name in ["val"]: 117 | self.vid_list = cross_vid_list[nb_train_samples:] 118 | 119 | else: 120 | if split_name == "test1": 121 | list_path = "public_server_val.txt" 122 | elif split_name == "test2": 123 | list_path = "public_server_test.txt" 124 | list_path = os.path.join(self.data_dir, list_path) 125 | with open(list_path) as f: 126 | self.vid_list = f.readlines() 127 | self.vid_list = [x.strip() for x in self.vid_list] 128 | 129 | else: 130 | msg = "unrecognised cut: {}" 131 | raise ValueError(msg.format(cut_name)) 132 | 133 | self.split_name = split_name 134 | self.dataset_name = f"ActivityNet_{cut_name}_{split_name}" 135 | -------------------------------------------------------------------------------- /data_loader/base.py: -------------------------------------------------------------------------------- 1 | from torch.utils.data import Dataset 2 | import torch 3 | import numpy as np 4 | 5 | from data_loader.rbmixin import RangeBasedMixin 6 | 7 | def default_collate_fn(items, experts_info): 8 | all_caption = [] 9 | all_caption_t = [] 10 | all_features = {} 11 | all_features_t = {} 12 | all_features_mask = {} 13 | 14 | bs = len(items) 15 | 16 | for mod_name, einfo in experts_info.items(): 17 | max_tok = einfo["max_tok"] 18 | dim = einfo["dim"] 19 | all_features[mod_name] = torch.zeros(bs, max_tok, dim) 20 | all_features_t[mod_name] = torch.zeros(bs, max_tok) 21 | all_features_mask[mod_name] = torch.zeros(bs, max_tok) 22 | 23 | for batch_idx, (caption, caption_t, features, features_t) in enumerate(items): 24 | all_caption.append(caption) 25 | all_caption_t.append(caption_t) 26 | for mod_name in features.keys(): 27 | max_tok = experts_info[mod_name]["max_tok"] 28 | mod_feat = features[mod_name] 29 | mod_feat_t = np.array(features_t[mod_name]) 30 | assert len(mod_feat) == len(mod_feat_t), (len(mod_feat), len(mod_feat_t)) 31 | if np.isnan(mod_feat_t.sum()): 32 | mod_feat_t = np.zeros(len(mod_feat_t)) 33 | mod_feat_t[:] = 1 34 | else: 35 | mod_feat_t = mod_feat_t - mod_feat_t[:,0].min() 36 | mod_feat_t = 2 + (mod_feat_t[:,1] + mod_feat_t[:,0]) / 2 # (ntok,) 37 | all_features[mod_name][batch_idx,:len(mod_feat)] = torch.from_numpy(mod_feat[:max_tok].copy()) 38 | all_features_t[mod_name][batch_idx,:len(mod_feat)] = torch.from_numpy(mod_feat_t[:max_tok].copy()) 39 | all_features_mask[mod_name][batch_idx, :len(mod_feat)] = 1 40 | 41 | all_caption_t = np.array(all_caption_t) 42 | return all_caption, all_caption_t, all_features, all_features_t, all_features_mask 43 | 44 | 45 | class BaseDataset(RangeBasedMixin, Dataset): 46 | def __init__(self, **kwargs): 47 | self.data_dir = kwargs.pop('data_dir') 48 | self.cut_name = kwargs.pop('cut_name') 49 | self.split_name = kwargs.pop('split_name') 50 | self.experts_info = kwargs.pop('experts_info') 51 | self.training = kwargs.pop('training') 52 | self.restrict_test_captions = None 53 | 54 | self.configure_train_test_splits(self.cut_name, self.split_name) 55 | super().__init__(**kwargs) 56 | 57 | def __len__(self): 58 | return len(self.vid_list) 59 | 60 | def __getitem__(self, idx, capidx=-1): 61 | idx = idx % len(self.vid_list) 62 | vid = self.vid_list[idx] 63 | if self.restrict_test_captions is not None and vid in self.restrict_test_captions: 64 | capidx = self.restrict_test_captions[vid] 65 | sample_data = self.get_sample_data(vid, capidx=capidx) 66 | captions = sample_data["captions"] 67 | captions_t = sample_data["captions_t"] 68 | features = sample_data["features"] 69 | features_t = sample_data["features_t"] 70 | 71 | 72 | assert len(captions) == 1, len(captions) 73 | caption = captions[0] 74 | caption_t = captions_t[0] 75 | return caption, caption_t, features, features_t 76 | 77 | def collate_fn(self, items): 78 | return default_collate_fn(items, self.experts_info) 79 | 80 | def get_val_captions(self, mode='all', seed=None): 81 | if mode == 'all': 82 | capidx = None 83 | elif mode == 'rand_1': 84 | capidx = -1 85 | else: 86 | raise NotImplementedError(f'Unknown mode={mode}') 87 | all_captions = [] 88 | for vid in self.vid_list: 89 | sample_data = self.get_sample_data(vid, capidx=capidx, caponly=True, seed=seed) 90 | captions = sample_data["captions"] 91 | captions_t = sample_data["captions_t"] 92 | captions_idxs = sample_data["captions_idxs"] 93 | assert len(captions) == len(captions_t) == len(captions_idxs), (len(captions), len(captions_t), len(captions_idxs)) 94 | 95 | for capidx1, cap, (t0, t1) in zip(captions_idxs, captions, captions_t): 96 | all_captions.append((vid, capidx1, cap, t0, t1)) 97 | return all_captions 98 | 99 | class RandCapMixin: 100 | def get_val_captions(self, mode='rand_1', seed=42): 101 | return super().get_val_captions(mode, seed) 102 | -------------------------------------------------------------------------------- /data_loader/lsmdc_dataset.py: -------------------------------------------------------------------------------- 1 | # Copyright 2020 Valentin Gabeur 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | """LSMDC dataset.""" 15 | import os 16 | 17 | from data_loader.base import BaseDataset 18 | import numpy as np 19 | import pandas as pd 20 | 21 | 22 | class LSMDC(BaseDataset): 23 | """LSMDC dataset.""" 24 | 25 | def configure_train_test_splits(self, cut_name, split_name): 26 | 27 | if cut_name in ["full"]: 28 | train_list_path = "LSMDC16_annos_training.csv" 29 | test_list_path = "LSMDC16_challenge_1000_publictect.csv" 30 | 31 | test_list_path = os.path.join(self.data_dir, test_list_path) 32 | df = pd.read_csv(test_list_path, delimiter="\t", header=None) 33 | test_vid_list = list(df[0]) 34 | nb_test_samples = len(test_vid_list) 35 | 36 | if split_name in ["train", "trn", "val", "trainval"]: 37 | train_list_path = os.path.join(self.data_dir, train_list_path) 38 | df = pd.read_csv(train_list_path, delimiter="\t", header=None) 39 | train_vid_list = list(df[0]) 40 | 41 | cross_vid_list = train_vid_list 42 | cross_vid_list = [x.strip() for x in cross_vid_list] 43 | 44 | # The cross seed is used to split training videos into different 45 | # cross validation splits. 46 | rng = np.random.RandomState(self.cross_seed) 47 | rng.shuffle(cross_vid_list) 48 | 49 | if split_name in ["train", "trn", "trainval"]: 50 | if split_name in ["trainval"]: 51 | self.vid_list = cross_vid_list 52 | elif split_name in ["train", "trn"]: 53 | self.vid_list = cross_vid_list[nb_test_samples:] 54 | if split_name in ["trn"]: 55 | self.vid_list = self.vid_list[:nb_test_samples] 56 | 57 | elif split_name in ["val"]: 58 | self.vid_list = cross_vid_list[:nb_test_samples] 59 | 60 | elif split_name == "test": 61 | self.vid_list = test_vid_list 62 | self.vid_list = [x.strip() for x in self.vid_list] 63 | elif cut_name == "mrc": 64 | self.vid_list = [] 65 | if split_name == 'train': 66 | list_path = os.path.join(self.data_dir, 'symlinked-feats/train.vids') 67 | elif split_name == 'val': 68 | list_path = os.path.join(self.data_dir, 'symlinked-feats/val.vids') 69 | elif split_name == 'test': 70 | list_path = os.path.join(self.data_dir, 'symlinked-feats/test.vids') 71 | else: 72 | raise NotImplementedError(f'Unknown split_name={split_name}') 73 | with open(list_path) as f: 74 | for line in f: 75 | vid = line.strip() 76 | self.vid_list.append(vid) 77 | else: 78 | raise NotImplementedError(f'Unknown cut_name={cut_name}') 79 | 80 | 81 | # There are five videos without captions in the training set, so we drop 82 | # them. 83 | movies = [ 84 | "0024_THE_LORD_OF_THE_RINGS_THE_FELLOWSHIP_OF_THE_RING_00.31.10.217-00.31.10.706", 85 | "1014_2012_00.01.21.399-00.01.23.997", 86 | "1014_2012_00.27.58.174-00.27.59.021", 87 | "1018_Body_Of_Lies_00.42.15.677-00.42.18.534", 88 | "1037_The_Curious_Case_Of_Benjamin_Button_02.25.14.743-02.25.17.312", 89 | ] 90 | for movie in movies: 91 | if movie in self.vid_list: 92 | self.vid_list.remove(movie) 93 | 94 | self.split_name = split_name 95 | self.dataset_name = f"LSMDC_{cut_name}_{split_name}" 96 | -------------------------------------------------------------------------------- /data_loader/msrvtt_dataset.py: -------------------------------------------------------------------------------- 1 | # Copyright 2020 Valentin Gabeur 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | """MSR-VTT dataset.""" 15 | import os 16 | import os.path 17 | 18 | from data_loader.base import BaseDataset 19 | import numpy as np 20 | 21 | def get_val_captions(self, cut_name, **kwargs): 22 | all_captions = [] 23 | for vid in self.vid_list: 24 | if cut_name == 'jsfusion': 25 | capidx = self.restrict_test_captions[vid] 26 | elif cut_name == 'miech': 27 | capidx = 0 28 | else: 29 | raise NotImplementedError 30 | sample_data = self.get_sample_data(vid, capidx=capidx, caponly=True) 31 | captions = sample_data["captions"] 32 | captions_t = sample_data["captions_t"] 33 | captions_idxs = sample_data["captions_idxs"] 34 | assert captions_idxs[0] == capidx 35 | assert len(captions) == len(captions_t) == len(captions_idxs), (len(captions), len(captions_t), len(captions_idxs)) 36 | 37 | for capidx, cap, (t0, t1) in zip(captions_idxs, captions, captions_t): 38 | all_captions.append((vid, capidx, cap, t0, t1)) 39 | return all_captions 40 | 41 | class MSRVTT(BaseDataset): 42 | """MSR-VTT dataset.""" 43 | 44 | def configure_train_test_splits(self, cut_name, split_name): 45 | self.restrict_test_captions = None 46 | 47 | if cut_name in ["miech", "jsfusion"]: 48 | self.get_val_captions = lambda *args, **kwargs: get_val_captions(self, cut_name, *args, **kwargs) 49 | if cut_name in ["miech"]: 50 | # For now, we follow Antoine's approach of using the first text caption 51 | # for the retrieval task when evaluating on his custom split. 52 | train_list_path = "train_list_miech.txt" 53 | test_list_path = "test_list_miech.txt" 54 | elif cut_name in ["jsfusion"]: 55 | train_list_path = "train_list_jsfusion.txt" 56 | test_list_path = "val_list_jsfusion.txt" 57 | # NOTE: The JSFusion split (referred to as 1k-A in the paper) uses all 58 | # videos, but randomly samples a single caption per video from the test 59 | # set for evaluation. To reproduce this evaluation, we use the indices 60 | # of the test captions, and restrict to this subset during eval. 61 | test_cap_idx_path = os.path.join(self.data_dir, "symlinked-feats", 62 | "jsfusion_val_caption_idx.pkl") 63 | with open(test_cap_idx_path, 'rb') as f: 64 | self.restrict_test_captions = pickle.load(f) 65 | 66 | test_list_path = os.path.join(self.data_dir, "symlinked-feats", test_list_path) 67 | with open(test_list_path) as f: 68 | test_vid_list = f.readlines() 69 | nb_test_samples = len(test_vid_list) 70 | 71 | if split_name in ["train", "trn", "val", "trainval"]: 72 | train_list_path = os.path.join(self.data_dir, "symlinked-feats", train_list_path) 73 | with open(train_list_path) as f: 74 | train_vid_list = f.readlines() 75 | nb_train_samples = len(train_vid_list) 76 | 77 | cross_vid_list = train_vid_list 78 | cross_vid_list = [x.strip() for x in cross_vid_list] 79 | 80 | # The cross seed is used to split training videos into different 81 | # cross validation splits. 82 | rng = np.random.RandomState(0) 83 | rng.shuffle(cross_vid_list) 84 | 85 | if split_name in ["train", "trn", "trainval"]: 86 | if split_name in ["trainval"]: 87 | self.vid_list = cross_vid_list 88 | elif split_name in ["train", "trn"]: 89 | self.vid_list = cross_vid_list[nb_test_samples:] 90 | if split_name in ["trn"]: 91 | self.vid_list = self.vid_list[:nb_test_samples] 92 | 93 | elif split_name in ["val"]: 94 | self.vid_list = cross_vid_list[:nb_test_samples] 95 | 96 | elif split_name == "test": 97 | self.vid_list = test_vid_list 98 | self.vid_list = [x.strip() for x in self.vid_list] 99 | 100 | elif cut_name in ["full", 'full_clean']: 101 | if split_name in ["train", "trn"]: 102 | #list_path = "train_list.txt" 103 | if cut_name == 'full': 104 | list_path = "symlinked-feats/train_list_full.txt" 105 | else: 106 | list_path = "symlinked-feats/train_list_full.ytvid.manual.txt" 107 | elif split_name in ["val"]: 108 | #list_path = "val_list.txt" 109 | list_path = "symlinked-feats/test_list_full.txt" 110 | elif split_name in ["test"]: 111 | list_path = "symlinked-feats/test_list_full.txt" 112 | else: 113 | raise ValueError(f"unrecognised split: {split_name}") 114 | list_path = os.path.join(self.data_dir, list_path) 115 | with open(list_path) as f: 116 | self.vid_list = f.readlines() 117 | self.vid_list = [x.strip() for x in self.vid_list] 118 | 119 | # We want the trn split to be the same size as the val set 120 | if split_name in ["trn"]: 121 | rng = np.random.RandomState(0) 122 | rng.shuffle(self.vid_list) 123 | self.vid_list = self.vid_list[:497] 124 | else: 125 | msg = "unrecognised cut: {}" 126 | raise ValueError(msg.format(cut_name)) 127 | 128 | self.split_name = split_name 129 | self.dataset_name = f"MSRVTT_{cut_name}_{split_name}" 130 | 131 | -------------------------------------------------------------------------------- /data_loader/rbmixin.py: -------------------------------------------------------------------------------- 1 | import os 2 | import torch 3 | import numpy as np 4 | import re 5 | 6 | def np_choice(rnd, arr): 7 | if rnd: 8 | choice_fn = rnd.choice 9 | else: 10 | choice_fn = np.random.choice 11 | idx = choice_fn(len(arr)) 12 | return arr[idx] 13 | 14 | 15 | class RangeBasedMixin: 16 | def __init__(self, **kwargs): 17 | self.fname_repl = kwargs.pop('fname_repl', None) 18 | self.capt_paths = {} 19 | self.capts_root = os.path.join(self.data_dir, 'capts') 20 | assert os.path.exists(self.capts_root), self.capts_root 21 | for root, dnames, fnames in os.walk(self.capts_root): 22 | for fname in fnames: 23 | if fname.endswith('.capts'): 24 | vid = os.path.splitext(fname)[0] 25 | path = os.path.join(self.capts_root, fname) 26 | self.capt_paths[vid] = path 27 | self.fidx_size = {} # fname --> size of file 28 | self.experts = list(self.experts_info.keys()) 29 | super().__init__(**kwargs) 30 | 31 | def read_timings(self, fname, offt, nemb, blksz=4096): 32 | if fname not in self.fidx_size: 33 | fsize = os.path.getsize(fname) 34 | self.fidx_size[fname] = fsize 35 | else: 36 | fsize = self.fidx_size[fname] 37 | fname_or_f = open(fname) 38 | 39 | timings = [] 40 | buf = '' 41 | while len(timings) < nemb and offt < fsize: 42 | rsz = min(blksz, fsize - offt) 43 | b = self.read_range(fname_or_f, offt, rsz) 44 | if type(b) is bytes: 45 | b = b.decode('utf8') 46 | buf = buf + b 47 | offt += rsz 48 | idx = 0 49 | while True: 50 | idx1 = buf.find('\n', idx) 51 | if idx1 == -1: 52 | if idx > 0: 53 | buf = buf[idx:] 54 | break 55 | if idx1 == fsize - 1: 56 | break 57 | a, b = buf[idx: idx1].split('\t') 58 | idx = idx1 + 1 59 | timings.append((float(a), float(b))) 60 | if len(timings) == nemb: 61 | break 62 | if type(fname_or_f) is not str: 63 | fname_or_f.close() 64 | return np.array(timings) 65 | 66 | def read_embds(self, fname, offt, nemb, embdim): 67 | bsz = nemb * embdim * 4 68 | data = self.read_range(fname, offt, bsz) 69 | embds = np.frombuffer(data, dtype=np.float32).reshape(-1, embdim) 70 | return embds 71 | 72 | def read_range(self, fname_or_f, offt, size): 73 | if type(fname_or_f) is str: 74 | with open(fname_or_f, 'rb') as f: 75 | f.seek(offt) 76 | data = f.read(size) 77 | else: 78 | fname_or_f.seek(offt) 79 | data = fname_or_f.read(size) 80 | return data 81 | 82 | def parse_line(self, line): 83 | s = line.strip().split('\t') 84 | text = s[0] 85 | t_start = float(s[1]) 86 | t_end = float(s[2]) 87 | s1 = list(map(int, s[3:])) 88 | embd_offts = s1[0::3] 89 | idx_offts = s1[1::3] 90 | nembs = s1[2::3] 91 | return text, t_start, t_end, embd_offts, idx_offts, nembs 92 | 93 | def get_sample_data(self, vid, capidx=None, caponly=False, seed=None): 94 | # -1 return random caption and corresponding embeddings 95 | # >=0 return one caption with index=capt_Idx and corresponding embeddings 96 | # None return all embds and capts 97 | if seed is not None: 98 | rnd = np.random.RandomState(seed) 99 | else: 100 | rnd = None 101 | choice_fn = lambda arr: np_choice(rnd, arr) 102 | 103 | path = self.capt_paths[vid] 104 | captions = [] 105 | captions_t = [] 106 | captions_idxs = [] 107 | features = {} 108 | features_t = {} 109 | with open(path) as f: 110 | mod_names = f.readline().strip().split('\t') 111 | _mod_dims = f.readline().strip().split('\t') 112 | mod_dim = {mod_name: int(dim) for mod_name, dim in zip(mod_names, _mod_dims)} 113 | _embd_idx_fnames = f.readline()[:-1].split('\t') 114 | if self.fname_repl: 115 | a, b = self.fname_repl 116 | _embd_idx_fnames = [re.sub(a, b, x) for x in _embd_idx_fnames] 117 | embd_fnames = _embd_idx_fnames[0::2] 118 | idx_fnames = _embd_idx_fnames[1::2] 119 | _offt_nemb = f.readline().strip().split('\t') 120 | global_embd_offts = list(map(int, _offt_nemb[0::3])) 121 | global_idx_offts = list(map(int, _offt_nemb[1::3])) 122 | global_nembs = list(map(int, _offt_nemb[2::3])) 123 | 124 | assert len(mod_names) == len(embd_fnames) 125 | assert len(mod_names) == len(idx_fnames) 126 | assert len(mod_names) == len(global_embd_offts) 127 | assert len(mod_names) == len(global_idx_offts) 128 | assert len(mod_names) == len(global_nembs) 129 | 130 | lines = list(enumerate(f)) 131 | if capidx is not None: 132 | if capidx >= 0: 133 | selected_cap_idx, capt_line = lines[capidx] 134 | capt_line = capt_line.strip() 135 | else: 136 | selected_cap_idx, capt_line = choice_fn(lines) 137 | capt_line = capt_line.strip() 138 | text, t0, t1, embd_offts, idx_offts, nembs = self.parse_line(capt_line) 139 | captions_t.append((t0, t1)) 140 | captions.append(text) 141 | captions_idxs.append(selected_cap_idx) 142 | if not caponly: 143 | for mod_name, embd_fname, idx_fname, offt_embd, offt_idx, nemb in zip(mod_names, embd_fnames, idx_fnames, embd_offts, idx_offts, nembs): 144 | if mod_name in self.experts and nemb > 0: 145 | embdim = mod_dim[mod_name] 146 | max_tok = self.experts_info[mod_name]["max_tok"] 147 | nemb = min(max_tok, nemb) 148 | features[mod_name] = self.read_embds(embd_fname, offt_embd, nemb, embdim) 149 | features_t[mod_name] = self.read_timings(idx_fname, offt_idx, nemb) 150 | assert len(features[mod_name]) == len(features_t[mod_name]), (mod_name, embd_fname, idx_fname, offt_embd, offt_idx, nemb, vid, capidx, len(features[mod_name]), len(features_t[mod_name])) 151 | else: 152 | # read all 153 | for cap_idx, line in lines: 154 | text, t0, t1, _embd_offts, _idx_offts, _nembs = self.parse_line(line) 155 | captions.append(text) 156 | captions_t.append((t0, t1)) 157 | captions_idxs.append(cap_idx) 158 | if not caponly: 159 | for mod_name, embd_fname, idx_fname, offt_embd, offt_idx, nemb in zip(mod_names, embd_fnames, idx_fnames, global_embd_offts, global_idx_offts, global_nembs): 160 | if mod_name in self.experts and nemb > 0: 161 | embdim = mod_dim[mod_name] 162 | max_tok = self.experts_info[mod_name]["max_tok"] 163 | nemb = min(max_tok, nemb) 164 | features[mod_name] = self.read_embds(embd_fname, offt_embd, nemb, embdim) 165 | features_t[mod_name] = self.read_timings(idx_fname, offt_idx, nemb) 166 | assert len(features[mod_name]) == len(features_t[mod_name]), (vid, capidx) 167 | 168 | if caponly: 169 | return dict(captions=captions, 170 | captions_t=captions_t, 171 | captions_idxs=captions_idxs) 172 | else: 173 | return dict(captions=captions, 174 | captions_t=captions_t, 175 | captions_idxs=captions_idxs, 176 | features=features, 177 | features_t=features_t) 178 | 179 | -------------------------------------------------------------------------------- /dumper.py: -------------------------------------------------------------------------------- 1 | import os 2 | import argparse 3 | import subprocess 4 | import threading 5 | import queue 6 | 7 | from tqdm import tqdm 8 | import numpy as np 9 | 10 | from mp_utils import MpGen 11 | 12 | 13 | import multiprocessing as mp 14 | import signal 15 | import traceback 16 | import sys 17 | 18 | 19 | 20 | def proc_pack(input_it, dst_prefix): 21 | print('Started proc_pack') 22 | emb_fname = dst_prefix+'.emb' 23 | idx_fname = dst_prefix+'.idx' 24 | dname = os.path.dirname(emb_fname) 25 | os.makedirs(dname, exist_ok=True) 26 | with open(emb_fname, 'wb') as fout_emb, open(idx_fname, 'w') as fout_idx: 27 | for video_path, timings, embs in input_it: 28 | if embs is None: 29 | yield video_path 30 | continue 31 | assert len(embs) == len(timings), (len(embs), len(timings)) 32 | fout_emb.write(embs.tobytes()) 33 | fout_idx.write(f'VIDEO\t{video_path}\n') 34 | for a, b in timings: 35 | fout_idx.write(f'{a:.2f}\t{b:.2f}\n') 36 | yield video_path 37 | 38 | def read_frames(video_path, fps, frame_size, frame_crop_size, alpha_h, alpha_w, hflip=False, max_frames=None): 39 | # 1. scale to frame_size on short side 40 | # 2. crop frame_crop_size 41 | # 42 | # alpha_h, alpha_w is used for control crop position after rescale 43 | # alpha_h=0.5, alpha_w=0.5 is equivalent to center crop 44 | # alpha_h=1, alpha_w=1 is equivalent to most right most bottom crop 45 | assert 0 <= alpha_h <= 1, alpha_h 46 | assert 0 <= alpha_w <= 1, alpha_w 47 | 48 | scale_w = f'round((iw/min(iw\,ih)*{frame_size})/2)*2' 49 | scale_h = f'round((ih/min(iw\,ih)*{frame_size})/2)*2' 50 | w0 = f'round(({scale_w}-{frame_crop_size})*{alpha_w})' 51 | h0 = f'round(({scale_h}-{frame_crop_size})*{alpha_h})' 52 | crop_w = f'{frame_crop_size}' 53 | crop_h = f'{frame_crop_size}' 54 | hflip_filter = ',hflip' if hflip else '' 55 | dframes = f'-dframes {max_frames}' if max_frames else '' 56 | 57 | cmd = f"ffmpeg -y -i {video_path} -max_muxing_queue_size 9999 -loglevel error -vf 'fps={fps}:round=up,scale={scale_w}:{scale_h},crop={crop_w}:{crop_h}:{w0}:{h0}{hflip_filter}' {dframes} -pix_fmt rgb24 -f rawvideo -nostdin pipe:" 58 | p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE) 59 | while True: 60 | data = p.stdout.read(10000 * frame_crop_size*frame_crop_size*3) 61 | if not data: 62 | break 63 | yield data 64 | 65 | 66 | def read_frames_center_crop(video_path, fps, frame_size, frame_crop_size): 67 | return read_frames(video_path, fps, frame_size, frame_crop_size, alpha_h=0.5, alpha_w=0.5) 68 | 69 | def read_frames_center_crop_batch(video_path, fps, frame_size, frame_crop_size, batch_num_frames): 70 | batch_byte_size = batch_num_frames * frame_crop_size * frame_crop_size * 3 71 | data0 = b'' 72 | for data in read_frames_center_crop(video_path, fps, frame_size, frame_crop_size): 73 | if len(data0) > 0: 74 | data0 = data0 + data 75 | else: 76 | data0 = data 77 | while len(data0) > batch_byte_size: 78 | data_batch = data0[:batch_byte_size] 79 | data0 = data0[batch_byte_size:] 80 | frames = np.frombuffer(data_batch, dtype=np.uint8).reshape(-1, frame_crop_size, frame_crop_size, 3) # (nframes, h, w, c) 81 | yield frames 82 | if len(data0): 83 | frames = np.frombuffer(data0, dtype=np.uint8).reshape(-1, frame_crop_size, frame_crop_size, 3) 84 | yield frames 85 | 86 | def ffmpeg_audio_reader(in_filename): 87 | cmd = f'ffmpeg -i {in_filename} -loglevel quiet -f wav -nostdin pipe:' 88 | p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE) 89 | all_data = b'' 90 | while True: 91 | data = p.stdout.read(1024**2) 92 | if not data: 93 | break 94 | all_data += data 95 | if len(all_data) == 0: 96 | return None 97 | else: 98 | return all_data 99 | 100 | class AudioDecoder: 101 | def __init__(self, input_it, num_workers=2): 102 | self.input_it = input_it 103 | self.workers = [] 104 | self.q = queue.Queue() 105 | self.num_running_workers = num_workers 106 | import warnings 107 | warnings.filterwarnings("ignore") 108 | for _ in range(num_workers): 109 | th = threading.Thread(target=self.worker_decoder) 110 | th.start() 111 | self.workers.append(th) 112 | 113 | def worker_decoder(self): 114 | import vggish.vggish_input as vggish_input 115 | import io 116 | import scipy.io.wavfile as scio 117 | 118 | for path in self.input_it: 119 | wav = ffmpeg_audio_reader(path) 120 | if wav is None: 121 | # no audio channel 122 | timings, segms = None, None 123 | else: 124 | sr, data = scio.read(io.BytesIO(wav)) 125 | data = data / 32768.0 126 | segms = vggish_input.waveform_to_examples(data, sr) 127 | t_start = np.arange(len(segms), dtype=np.float32) * 0.96 128 | t_end = t_start + 0.96 129 | timings = np.concatenate([t_start[..., None], t_end[..., None]], axis=1) # (nsegm, 2) 130 | self.q.put((path, timings, segms)) 131 | self.q.put(None) 132 | 133 | def __iter__(self): 134 | return self 135 | 136 | def __next__(self): 137 | while True: 138 | data = self.q.get() 139 | if data is None: 140 | self.num_running_workers -= 1 141 | if self.num_running_workers == 0: 142 | for th in self.workers: 143 | th.join() 144 | raise StopIteration 145 | continue 146 | return data 147 | 148 | 149 | def proc_dumper_video_1( 150 | input_it, 151 | fps, 152 | frame_size, 153 | frame_crop_size, 154 | frames_per_clip, 155 | per_batch_size, 156 | model, 157 | lock, 158 | q_out): 159 | for path in input_it: 160 | frames_batch_iter = read_frames_center_crop_batch( 161 | video_path=path, 162 | fps=fps, 163 | frame_size=frame_size, 164 | frame_crop_size=frame_crop_size, 165 | batch_num_frames=per_batch_size*frames_per_clip) 166 | # frames_batch_iter: (-1, h, w, c) 167 | embs = [] 168 | timings = [] 169 | t = 0 170 | delta = frames_per_clip / fps 171 | for frames in frames_batch_iter: 172 | if len(frames) % frames_per_clip > 0: 173 | n = len(frames) 174 | n1 = int(len(frames) // frames_per_clip * frames_per_clip) 175 | frames1 = frames[:n1] 176 | # increase frame rate in the last video segment 177 | idxs = np.ceil(np.linspace(n1, n-1, frames_per_clip)).astype(np.long) 178 | frames2 = frames[idxs] 179 | frames = np.concatenate([frames1, frames2], axis=0) 180 | assert len(frames) % frames_per_clip == 0 181 | batch_frames = frames.reshape(-1, frames_per_clip, frame_crop_size, frame_crop_size, 3) 182 | for _ in range(len(batch_frames)): 183 | timings.append((t, t + delta)) 184 | t += delta 185 | with lock: 186 | embs.append(model(batch_frames)) 187 | if len(embs) > 0: 188 | embs = np.concatenate(embs, axis=0) 189 | timings = np.array(timings) # (nsegm, 2) 190 | else: 191 | print(f'Nothing decoded: {path}') 192 | embs = None 193 | timings = None 194 | q_out.put((path, timings, embs)) 195 | q_out.put(None) 196 | 197 | 198 | def proc_dumper_video( 199 | input_it, 200 | gpu, 201 | fps, 202 | frame_size, 203 | frame_crop_size, 204 | frames_per_clip, 205 | model_type, 206 | per_batch_size, 207 | num_readers=2): 208 | os.environ['CUDA_VISIBLE_DEVICES'] = f'{gpu}' 209 | if model_type == 'VMZ_irCSN_152': 210 | from models.vmz_model import VMZ_irCSN_152 211 | model = VMZ_irCSN_152('ckpts/irCSN_152_ig65m_from_scratch_f125286141.pth') 212 | elif model_type == 'CLIP': 213 | from models.clip_model import CLIP 214 | model = CLIP() 215 | else: 216 | raise NotImplementedError 217 | lock = threading.Lock() 218 | q = queue.Queue(20) 219 | threads = [] 220 | for _ in range(num_readers): 221 | th = threading.Thread(target=proc_dumper_video_1, kwargs=dict( 222 | input_it=input_it, 223 | fps=fps, 224 | frame_size=frame_size, 225 | frame_crop_size=frame_crop_size, 226 | frames_per_clip=frames_per_clip, 227 | per_batch_size=per_batch_size, 228 | model=model, 229 | lock=lock, 230 | q_out=q)) 231 | th.start() 232 | threads.append(th) 233 | num_alive = num_readers 234 | while num_alive > 0: 235 | x = q.get() 236 | if x is None: 237 | num_alive -= 1 238 | continue 239 | yield x 240 | for th in threads: 241 | th.join() 242 | 243 | 244 | 245 | def proc_dumper_audio( 246 | input_it, 247 | gpu, 248 | model_type, 249 | per_batch_size): 250 | os.environ['CUDA_VISIBLE_DEVICES'] = f'{gpu}' 251 | if model_type == 'tf_vggish': 252 | #print(f'DEVICE: {gpu}') 253 | #import tensorflow as tf 254 | #device = tf.config.list_physical_devices('GPU')[gpu] 255 | #tf.config.set_visible_devices([device], 'GPU') 256 | from models.vggish_model import VGGish 257 | model = VGGish('ckpts/vggish_model.ckpt', per_batch_size=per_batch_size) 258 | else: 259 | raise NotImplementedError 260 | 261 | loader = AudioDecoder(input_it=input_it, num_workers=1) 262 | for path, timings, frames in loader: 263 | if frames is None: 264 | yield path, timings, None 265 | continue 266 | embs = [] 267 | idxs = range(0, len(frames), per_batch_size) 268 | for idx in idxs: 269 | batch = frames[idx: idx + per_batch_size] 270 | embs.append(model(batch)) 271 | if len(embs) > 0: 272 | embs = np.concatenate(embs, axis=0) 273 | yield path, timings, embs 274 | else: 275 | yield path, None, None 276 | 277 | 278 | def main(): 279 | parser = argparse.ArgumentParser() 280 | parser.add_argument('--model_type', required=True, choices=['CLIP', 'VMZ_irCSN_152', 'tf_vggish']) 281 | parser.add_argument('--gpus', type=lambda x: list(map(int, x.split(','))), default=[0,1,2,3,4,5,6,7]) 282 | parser.add_argument('--dst_prefix', required=True) 283 | parser.add_argument('--lst', help='each line is path to video file', required=True) 284 | parser.add_argument('--nworker_per_gpu', type=int, default=4) 285 | parser.add_argument('--num_readers', type=int, default=2) 286 | parser.add_argument('--per_batch_size', type=int, default=8) 287 | parser.add_argument('--fps', type=int, default=30) 288 | parser.add_argument('--frame_size', type=int, default=256) 289 | parser.add_argument('--frame_crop_size', type=int, default=224) 290 | parser.add_argument('--frames_per_clip', type=int, default=30) 291 | args = parser.parse_args() 292 | 293 | lst = [] # paths to video files 294 | with open(args.lst) as f: 295 | for line in f: 296 | path = line.strip() 297 | if not path: 298 | continue 299 | lst.append(path) 300 | 301 | g0 = lst 302 | 303 | num_workers_dumper = len(args.gpus)*args.nworker_per_gpu 304 | if args.model_type in ['CLIP', 'VMZ_irCSN_152']: 305 | proc_dumper_fn = lambda input_it, rank: proc_dumper_video( 306 | input_it=input_it, 307 | gpu=args.gpus[rank % len(args.gpus)], 308 | fps=args.fps, 309 | frame_size=args.frame_size, 310 | frame_crop_size=args.frame_crop_size, 311 | frames_per_clip=args.frames_per_clip, 312 | model_type=args.model_type, 313 | per_batch_size=args.per_batch_size, 314 | num_readers=args.num_readers) 315 | elif args.model_type in ['tf_vggish']: 316 | proc_dumper_fn = lambda input_it, rank: proc_dumper_audio( 317 | input_it=input_it, 318 | gpu=args.gpus[rank % len(args.gpus)], 319 | model_type=args.model_type, 320 | per_batch_size=args.per_batch_size) 321 | g1 = MpGen(g0, 322 | proc_dumper_fn, 323 | num_workers=num_workers_dumper, 324 | streaming_mode=True) 325 | 326 | proc_pack_fn = lambda input_it, rank: proc_pack( 327 | input_it=input_it, 328 | dst_prefix=args.dst_prefix) 329 | g2 = MpGen(g1, proc_pack_fn, num_workers=1, streaming_mode=True) 330 | 331 | for _ in tqdm(g2, total=len(g0)): 332 | pass 333 | 334 | 335 | 336 | if __name__ == "__main__": 337 | main() 338 | -------------------------------------------------------------------------------- /duplicate_lists/README.md: -------------------------------------------------------------------------------- 1 | In out [work](https://arxiv.org/abs/2103.10699) we concatenate training parts of many popular datasets. The single large training dataset is created. 2 | It is important to be sure that there is not intersection between resulting large training dataset and original test sets. 3 | 4 | We manually intersected by embeddings test parts of MSRVTT (full split), LSMDC (publictest) and ActivityNet (val1+val2) with 5 | all datasets mentioned in table below. Numbers in cells represent how many pairs we managed to find in intersection between two given datasets. 6 | 7 | | | ActivityNet | LSMDC | MSRVTT | 8 | |---|---|---|---| 9 | |ActivityNet|181|0|12| 10 | |LSMDC|0|-|17| 11 | |MSRVTT|8|0|281| 12 | |MSVD|1|1|1| 13 | |TGIF|0|0|8| 14 | |TwitterVines|0|0|3| 15 | |YouCook2|10|0|34| 16 | |Kinetics700|235|0|1| 17 | |HowTo100M|-|-|21| 18 | 19 | Sign `-` means that due to lack of human resources we do not find intersection between given pair of datasets. 20 | 21 | In this work we try to find duplicates and pseudo duplicates. 22 | 23 | We say that video segments S1 and S2 are duplicates if 24 | the same content is present on both of them. S1 and S2 may have different aspect ratio, brightness, presence/absence of logo, 25 | S1 and S2 may be two different crops from the same video segment or may have different quality. For example. 26 | 27 | 28 | ![](dup1.jpg) 29 | ![](dup2.jpg) 30 | 31 | 32 | We say that two video segments S1, S2 are pseudo duplicates if very similar things are present on both of them. 33 | For example: the same background and the same person are presented on both S1 and S2. The example of pseudo duplicate 34 | (the first one from ActivityNet val, the second one from ActivityNet train) are depicted on figures below. 35 | 36 | ![](pseudo_dup1.jpg) 37 | ![](pseudo_dup2.jpg) 38 | 39 | 40 | In `lists` sub folder we present all found duplicates. The filenames have format: `_.lst`. 41 | Each line has structure : `\t\t\t\t\t\n`. 42 | Values ``, ``, ``, `` are time in second where duplicate segment starts and ends. 43 | 44 | 45 | For some duplicate pairs start, end offsets may be incorrect. In this case duplicate segment can be 46 | 5-10 second left or right. 47 | 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /duplicate_lists/dup1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/papermsucode/mdmmt/1741ce301037d4ddfa9836854cdca1fade364d1b/duplicate_lists/dup1.jpg -------------------------------------------------------------------------------- /duplicate_lists/dup2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/papermsucode/mdmmt/1741ce301037d4ddfa9836854cdca1fade364d1b/duplicate_lists/dup2.jpg -------------------------------------------------------------------------------- /duplicate_lists/lists/ActivityNet_ActivityNet.lst: -------------------------------------------------------------------------------- 1 | DepG0r3JiV4.mp4 15 17 xzoquwJYEZw.mp4 15 17 2 | SLisp6hn700.mp4 5 7 dH_gpSfaA6E.mp4 5 7 3 | dwCeFVAaP9c.mp4 131 133 mLijl36SjJU.mp4 131 133 4 | szl1InYab_k.mp4 0 2 kC8DS6b76yI.mp4 0 2 5 | 2HmhRdKRVb4.mp4 0 2 fM4pJeHb8hQ.mp4 0 2 6 | Px08sPeSsG0.mp4 11 13 nLddpveoSHE.mp4 11 13 7 | 2HmhRdKRVb4.mp4 0 2 WXMb7XF6k8o.mp4 0 2 8 | H91Dm6jaUPg.mp4 7 9 fRUoSevi63M.mp4 7 9 9 | H91Dm6jaUPg.mp4 7 9 -YjGbsbDoxs.mp4 7 9 10 | akwJwcvfjLA.mp4 13 15 xzoquwJYEZw.mp4 13 15 11 | mUyMYnGXKgk.mp4 0 2 KV0L45xelkE.mp4 0 2 12 | D1E_KJRxGvQ.mp4 84 86 W6y6Vmk5edg.mp4 74 76 13 | H91Dm6jaUPg.mp4 7 9 o6lTgyb_AkM.mp4 7 9 14 | H91Dm6jaUPg.mp4 7 9 tokwDYW6rS0.mp4 7 9 15 | Px08sPeSsG0.mp4 10 12 IN8-B39kq_k.mp4 10 12 16 | Dzj5X11anrk.mp4 20 22 tL90IPP3hbA.mp4 20 22 17 | T8ae3_Pm5eE.mp4 15 17 99dCcB5Unmo.mp4 15 17 18 | nXNczyQpljQ.mp4 113 115 cBCi-pOE5NQ.mp4 135 137 19 | qiRrR2Nj2SQ.mp4 15 17 Q5kU3DUXXZg.mp4 15 17 20 | mUyMYnGXKgk.mp4 0 2 Db6sq4DjW7E.mp4 0 2 21 | 5KYUiMysyb0.mp4 18 20 0WJX2A6PSnA.mp4 18 20 22 | 3TxZTZEEg44.mp4 137 139 gCxLSh-cgng.mp4 122 124 23 | IJ76Wtgg2g4.mp4 83 85 62h9hnNTKWM.mp4 83 85 24 | IJ76Wtgg2g4.mp4 83 85 PXBcPu2_KOo.mp4 84 86 25 | mhYFpct97UE.mp4 6 8 xJNqBSJ7rqU.mp4 6 8 26 | iUGuDzgow2I.mp4 39 41 aeEMrTpNUss.mp4 25 27 27 | n3v9Znovl98.mp4 144 146 B-nlhZ0RR4A.mp4 64 66 28 | ybkcKusf-Kg.mp4 21 23 aeEMrTpNUss.mp4 25 27 29 | ybkcKusf-Kg.mp4 21 23 5kBKAfEX7XA.mp4 40 42 30 | QVdsLRKpCT0.mp4 52 54 aeEMrTpNUss.mp4 25 27 31 | R8WbSI3m1lI.mp4 0 2 H8MY7XGrN6Q.mp4 7 9 32 | lfH_S2LTEXA.mp4 75 77 fY2IeYSxY4U.mp4 161 163 33 | AISkvED80lU.mp4 51 53 3l7quTy4c2s.mp4 55 57 34 | rMy6sItJID0.mp4 69 71 CB41iJu4ZVY.mp4 61 63 35 | i1CVl-0-gJE.mp4 23 25 V2PhVadSbpQ.mp4 23 25 36 | T8ae3_Pm5eE.mp4 16 18 IdhpB7doBOE.mp4 16 18 37 | W8ayZca_fAY.mp4 43 45 XoCvj2IbVGE.mp4 213 215 38 | D1E_KJRxGvQ.mp4 53 55 0kykNR9FUWU.mp4 85 87 39 | IJ76Wtgg2g4.mp4 83 85 FoPNGc6Lg8k.mp4 64 66 40 | TOP1Fwili-k.mp4 9 11 4ZyPBOe4P0U.mp4 9 11 41 | cjUz6gVQPEs.mp4 78 80 gtd2Ye-raxE.mp4 57 59 42 | MC0L0ljTUiw.mp4 168 170 J_SD_hhGET8.mp4 168 170 43 | AmWcQz_KJG4.mp4 15 17 iWj81FBROQQ.mp4 38 40 44 | NBXH7A2EO7Q.mp4 85 87 RTIzzeNaH2Q.mp4 141 143 45 | mhYFpct97UE.mp4 6 8 R2cL7miVEwA.mp4 6 8 46 | vL8s-b4eJiU.mp4 79 81 PaPR1XQU0_A.mp4 92 94 47 | AmWcQz_KJG4.mp4 62 64 CB41iJu4ZVY.mp4 61 63 48 | YfxK4HAp8jI.mp4 22 24 y3Wfx-RvTpk.mp4 12 14 49 | nXNczyQpljQ.mp4 86 88 nDbLtdY66dA.mp4 38 40 50 | jzCnWUUUviE.mp4 7 9 35DlDj_hzvg.mp4 5 7 51 | aBdrTqSnWbw.mp4 14 16 erevt6avST0.mp4 14 16 52 | lyJpgvmTOpo.mp4 2 4 37Q3so6ERxs.mp4 2 4 53 | Likt_9dbMqE.mp4 132 134 LHjmL7Pg_80.mp4 132 134 54 | mbGpp_nDwI4.mp4 80 82 SO67XxdevPw.mp4 20 22 55 | M-n0vW3p2sE.mp4 16 18 VgQ6a7oVx7g.mp4 19 21 56 | OqLUp37WKMA.mp4 6 8 t6FuJ4L8sHY.mp4 23 25 57 | 9A3z0W8U124.mp4 84 86 m210FwMsnTQ.mp4 16 18 58 | mbGpp_nDwI4.mp4 32 34 PUHGXI6N0DA.mp4 41 43 59 | mbGpp_nDwI4.mp4 31 33 fxxeCpqgRfk.mp4 44 46 60 | xqzsv8VpaNM.mp4 31 33 cMoy7UJtlyA.mp4 48 50 61 | eXMF6Skt2To.mp4 19 21 _Af_9cK5x4E.mp4 94 96 62 | EbQJuDQdW8U.mp4 1 3 EgPk-mmJyS8.mp4 1 3 63 | k7MXH55q28U.mp4 44 46 30y8Uy0B_uk.mp4 17 19 64 | dFVX_2UQ2WY.mp4 45 47 7j8cTyXi5a4.mp4 73 75 65 | qkk2tK19sx8.mp4 25 27 sRgBK2_nb0I.mp4 21 23 66 | M-n0vW3p2sE.mp4 16 18 71vVRQ4l8OI.mp4 42 44 67 | 9A3z0W8U124.mp4 84 86 V5MvrOzQWZo.mp4 60 62 68 | otWTm1_aAqI.mp4 23 25 V1ntLwOfkyE.mp4 17 19 69 | fJNauQt9Di0.mp4 121 123 K-eZfCs8yOc.mp4 47 49 70 | otWTm1_aAqI.mp4 24 26 AWXdK-ix3gQ.mp4 9 11 71 | mbGpp_nDwI4.mp4 32 34 vWGkTOLx57s.mp4 30 32 72 | 4o8MaHTb7E4.mp4 0 2 3hp7kPpZDhs.mp4 25 27 73 | 7DJDUzdw_I4.mp4 8 10 SO67XxdevPw.mp4 20 22 74 | Tab-dSCaMC8.mp4 40 42 mS7SAG1nW1o.mp4 50 52 75 | M_WEOecjwLY.mp4 2 4 7EEpIeXhO54.mp4 116 118 76 | 7DJDUzdw_I4.mp4 8 10 fxxeCpqgRfk.mp4 33 35 77 | tqqWTxQ5-kY.mp4 2 4 gUFRtx51OJc.mp4 2 4 78 | 7DJDUzdw_I4.mp4 8 10 XftM9eALPy0.mp4 49 51 79 | Tab-dSCaMC8.mp4 11 13 _032TQam_mY.mp4 13 15 80 | dAcdSkaoK64.mp4 63 65 GQzwzOM9db8.mp4 5 7 81 | Nj_rPQwzllA.mp4 126 128 NnEUVHhtLZs.mp4 60 62 82 | OjV4UScwkU0.mp4 62 64 RW-nnJiVPsU.mp4 62 64 83 | 0zjA3KPnLK8.mp4 46 48 wOwWidUOaxc.mp4 46 48 84 | _MR8G1jwM4o.mp4 149 151 MEbEcvzdytY.mp4 71 73 85 | j7fPZQE3-fQ.mp4 2 4 gUFRtx51OJc.mp4 2 4 86 | mk3srKjFB3A.mp4 30 32 sRgBK2_nb0I.mp4 29 31 87 | 9-yueOtwiL8.mp4 65 67 lkSkFmHYdtI.mp4 11 13 88 | uJuGXnGqozs.mp4 23 25 RxuL7k7-hYQ.mp4 88 90 89 | 1cLxW-FhgpA.mp4 6 8 gXKGS1N3zuM.mp4 5 7 90 | BwR1DPCVsP8.mp4 123 125 IGcalXmWUwA.mp4 95 97 91 | 91XkPU8A5hs.mp4 55 57 YoXZfvf5Teg.mp4 226 228 92 | YNQphOFqDOA.mp4 9 11 rKnQNI9PNFI.mp4 17 19 93 | aBdrTqSnWbw.mp4 15 17 W6Sz8ajVsjc.mp4 15 17 94 | RAluocUocdw.mp4 60 62 I5QbY8vlR54.mp4 38 40 95 | BwR1DPCVsP8.mp4 10 12 XToVLTbQEm4.mp4 10 12 96 | 7RESODKApso.mp4 26 28 K_0DLTcFy-8.mp4 26 28 97 | aBdrTqSnWbw.mp4 15 17 oO6jZR9Aijc.mp4 15 17 98 | -jNouTszLJ0.mp4 21 23 LHiui4s2X1s.mp4 18 20 99 | GkwkHQJifDU.mp4 2 4 1V0TqgcXSVk.mp4 10 12 100 | apjGHMrnMV0.mp4 144 146 _j5JUQzOCtc.mp4 79 81 101 | pzkwJYJol7o.mp4 93 95 dEUFGAwRhEM.mp4 207 209 102 | eBlYGGmeBY0.mp4 50 52 60CCYfec2vQ.mp4 54 56 103 | AauepSs1kUU.mp4 49 51 8eDJXDetgGE.mp4 160 162 104 | cyznGwlE9hM.mp4 156 158 EZZzVXqxG6U.mp4 73 75 105 | 7ih5UMIU7zE.mp4 132 134 yCAsVc5Tb_0.mp4 47 49 106 | aYSJn94g_Io.mp4 33 35 P6t2HLPZ3Dk.mp4 11 13 107 | 91XkPU8A5hs.mp4 65 67 1o-Fx2dGfpc.mp4 10 12 108 | 2lUqeOw61QY.mp4 47 49 dtT0BzjTStw.mp4 23 25 109 | YfxK4HAp8jI.mp4 37 39 dtT0BzjTStw.mp4 65 67 110 | lOtplLrtapE.mp4 47 49 Ap7GCrt9C4w.mp4 97 99 111 | 2lUqeOw61QY.mp4 47 49 y3Wfx-RvTpk.mp4 30 32 112 | ePaFTey15ho.mp4 183 185 BLmAF2wbTz8.mp4 6 8 113 | AISkvED80lU.mp4 52 54 Ch_qHjUtOpE.mp4 4 6 114 | OqLUp37WKMA.mp4 6 8 dfex2oZYqmU.mp4 18 20 115 | eZbdiuUu0S8.mp4 187 189 0hWGSkDnRHA.mp4 14 16 116 | aa0MLYA8F7s.mp4 35 37 2_tzemKY72E.mp4 32 34 117 | gIgim1Dp8HU.mp4 2 4 Qg3Lih9PTBM.mp4 2 4 118 | n3v9Znovl98.mp4 45 47 1sA-lEbrgak.mp4 24 26 119 | 91XkPU8A5hs.mp4 59 61 0bjHe_5nACw.mp4 106 108 120 | WXEq3OeD68o.mp4 22 24 kI6maggAugg.mp4 60 62 121 | MiOJxYa5Nt4.mp4 6 8 Q48_MDiak-w.mp4 4 6 122 | gLfvk2SSj1c.mp4 62 64 q4rVY3sLQqA.mp4 28 30 123 | eXMF6Skt2To.mp4 118 120 4XGQR2VmWpw.mp4 129 131 124 | AMMECm7Huhk.mp4 140 142 zU6SnkNIdrw.mp4 140 142 125 | APAxAnwS9oM.mp4 97 99 FIzlf7jdsUY.mp4 144 146 126 | VFqkLp5mzBM.mp4 28 30 uqT5jtfx8x0.mp4 20 22 127 | j1XZ3FA8EYY.mp4 148 150 LHjmL7Pg_80.mp4 86 88 128 | 6NqS3vYvf6Q.mp4 143 145 q2TF-3bWZuU.mp4 119 121 129 | lfH_S2LTEXA.mp4 127 129 30y8Uy0B_uk.mp4 85 87 130 | K0MzjnMzbj4.mp4 164 166 XToVLTbQEm4.mp4 162 164 131 | AJ15GW-sS5M.mp4 51 53 cByxAZfw_hM.mp4 31 33 132 | CRdgzvZxB8A.mp4 45 47 2bEr09bbqAA.mp4 53 55 133 | JLDZdxTf5TA.mp4 64 66 RgzbNJPchqc.mp4 45 47 134 | tCQiu-qY9XA.mp4 35 37 _dLbtK8_SHo.mp4 149 151 135 | FU0EPNGKsv8.mp4 47 49 Db6sq4DjW7E.mp4 35 37 136 | 4sm-tTbfamM.mp4 110 112 CHaTWk6uqd8.mp4 227 229 137 | lfH_S2LTEXA.mp4 21 23 9ZQY-ZfimYo.mp4 18 20 138 | DXhVbxfmrYM.mp4 28 30 rVYuVW9tB3U.mp4 28 30 139 | LqCg09IRp-o.mp4 22 24 pExl_cwmT8M.mp4 22 24 140 | as7KugARkLE.mp4 4 6 OJJMEEsOdPQ.mp4 3 5 141 | uJuGXnGqozs.mp4 37 39 rBnygEUFOvE.mp4 27 29 142 | AJ15GW-sS5M.mp4 98 100 UCZGbQFg6io.mp4 44 46 143 | 2Voht8wf3dQ.mp4 101 103 4taBobzpYNU.mp4 103 105 144 | UcI4miTi0Cg.mp4 31 33 t6FuJ4L8sHY.mp4 35 37 145 | GkwkHQJifDU.mp4 12 14 02yDi9BaDO8.mp4 34 36 146 | niqc-dW54ic.mp4 12 14 PdNb0g36a6U.mp4 63 65 147 | vWde8sMxe1w.mp4 10 12 VCg6_fuipp8.mp4 3 5 148 | sWtwatYMbX0.mp4 10 12 DHfiz3MNbcc.mp4 56 58 149 | 70bS0DkAeDo.mp4 14 16 8TDYCXqSHCw.mp4 12 14 150 | -wXbBZDSIa8.mp4 11 13 jFp6ld_IGuY.mp4 16 18 151 | TUfYisuVrs0.mp4 1 3 gHhgZ0Bd4H4.mp4 212 214 152 | hGziyfXmotc.mp4 10 12 nvFtFFJXxB0.mp4 10 12 153 | igrjxhf0XyY.mp4 32 34 hKn_RK3VSAo.mp4 18 20 154 | igrjxhf0XyY.mp4 32 34 MjHlAvy2qVY.mp4 18 20 155 | lfH_S2LTEXA.mp4 27 29 jVM8v6uJx8c.mp4 38 40 156 | RpH774VD6Hw.mp4 78 80 FbvTQ1-FCag.mp4 149 151 157 | vL8s-b4eJiU.mp4 162 164 rVmNL8rzHnU.mp4 154 156 158 | hDPLy21Yyuk.mp4 2 4 F2x2fynkbAQ.mp4 1 3 159 | lCIJJgxTs2U.mp4 10 12 lGPUCwHjiK0.mp4 4 6 160 | sWtwatYMbX0.mp4 10 12 ACki-MP9qdQ.mp4 10 12 161 | uMGfCaGMnEE.mp4 59 61 1BfYAuxv6Wk.mp4 12 14 162 | _RCe4Q0p1aA.mp4 46 48 DU2hdNIS2WI.mp4 15 17 163 | O-YKLVm0ciI.mp4 200 202 hR6VFvMXCN4.mp4 0 2 164 | 5dXi-tAGqbs.mp4 28 30 YH3571KWDpM.mp4 124 126 165 | -voGnJbk3CI.mp4 10 12 XSDIekFXkv0.mp4 27 29 166 | sWtwatYMbX0.mp4 10 12 1BfYAuxv6Wk.mp4 12 14 167 | Likt_9dbMqE.mp4 143 145 lzQwtmUrSK4.mp4 113 115 168 | JLDZdxTf5TA.mp4 97 99 h9WOFfVGeAQ.mp4 6 8 169 | sWtwatYMbX0.mp4 10 12 Rl6US0JizDs.mp4 27 29 170 | sWtwatYMbX0.mp4 10 12 0ivHmKR8cUw.mp4 24 26 171 | uMGfCaGMnEE.mp4 59 61 0ivHmKR8cUw.mp4 57 59 172 | AJ15GW-sS5M.mp4 146 148 VM-ldOw7e4Y.mp4 62 64 173 | niqc-dW54ic.mp4 12 14 e1TfVkNgitY.mp4 33 35 174 | 1cLxW-FhgpA.mp4 129 131 3K62qZ2hGyw.mp4 125 127 175 | Z9k8GiGjkZ8.mp4 1 3 BOqca4eckEs.mp4 1 3 176 | Vncj0EkAGio.mp4 48 50 pvFviIF1VGc.mp4 35 37 177 | cKMGacBQX0E.mp4 0 2 P49Ci0Ph8eU.mp4 0 2 178 | y9kk0ptXevk.mp4 10 12 7j8cTyXi5a4.mp4 12 14 179 | sWtwatYMbX0.mp4 22 24 Ygt3z-K-ZMQ.mp4 29 31 180 | 5wQLpjdsRUg.mp4 12 14 Oheg1qwrESg.mp4 52 54 181 | UH_z4C6sv3E.mp4 12 14 XLsuG0cNl4o.mp4 48 50 182 | -------------------------------------------------------------------------------- /duplicate_lists/lists/ActivityNet_Kinetics700.lst: -------------------------------------------------------------------------------- 1 | Vhf-vNRYQEg.mp4 55 57 279487.mp4 5 7 2 | R_TRpIHkgMs.mp4 62 64 113870.mp4 3 5 3 | O9phka35v6I.mp4 60 62 211837.mp4 5 7 4 | B_PhHrBEeNI.mp4 118 120 100378.mp4 0 2 5 | DYwF_1xX4dU.mp4 154 156 116972.mp4 3 5 6 | DYwF_1xX4dU.mp4 96 98 182754.mp4 7 9 7 | ZefWc2tgltY.mp4 12 14 182754.mp4 5 7 8 | WN5EWPfDbog.mp4 3 5 285299.mp4 2 4 9 | Sjx7K9Ybx9Q.mp4 8 10 253572.mp4 7 9 10 | 4yZ1agUX004.mp4 89 91 44804.mp4 4 6 11 | dFsFL_WJasg.mp4 19 21 352432.mp4 5 7 12 | fKDl_CnA8nY.mp4 71 73 370322.mp4 8 10 13 | IEtCboPbTXI.mp4 60 62 158392.mp4 7 9 14 | WJfMz7joX4s.mp4 54 56 284881.mp4 8 10 15 | 5rVXCKLihyg.mp4 56 58 51761.mp4 3 5 16 | 0RIc6mwDRaQ.mp4 51 53 10704.mp4 7 9 17 | akwJwcvfjLA.mp4 19 21 117949.mp4 6 8 18 | DepG0r3JiV4.mp4 21 23 117949.mp4 8 10 19 | SipyRTPgdfY.mp4 14 16 253420.mp4 1 3 20 | 30Yk_1Yc7Vk.mp4 18 20 30039.mp4 7 9 21 | C_2EFIuyDSA.mp4 33 35 108685.mp4 4 6 22 | vGKdr_au240.mp4 32 34 232679.mp4 8 10 23 | K6Tm5xHkJ5c.mp4 50 52 169949.mp4 0 2 24 | K6Tm5xHkJ5c.mp4 50 52 126681.mp4 0 2 25 | ZU4Mgdd3omA.mp4 9 11 311294.mp4 7 9 26 | LkUnT9fMIXc.mp4 17 19 189845.mp4 7 9 27 | QhiKgeJV3k0.mp4 82 84 182473.mp4 1 3 28 | Vnj0j648Emw.mp4 8 10 280300.mp4 8 10 29 | DYwF_1xX4dU.mp4 158 160 266879.mp4 0 2 30 | 0KqeKi2CBqg.mp4 53 55 9962.mp4 2 4 31 | bH-S32gOlCA.mp4 182 184 335622.mp4 8 10 32 | -MB6Wxglgzw.mp4 8 10 2718.mp4 3 5 33 | Yk3pQ18So90.mp4 135 137 305102.mp4 6 8 34 | KyrDumISv4A.mp4 4 6 182466.mp4 0 2 35 | dAiqJJKezPE.mp4 26 28 351684.mp4 2 4 36 | f6j6lb0AaxM.mp4 52 54 368130.mp4 8 10 37 | krFle3KU4Ts.mp4 25 27 100084.mp4 4 6 38 | eRN5gqZFXHI.mp4 141 143 362393.mp4 1 3 39 | L963epA4MFU.mp4 20 22 184380.mp4 3 5 40 | AZn294ubbps.mp4 92 94 91806.mp4 2 4 41 | cz2ESqP3PDk.mp4 12 14 349733.mp4 4 6 42 | CFBmZ1g16H8.mp4 85 87 106248.mp4 8 10 43 | e4XYZAs7tcs.mp4 6 8 358985.mp4 1 3 44 | 3-_Eld2NwJ0.mp4 32 34 29908.mp4 4 6 45 | szl1InYab_k.mp4 16 18 175633.mp4 6 8 46 | IqRN2sOQ7Mo.mp4 109 111 163669.mp4 6 8 47 | 1VBg21aaiKM.mp4 73 75 18739.mp4 3 5 48 | Tc0nHNkf0KM.mp4 5 7 261120.mp4 3 5 49 | A8NAj6NQ5vM.mp4 4 6 88267.mp4 3 5 50 | PoamN_DEInI.mp4 15 17 226993.mp4 8 10 51 | 1RVu0qNtWCc.mp4 128 130 18339.mp4 2 4 52 | Khxa5Ey3udM.mp4 88 90 180367.mp4 5 7 53 | 6O5UcjQMwoQ.mp4 15 17 55932.mp4 1 3 54 | W8ayZca_fAY.mp4 123 125 283182.mp4 2 4 55 | HsGz6S2MBU4.mp4 6 8 154949.mp4 3 5 56 | DjT4-5H3xDQ.mp4 32 34 118636.mp4 5 7 57 | bY-4XBIGiwI.mp4 89 91 337759.mp4 0 2 58 | 3L0MnbQkLWM.mp4 77 79 32584.mp4 1 3 59 | WuO75Sb0Kgg.mp4 59 61 289498.mp4 6 8 60 | IK9kE9IrcOM.mp4 40 42 159183.mp4 5 7 61 | JFBd-R1YuXY.mp4 80 82 167515.mp4 5 7 62 | fJCkM6secVM.mp4 184 186 370184.mp4 8 10 63 | QCeGGnd4QB0.mp4 13 15 230689.mp4 5 7 64 | b4DhjwkO-b4.mp4 4 6 333773.mp4 2 4 65 | RF0ChBe9HHI.mp4 72 74 328083.mp4 1 3 66 | -DGsqL65o4k.mp4 33 35 292419.mp4 0 2 67 | YNnyUVFE4uM.mp4 48 50 302215.mp4 3 5 68 | djpr7UMlnSw.mp4 11 13 356242.mp4 7 9 69 | 5ayMRPi7Lg4.mp4 9 11 49720.mp4 1 3 70 | D0RDF1ez-8Y.mp4 85 87 112204.mp4 5 7 71 | YYmx8EHIjAE.mp4 34 36 303364.mp4 1 3 72 | altXks0a0qY.mp4 0 2 331251.mp4 0 2 73 | NWaMWZUuTZc.mp4 28 30 205833.mp4 8 10 74 | 8Da6w-Eg3Ko.mp4 224 226 71177.mp4 7 9 75 | QDTo_ss6INM.mp4 86 88 230816.mp4 0 2 76 | KBMvitQaXzE.mp4 20 22 175760.mp4 5 7 77 | fCLnOf-YjEI.mp4 45 47 369146.mp4 4 6 78 | KfzVxgHEyzI.mp4 10 12 180065.mp4 2 4 79 | RihO8i98QJg.mp4 145 147 244315.mp4 8 10 80 | G8dCenteoT0.mp4 12 14 139549.mp4 4 6 81 | J1fcLhB-Slg.mp4 5 7 165163.mp4 0 2 82 | Pt5jMqQXTZ8.mp4 8 10 227528.mp4 7 9 83 | -MldnTjJ-zE.mp4 165 167 2787.mp4 2 4 84 | ruNII4WvE3k.mp4 16 18 267602.mp4 4 6 85 | ZYcZZJ0XItM.mp4 99 101 311754.mp4 1 3 86 | xIhTY02lRSE.mp4 31 33 177763.mp4 6 8 87 | DAv8CEings8.mp4 30 32 113866.mp4 6 8 88 | IHpBwsyMT9Q.mp4 38 40 158829.mp4 3 5 89 | NBXH7A2EO7Q.mp4 75 77 202966.mp4 1 3 90 | 5j5_YV25cFA.mp4 33 35 50785.mp4 0 2 91 | 7xpkFhlxo2Q.mp4 60 62 68821.mp4 5 7 92 | 7AsHuXeoSpA.mp4 12 14 62423.mp4 8 10 93 | MaJlWFemO68.mp4 9 11 197428.mp4 2 4 94 | ewGW8hMlxnA.mp4 72 74 366443.mp4 8 10 95 | j5mhELw7XaM.mp4 48 50 59499.mp4 7 9 96 | bb9AIdvKkZU.mp4 21 23 338270.mp4 0 2 97 | P3_YQbHXEIs.mp4 62 64 219869.mp4 5 7 98 | _KOVk8iGbrA.mp4 148 150 318473.mp4 6 8 99 | a74RMGL_c8E.mp4 7 9 325692.mp4 7 9 100 | 6WQSZekz8vQ.mp4 47 49 56989.mp4 3 5 101 | VFqkLp5mzBM.mp4 45 47 275812.mp4 7 9 102 | U6-j4rUn3dk.mp4 148 150 265429.mp4 6 8 103 | 69X7tP6p7E0.mp4 62 64 111815.mp4 0 2 104 | XjV0D7nJx0Q.mp4 14 16 296679.mp4 6 8 105 | YTuQrhSKkNE.mp4 74 76 302883.mp4 0 2 106 | EHianByJXXM.mp4 8 10 123523.mp4 8 10 107 | MVxXCu4zxSM.mp4 75 77 196773.mp4 4 6 108 | B5Ea3Bs8hC4.mp4 14 16 96269.mp4 1 3 109 | JSqJmZPqDy8.mp4 6 8 169302.mp4 4 6 110 | c1tbdVxIhH4.mp4 29 31 342009.mp4 3 5 111 | 9JrRZ9i1sXo.mp4 14 16 80952.mp4 2 4 112 | aBdrTqSnWbw.mp4 14 16 21022.mp4 4 6 113 | U1nvAxorOPQ.mp4 80 82 264745.mp4 8 10 114 | 7QxUtHqQdbY.mp4 10 12 64564.mp4 4 6 115 | WRc1Jv1j3nk.mp4 23 25 251593.mp4 5 7 116 | 5Wp2dxIAocI.mp4 136 138 49129.mp4 8 10 117 | 1fbU_MkV7NE.mp4 76 78 19977.mp4 2 4 118 | 39dTxOhrW68.mp4 26 28 31261.mp4 0 2 119 | EQajiMQAW74.mp4 36 38 124759.mp4 6 8 120 | PLnfT1PoVHw.mp4 87 89 222936.mp4 0 2 121 | fKDl_CnA8nY.mp4 5 7 137092.mp4 1 3 122 | 6HmKyms-U2s.mp4 52 54 55127.mp4 3 5 123 | eVTMUEYhwDE.mp4 6 8 362863.mp4 3 5 124 | cEVHZc_uT7c.mp4 106 108 343998.mp4 7 9 125 | 6Y8wppTQFPo.mp4 66 68 57208.mp4 3 5 126 | F3FjEM9ls0o.mp4 5 7 129992.mp4 5 7 127 | O62LVI0XNHo.mp4 18 20 211168.mp4 3 5 128 | eU27exUJZSM.mp4 4 6 362711.mp4 4 6 129 | K5v9-h2S5pw.mp4 128 130 174810.mp4 5 7 130 | 9RAW6QibWRs.mp4 14 16 81928.mp4 6 8 131 | GG_Bi89pNlg.mp4 6 8 140862.mp4 1 3 132 | aPEqCGdCsp0.mp4 206 208 328049.mp4 4 6 133 | LZC9MLWo9bE.mp4 61 63 188044.mp4 5 7 134 | OsrRpGbIpKA.mp4 78 80 218222.mp4 3 5 135 | 4R37E4Kevs4.mp4 16 18 40876.mp4 3 5 136 | PUWg7fXnCf0.mp4 9 11 224030.mp4 2 4 137 | AUPs7Ukfc1I.mp4 12 14 91137.mp4 1 3 138 | K0MzjnMzbj4.mp4 6 8 370746.mp4 4 6 139 | 7LimgSQsHm0.mp4 71 73 63846.mp4 5 7 140 | 5QS_VBDwKzw.mp4 27 29 48406.mp4 5 7 141 | D_y9uXMbImA.mp4 27 29 117180.mp4 8 10 142 | 7FPvAakfM9Y.mp4 40 42 63012.mp4 7 9 143 | vJiOYQE9tts.mp4 88 90 321088.mp4 3 5 144 | 21biKVGaY1Y.mp4 20 22 22613.mp4 2 4 145 | fPtKNj6jCPU.mp4 43 45 371015.mp4 3 5 146 | BLamvR0GIE8.mp4 7 9 98640.mp4 3 5 147 | PKYg6_rs3LQ.mp4 16 18 222730.mp4 1 3 148 | K_IqYFJKIgk.mp4 44 46 178997.mp4 1 3 149 | DTWZhe352y8.mp4 112 114 116264.mp4 5 7 150 | -E2dqOULQgY.mp4 65 67 1819.mp4 5 7 151 | Ieb7EkMxpJk.mp4 17 19 162058.mp4 1 3 152 | dRqbDamDLT0.mp4 176 178 353931.mp4 0 2 153 | Upd7zpT6tuc.mp4 151 153 271871.mp4 8 10 154 | ByF8Pg3xXNA.mp4 2 4 103619.mp4 2 4 155 | 5ssP_EapV9Q.mp4 99 101 51944.mp4 3 5 156 | 6LWkrN1qz8E.mp4 129 131 55630.mp4 8 10 157 | ZefWc2tgltY.mp4 68 70 266879.mp4 0 2 158 | ivkF2jbavhc.mp4 41 43 183674.mp4 1 3 159 | rFTVKkMqpIQ.mp4 40 42 34077.mp4 1 3 160 | ND9mMyNjm5M.mp4 29 31 203195.mp4 4 6 161 | 5BbHu0WQZqw.mp4 26 28 46550.mp4 0 2 162 | 7s7YqryNMAE.mp4 27 29 68143.mp4 3 5 163 | B1DNoole3Wo.mp4 29 31 95655.mp4 1 3 164 | LnMvFpR0xCY.mp4 133 135 190230.mp4 4 6 165 | xFIfGrhYpAg.mp4 19 21 131693.mp4 7 9 166 | CfDdbeAk8LE.mp4 8 10 109550.mp4 2 4 167 | Ld2a5ogu9k8.mp4 29 31 188734.mp4 5 7 168 | 2XOTxAZZhsQ.mp4 40 42 26437.mp4 8 10 169 | 12v5k4Z8lAE.mp4 59 61 15330.mp4 3 5 170 | 4bUxtqX_oxM.mp4 5 7 42126.mp4 5 7 171 | dP2DgvNt12Y.mp4 26 28 353607.mp4 6 8 172 | RaQE93FNLQI.mp4 45 47 242962.mp4 0 2 173 | aVH9QsSATKM.mp4 129 131 328826.mp4 1 3 174 | WQmJrfjOF7o.mp4 57 59 73088.mp4 7 9 175 | FExyWFc1nU0.mp4 26 28 132014.mp4 2 4 176 | HQP20PGfwYM.mp4 138 140 151096.mp4 1 3 177 | JE50XTpCN78.mp4 149 151 167322.mp4 7 9 178 | 6skP3w9WDIM.mp4 84 86 59929.mp4 7 9 179 | 1DmdX5QwqFI.mp4 75 77 16674.mp4 2 4 180 | Zw4illqWzFI.mp4 11 13 314814.mp4 6 8 181 | ArzhjEk4j_Y.mp4 11 13 94372.mp4 8 10 182 | 3MS3CAyl_YA.mp4 43 45 32754.mp4 2 4 183 | 1rf7t4sYtIA.mp4 12 14 21417.mp4 1 3 184 | 1qKXZ9fThTg.mp4 96 98 21258.mp4 3 5 185 | WCCkmuFrSQ0.mp4 11 13 283749.mp4 1 3 186 | aGlfi9PqRdY.mp4 31 33 327060.mp4 5 7 187 | 7B1FZR0IA6M.mp4 29 31 62441.mp4 0 2 188 | H0l29-F7Edg.mp4 9 11 147147.mp4 8 10 189 | 1VBg21aaiKM.mp4 5 7 342487.mp4 0 2 190 | rDT4ngAfeHs.mp4 10 12 165042.mp4 7 9 191 | 685wnEW1Uq4.mp4 4 6 53900.mp4 3 5 192 | UXi0Cy16-0Y.mp4 12 14 269331.mp4 0 2 193 | O-YKLVm0ciI.mp4 91 93 210020.mp4 0 2 194 | PsddM2OmOGo.mp4 65 67 117623.mp4 8 10 195 | 0fsMeZoZzJI.mp4 52 54 12512.mp4 3 5 196 | 2sbF8W0_bbg.mp4 8 10 29018.mp4 5 7 197 | cY3QbnSeu9k.mp4 101 103 126693.mp4 5 7 198 | 5koLOwu786I.mp4 49 51 50983.mp4 2 4 199 | 5g7bqiT7Y3c.mp4 0 2 50412.mp4 0 2 200 | zLZTqSaGxJo.mp4 75 77 55062.mp4 0 2 201 | Fyi7pbkKk7w.mp4 90 92 137837.mp4 1 3 202 | T_5ANYuDWOA.mp4 27 29 260650.mp4 7 9 203 | Q78FBGHniCc.mp4 45 47 229704.mp4 1 3 204 | 57buK1yvKPk.mp4 72 74 46091.mp4 5 7 205 | f7ndXtwTep0.mp4 50 52 368323.mp4 2 4 206 | X0UmqVLOAK0.mp4 3 5 290341.mp4 0 2 207 | vlqrUu4gi0Q.mp4 45 47 143110.mp4 8 10 208 | VcQHv5PHb-M.mp4 85 87 278774.mp4 4 6 209 | Rn5qprCWXFg.mp4 76 78 244899.mp4 8 10 210 | 91XkPU8A5hs.mp4 19 21 119923.mp4 5 7 211 | Lr5GuPjfU7Q.mp4 42 44 190703.mp4 2 4 212 | BSlVLi81VGM.mp4 43 45 99521.mp4 5 7 213 | od1jHUzgrAU.mp4 91 93 319899.mp4 0 2 214 | FNAt8Pew0HA.mp4 11 13 133112.mp4 4 6 215 | Kyo1nkGKRqw.mp4 55 57 182462.mp4 2 4 216 | SaG9e90z1j8.mp4 86 88 252045.mp4 0 2 217 | dSF2i1OQtMc.mp4 92 94 353972.mp4 5 7 218 | 1scjpxusQx0.mp4 151 153 21519.mp4 6 8 219 | 8ma-p7ap2MQ.mp4 89 91 76027.mp4 6 8 220 | WQmJrfjOF7o.mp4 128 130 285700.mp4 5 7 221 | W8ayZca_fAY.mp4 61 63 342081.mp4 0 2 222 | -lEsnrNNZFU.mp4 7 9 5736.mp4 7 9 223 | Fky1ioAUt38.mp4 0 2 136276.mp4 0 2 224 | 6g80a1NnftU.mp4 66 68 58290.mp4 3 5 225 | T69Cadlc62E.mp4 58 60 256629.mp4 6 8 226 | 9hE6VRD3qXQ.mp4 40 42 84240.mp4 8 10 227 | CRH5U5XKb2Q.mp4 202 204 345915.mp4 1 3 228 | Q-fUXywUo7o.mp4 116 118 228510.mp4 8 10 229 | -l16smV_uYg.mp4 124 126 144997.mp4 1 3 230 | 8nQGd6hiduA.mp4 83 85 198758.mp4 3 5 231 | EInkc1uEX3c.mp4 148 150 123705.mp4 8 10 232 | RLMvrl_vaqc.mp4 12 14 241088.mp4 1 3 233 | t1urvYx1X_w.mp4 16 18 134516.mp4 5 7 234 | JZz2O0y0ufY.mp4 6 8 36796.mp4 2 4 235 | Qu3_80O0j5w.mp4 67 69 236886.mp4 6 8 236 | -------------------------------------------------------------------------------- /duplicate_lists/lists/ActivityNet_LSMDC.lst: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/papermsucode/mdmmt/1741ce301037d4ddfa9836854cdca1fade364d1b/duplicate_lists/lists/ActivityNet_LSMDC.lst -------------------------------------------------------------------------------- /duplicate_lists/lists/ActivityNet_MSRVTT.lst: -------------------------------------------------------------------------------- 1 | vopKTwCiHrA.mp4 116 118 video3475.mp4 4 6 2 | vopKTwCiHrA.mp4 83 85 video3296.mp4 16 18 3 | B-6kP8M_GmM.mp4 51 53 video3219.mp4 0 2 4 | 3X6eP273RoI.mp4 3 5 video4946.mp4 0 2 5 | vvHrSeomFtg.mp4 3 5 video4946.mp4 0 2 6 | xaCOYdzox0g.mp4 3 5 video4946.mp4 0 2 7 | vopKTwCiHrA.mp4 55 57 video5091.mp4 0 2 8 | cZZM3bgmXE4.mp4 217 219 video3796.mp4 11 13 9 | -------------------------------------------------------------------------------- /duplicate_lists/lists/ActivityNet_MSVD.lst: -------------------------------------------------------------------------------- 1 | MdOAr_4FJvc.mp4 13 15 MdOAr_4FJvc_5_15.avi 7 9 2 | -------------------------------------------------------------------------------- /duplicate_lists/lists/ActivityNet_TGIF.lst: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/papermsucode/mdmmt/1741ce301037d4ddfa9836854cdca1fade364d1b/duplicate_lists/lists/ActivityNet_TGIF.lst -------------------------------------------------------------------------------- /duplicate_lists/lists/ActivityNet_TwitterVines.lst: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/papermsucode/mdmmt/1741ce301037d4ddfa9836854cdca1fade364d1b/duplicate_lists/lists/ActivityNet_TwitterVines.lst -------------------------------------------------------------------------------- /duplicate_lists/lists/ActivityNet_YouCook2.lst: -------------------------------------------------------------------------------- 1 | dn1qrAHh7k0.mp4 84 86 dn1qrAHh7k0.mp4 84 86 2 | 7hfaWQgcDyo.mp4 41 43 7hfaWQgcDyo.mp4 41 43 3 | WFbUBMgOMn8.mp4 6 8 SuK9T9KOBSs.mp4 6 8 4 | AMMECm7Huhk.mp4 125 127 5yJz2Sc7T5k.mp4 194 196 5 | AMMECm7Huhk.mp4 147 149 OSabGgdaQeM.mp4 219 221 6 | 3j2d27w3x5Q.mp4 19 21 0B-59Ok_r1Y.mp4 13 15 7 | DjT4-5H3xDQ.mp4 90 92 djKnQP_LvSk.mp4 149 151 8 | DjT4-5H3xDQ.mp4 97 99 AGq4lnC_WVo.mp4 385 387 9 | AMMECm7Huhk.mp4 3 5 uJuGp3BUD6o.mp4 7 9 10 | GQdkuWJGYFg.mp4 2 4 mKIvvx1SwmQ.mp4 7 9 11 | -------------------------------------------------------------------------------- /duplicate_lists/lists/LSMDC_ActivityNet.lst: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/papermsucode/mdmmt/1741ce301037d4ddfa9836854cdca1fade364d1b/duplicate_lists/lists/LSMDC_ActivityNet.lst -------------------------------------------------------------------------------- /duplicate_lists/lists/LSMDC_Kinetics700.lst: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/papermsucode/mdmmt/1741ce301037d4ddfa9836854cdca1fade364d1b/duplicate_lists/lists/LSMDC_Kinetics700.lst -------------------------------------------------------------------------------- /duplicate_lists/lists/LSMDC_MSRVTT.lst: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/papermsucode/mdmmt/1741ce301037d4ddfa9836854cdca1fade364d1b/duplicate_lists/lists/LSMDC_MSRVTT.lst -------------------------------------------------------------------------------- /duplicate_lists/lists/LSMDC_MSVD.lst: -------------------------------------------------------------------------------- 1 | 3056_PUBLIC_ENEMIES_02.01.34.458-02.01.36.289.avi 0 2 swJ0zhVJ8DU_15_21.avi 2 4 2 | -------------------------------------------------------------------------------- /duplicate_lists/lists/LSMDC_TGIF.lst: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/papermsucode/mdmmt/1741ce301037d4ddfa9836854cdca1fade364d1b/duplicate_lists/lists/LSMDC_TGIF.lst -------------------------------------------------------------------------------- /duplicate_lists/lists/LSMDC_TwitterVines.lst: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/papermsucode/mdmmt/1741ce301037d4ddfa9836854cdca1fade364d1b/duplicate_lists/lists/LSMDC_TwitterVines.lst -------------------------------------------------------------------------------- /duplicate_lists/lists/LSMDC_YouCook2.lst: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/papermsucode/mdmmt/1741ce301037d4ddfa9836854cdca1fade364d1b/duplicate_lists/lists/LSMDC_YouCook2.lst -------------------------------------------------------------------------------- /duplicate_lists/lists/MSRVTT_ActivityNet.lst: -------------------------------------------------------------------------------- 1 | video7241.mp4 15 19 ypf6WHYpeRU.mp4 148 152 2 | video9804.mp4 6 10 ypf6WHYpeRU.mp4 133 137 3 | video9671.mp4 1 5 8Qg395HjqFg.mp4 9 13 4 | video8475.mp4 7 11 ypf6WHYpeRU.mp4 133 137 5 | video8813.mp4 0 4 0jvbBtMIA8k.mp4 5 9 6 | video9615.mp4 4 8 86sxvTk3YEY.mp4 35 39 7 | video8813.mp4 0 4 86sxvTk3YEY.mp4 5 9 8 | video9615.mp4 5 9 0jvbBtMIA8k.mp4 26 30 9 | video9082.mp4 12 16 enESbo2pA9U.mp4 120 124 10 | video7282.mp4 5 9 8Qg395HjqFg.mp4 162 166 11 | video9879.mp4 3 7 yTJCrP0HqEE.mp4 41 45 12 | video9282.mp4 3 7 yTJCrP0HqEE.mp4 42 46 13 | -------------------------------------------------------------------------------- /duplicate_lists/lists/MSRVTT_HowTo100M.lst: -------------------------------------------------------------------------------- 1 | video7850.mp4 12 16 -QsjoCXiA_A.mp4 398 402 2 | video9638.mp4 0 4 TqfMHH67KJA.mp4 1811 1815 3 | video7241.mp4 15 19 uOmtVFQ3WF8.mp4 240 244 4 | video7241.mp4 15 19 cmYsRcLMvO8.mp4 201 205 5 | video9401.mp4 3 7 -QsjoCXiA_A.mp4 276 280 6 | video9952.mp4 1 5 -QsjoCXiA_A.mp4 276 280 7 | video7930.mp4 10 14 y5KPZp2t52U.mp4 213 217 8 | video8690.mp4 2 6 igXvifC7Gd0.mp4 171 175 9 | video8444.mp4 8 12 vQJ5ejIqUQI.mp4 120 124 10 | video8444.mp4 7 11 5mXLUDF7lnQ.mp4 101 105 11 | video8444.mp4 8 12 FjLrVethvZY.mp4 293 297 12 | video8747.mp4 4 8 XyBzmblzxVU.mp4 486 490 13 | video8444.mp4 8 12 diXKW_pLpQA.mp4 234 238 14 | video7546.mp4 13 17 GRDRUoO0g0U.mp4 105 109 15 | video9611.mp4 12 16 lR3Ae6IAOiM.mp4 252 256 16 | video8475.mp4 7 11 cmYsRcLMvO8.mp4 191 195 17 | video7607.mp4 2 6 bf7BXwVeyWw.mp4 6 10 18 | video7366.mp4 0 4 f5NUO2OEz7k.mp4 1160 1164 19 | video7607.mp4 2 6 H0_yKBitO8M.mp4 6 10 20 | video9671.mp4 1 5 uwVtPY1UO9I.mp4 170 174 21 | video8512.mp4 10 14 I_O-80EtAgI.mp4 23 27 22 | -------------------------------------------------------------------------------- /duplicate_lists/lists/MSRVTT_Kinetics700.lst: -------------------------------------------------------------------------------- 1 | video9402.mp4 0 2 341305.mp4 6 8 2 | -------------------------------------------------------------------------------- /duplicate_lists/lists/MSRVTT_LSMDC.lst: -------------------------------------------------------------------------------- 1 | video7671.mp4 2 4 1045_An_education_00.49.08.763-00.49.12.792.avi 2 4 2 | video8174.mp4 8 10 0001_American_Beauty_00.52.37.472-00.52.39.324.avi 0 2 3 | video8653.mp4 7 9 1045_An_education_00.49.55.627-00.50.17.697.avi 3 5 4 | video8174.mp4 7 9 0001_American_Beauty_00.52.34.536-00.52.36.574.avi 0 2 5 | video8174.mp4 7 9 0001_American_Beauty_00.52.46.937-00.52.54.414.avi 0 2 6 | video8090.mp4 18 20 3014_CAPTAIN_AMERICA_00.37.11.975-00.37.15.565.avi 1 3 7 | video7671.mp4 9 11 1045_An_education_00.49.55.627-00.50.17.697.avi 3 5 8 | video8090.mp4 4 6 3014_CAPTAIN_AMERICA_00.36.58.713-00.37.00.221.avi 0 2 9 | video8090.mp4 14 16 3014_CAPTAIN_AMERICA_00.37.01.308-00.37.10.708.avi 7 9 10 | video8653.mp4 0 2 1045_An_education_00.49.50.568-00.49.55.627.avi 0 2 11 | video7671.mp4 9 11 1045_An_education_00.49.16.965-00.49.21.121.avi 1 3 12 | video8653.mp4 6 8 1045_An_education_00.49.16.965-00.49.21.121.avi 1 3 13 | video7671.mp4 3 5 1045_An_education_00.49.50.568-00.49.55.627.avi 0 2 14 | video8653.mp4 0 2 1045_An_education_00.49.08.763-00.49.12.792.avi 2 4 15 | video9435.mp4 6 8 3014_CAPTAIN_AMERICA_00.36.46.282-00.36.50.008.avi 0 2 16 | video7636.mp4 0 2 3014_CAPTAIN_AMERICA_01.53.21.954-01.53.36.744.avi 8 10 17 | video7636.mp4 1 3 3037_IRON_MAN2_01.54.39.101-01.54.41.748.avi 1 3 18 | -------------------------------------------------------------------------------- /duplicate_lists/lists/MSRVTT_MSRVTT.lst: -------------------------------------------------------------------------------- 1 | video8832.mp4 10 14 video1607.mp4 11 15 2 | video7884.mp4 8 12 video4776.mp4 8 12 3 | video8832.mp4 11 15 video2679.mp4 10 14 4 | video9054.mp4 7 11 video4749.mp4 7 11 5 | video8832.mp4 12 16 video425.mp4 11 15 6 | video7558.mp4 9 13 video6663.mp4 1 5 7 | video8731.mp4 6 10 video3089.mp4 0 4 8 | video9054.mp4 0 4 video4680.mp4 4 8 9 | video7118.mp4 8 12 video4919.mp4 9 13 10 | video7129.mp4 5 9 video4919.mp4 9 13 11 | video7118.mp4 7 11 video583.mp4 7 11 12 | video7129.mp4 4 8 video583.mp4 7 11 13 | video7118.mp4 8 12 video4356.mp4 9 13 14 | video7129.mp4 5 9 video4356.mp4 9 13 15 | video7500.mp4 8 12 video2586.mp4 8 12 16 | video9417.mp4 2 6 video5985.mp4 3 7 17 | video8832.mp4 3 7 video5143.mp4 2 6 18 | video9012.mp4 7 11 video4356.mp4 2 6 19 | video9191.mp4 4 8 video5375.mp4 5 9 20 | video9012.mp4 4 8 video425.mp4 0 4 21 | video8752.mp4 6 10 video637.mp4 3 7 22 | video9012.mp4 9 13 video583.mp4 3 7 23 | video9014.mp4 2 6 video2007.mp4 5 9 24 | video8832.mp4 3 7 video583.mp4 0 4 25 | video7241.mp4 8 12 video821.mp4 3 7 26 | video9804.mp4 6 10 video5607.mp4 6 10 27 | video8832.mp4 8 12 video4356.mp4 7 11 28 | video8850.mp4 4 8 video6483.mp4 1 5 29 | video8832.mp4 9 13 video4919.mp4 7 11 30 | video9804.mp4 6 10 video4773.mp4 0 4 31 | video9804.mp4 7 11 video5739.mp4 7 11 32 | video8394.mp4 5 9 video5570.mp4 0 4 33 | video7129.mp4 7 11 video1607.mp4 12 16 34 | video9012.mp4 4 8 video1607.mp4 2 6 35 | video7241.mp4 6 10 video4773.mp4 1 5 36 | video7241.mp4 0 4 video5607.mp4 6 10 37 | video9012.mp4 4 8 video2679.mp4 0 4 38 | video9012.mp4 7 11 video5143.mp4 2 6 39 | video7118.mp4 6 10 video1607.mp4 9 13 40 | video7241.mp4 1 5 video5739.mp4 7 11 41 | video7011.mp4 9 13 video4312.mp4 4 8 42 | video9012.mp4 7 11 video4919.mp4 0 4 43 | video9089.mp4 1 5 video409.mp4 1 5 44 | video9804.mp4 6 10 video821.mp4 5 9 45 | video7118.mp4 1 5 video2679.mp4 2 6 46 | video7612.mp4 1 5 video915.mp4 15 19 47 | video9012.mp4 7 11 video5100.mp4 5 9 48 | video7118.mp4 1 5 video5100.mp4 5 9 49 | video7118.mp4 6 10 video425.mp4 7 11 50 | video7118.mp4 1 5 video5143.mp4 2 6 51 | video7883.mp4 8 12 video4466.mp4 24 28 52 | video7129.mp4 4 8 video425.mp4 8 12 53 | video8539.mp4 1 5 video1078.mp4 0 4 54 | video8832.mp4 3 7 video5100.mp4 5 9 55 | video7129.mp4 3 7 video2679.mp4 7 11 56 | video8144.mp4 7 11 video5749.mp4 4 8 57 | video7118.mp4 9 13 video3672.mp4 1 5 58 | video7129.mp4 6 10 video3672.mp4 1 5 59 | video7241.mp4 5 9 video4536.mp4 7 11 60 | video9804.mp4 6 10 video4536.mp4 7 11 61 | video9623.mp4 1 5 video337.mp4 0 4 62 | video8144.mp4 7 11 video1936.mp4 7 11 63 | video8475.mp4 7 11 video5607.mp4 6 10 64 | video8017.mp4 19 23 video5203.mp4 7 11 65 | video7922.mp4 1 5 video165.mp4 5 9 66 | video7118.mp4 9 13 video4218.mp4 1 5 67 | video7129.mp4 6 10 video4218.mp4 1 5 68 | video8475.mp4 7 11 video821.mp4 5 9 69 | video9012.mp4 1 5 video4238.mp4 4 8 70 | video7366.mp4 0 4 video2607.mp4 17 21 71 | video8582.mp4 3 7 video5884.mp4 3 7 72 | video8993.mp4 6 10 video2355.mp4 8 12 73 | video7975.mp4 4 8 video6625.mp4 22 26 74 | video8907.mp4 8 12 video5625.mp4 2 6 75 | video7413.mp4 4 8 video3246.mp4 6 10 76 | video8358.mp4 25 29 video5760.mp4 2 6 77 | video8832.mp4 12 16 video4218.mp4 1 5 78 | video7129.mp4 0 4 video5100.mp4 7 11 79 | video8475.mp4 7 11 video4536.mp4 7 11 80 | video7748.mp4 4 8 video6625.mp4 17 21 81 | video9308.mp4 5 9 video3851.mp4 9 13 82 | video7129.mp4 0 4 video5143.mp4 4 8 83 | video7444.mp4 8 12 video6639.mp4 6 10 84 | video8628.mp4 3 7 video2607.mp4 17 21 85 | video9071.mp4 13 17 video126.mp4 6 10 86 | video7612.mp4 22 26 video5099.mp4 4 8 87 | video7686.mp4 13 17 video6918.mp4 5 9 88 | video7636.mp4 0 4 video5625.mp4 2 6 89 | video7607.mp4 6 10 video2355.mp4 8 12 90 | video7883.mp4 5 9 video1104.mp4 18 22 91 | video7449.mp4 2 6 video1078.mp4 3 7 92 | video8908.mp4 10 14 video5375.mp4 2 6 93 | video8539.mp4 4 8 video6813.mp4 2 6 94 | video7862.mp4 0 4 video3865.mp4 6 10 95 | video7308.mp4 5 9 video2607.mp4 11 15 96 | video9674.mp4 2 6 video2501.mp4 10 14 97 | video9674.mp4 0 4 video2802.mp4 0 4 98 | video8075.mp4 6 10 video4680.mp4 3 7 99 | video8832.mp4 1 5 video4238.mp4 8 12 100 | video8832.mp4 10 14 video3672.mp4 1 5 101 | video9071.mp4 14 18 video3851.mp4 9 13 102 | video7449.mp4 8 12 video4070.mp4 2 6 103 | video8002.mp4 4 8 video5225.mp4 2 6 104 | video7867.mp4 4 8 video5393.mp4 6 10 105 | video9991.mp4 6 10 video5412.mp4 7 11 106 | video7960.mp4 8 12 video5412.mp4 5 9 107 | video9870.mp4 16 20 video5.mp4 16 20 108 | video7366.mp4 0 4 video6500.mp4 6 10 109 | video7883.mp4 6 10 video4324.mp4 12 16 110 | video7449.mp4 9 13 video4324.mp4 4 8 111 | video7449.mp4 9 13 video2647.mp4 2 6 112 | video8779.mp4 0 4 video1418.mp4 1 5 113 | video7308.mp4 19 23 video6500.mp4 6 10 114 | video9084.mp4 2 6 video5771.mp4 8 12 115 | video7156.mp4 0 4 video5570.mp4 7 11 116 | video8757.mp4 7 11 video5793.mp4 2 6 117 | video8757.mp4 7 11 video6208.mp4 3 7 118 | video8537.mp4 18 22 video4559.mp4 10 14 119 | video7159.mp4 1 5 video518.mp4 3 7 120 | video8823.mp4 0 4 video6118.mp4 1 5 121 | video7748.mp4 3 7 video6636.mp4 4 8 122 | video7449.mp4 8 12 video1104.mp4 3 7 123 | video8628.mp4 3 7 video6500.mp4 6 10 124 | video9308.mp4 5 9 video126.mp4 6 10 125 | video8443.mp4 8 12 video2505.mp4 9 13 126 | video8539.mp4 22 26 video6496.mp4 16 20 127 | video7159.mp4 1 5 video3814.mp4 0 4 128 | video7067.mp4 3 7 video4155.mp4 8 12 129 | video7882.mp4 9 13 video1458.mp4 2 6 130 | video7975.mp4 5 9 video6636.mp4 4 8 131 | video8539.mp4 22 26 video4070.mp4 2 6 132 | video9375.mp4 5 9 video3633.mp4 16 20 133 | video9064.mp4 5 9 video6603.mp4 11 15 134 | video7782.mp4 7 11 video3315.mp4 4 8 135 | video9791.mp4 9 13 video3376.mp4 8 12 136 | video8371.mp4 3 7 video3159.mp4 4 8 137 | video7117.mp4 4 8 video6332.mp4 3 7 138 | video7883.mp4 8 12 video2647.mp4 21 25 139 | video9632.mp4 6 10 video1527.mp4 5 9 140 | video8823.mp4 0 4 video5760.mp4 1 5 141 | video8556.mp4 5 9 video2692.mp4 6 10 142 | video9674.mp4 1 5 video6786.mp4 6 10 143 | video9212.mp4 7 11 video1311.mp4 5 9 144 | video9375.mp4 4 8 video3212.mp4 7 11 145 | video9012.mp4 0 4 video2100.mp4 7 11 146 | video7019.mp4 7 11 video5188.mp4 6 10 147 | video7908.mp4 7 11 video6438.mp4 6 10 148 | video7449.mp4 9 13 video6496.mp4 1 5 149 | video9375.mp4 8 12 video2295.mp4 12 16 150 | video7941.mp4 1 5 video6208.mp4 2 6 151 | video8539.mp4 22 26 video1104.mp4 3 7 152 | video7014.mp4 5 9 video3424.mp4 2 6 153 | video8823.mp4 0 4 video1985.mp4 14 18 154 | video8823.mp4 0 4 video1985.mp4 14 18 155 | video8586.mp4 0 4 video4070.mp4 2 6 156 | video9632.mp4 6 10 video5771.mp4 10 14 157 | video7941.mp4 1 5 video5793.mp4 1 5 158 | video8586.mp4 0 4 video1104.mp4 18 22 159 | video7941.mp4 2 6 video357.mp4 7 11 160 | video9012.mp4 1 5 video5665.mp4 5 9 161 | video8399.mp4 0 4 video5594.mp4 7 11 162 | video7946.mp4 9 13 video5188.mp4 6 10 163 | video8575.mp4 1 5 video3376.mp4 1 5 164 | video9879.mp4 4 8 video4515.mp4 0 4 165 | video8443.mp4 2 6 video3669.mp4 6 10 166 | video8105.mp4 0 4 video4945.mp4 2 6 167 | video8105.mp4 11 15 video6594.mp4 3 7 168 | video8105.mp4 11 15 video6594.mp4 3 7 169 | video8105.mp4 13 17 video347.mp4 0 4 170 | video9084.mp4 2 6 video5594.mp4 7 11 171 | video7014.mp4 1 5 video2428.mp4 5 9 172 | video7883.mp4 14 18 video3441.mp4 9 13 173 | video7883.mp4 6 10 video6255.mp4 21 25 174 | video8975.mp4 1 5 video1877.mp4 6 10 175 | video8399.mp4 0 4 video5771.mp4 10 14 176 | video7862.mp4 0 4 video3424.mp4 7 11 177 | video8224.mp4 6 10 video6343.mp4 6 10 178 | video9825.mp4 10 14 video5188.mp4 7 11 179 | video8537.mp4 22 26 video5361.mp4 3 7 180 | video8537.mp4 17 21 video3758.mp4 2 6 181 | video8539.mp4 15 19 video4466.mp4 21 25 182 | video8537.mp4 17 21 video3633.mp4 13 17 183 | video9298.mp4 0 4 video3865.mp4 6 10 184 | video9298.mp4 0 4 video3865.mp4 6 10 185 | video7449.mp4 9 13 video4466.mp4 24 28 186 | video8537.mp4 21 25 video2360.mp4 0 4 187 | video8537.mp4 21 25 video665.mp4 9 13 188 | video7883.mp4 8 12 video4070.mp4 2 6 189 | video9641.mp4 4 8 video5555.mp4 0 4 190 | video8257.mp4 5 9 video5188.mp4 7 11 191 | video7730.mp4 5 9 video3851.mp4 10 14 192 | video7946.mp4 4 8 video2430.mp4 6 10 193 | video8443.mp4 8 12 video4543.mp4 14 18 194 | video8586.mp4 0 4 video4466.mp4 22 26 195 | video8586.mp4 0 4 video4324.mp4 6 10 196 | video9881.mp4 7 11 video6347.mp4 15 19 197 | video9193.mp4 9 13 video1159.mp4 9 13 198 | video9375.mp4 7 11 video3556.mp4 9 13 199 | video9375.mp4 8 12 video5123.mp4 8 12 200 | video8443.mp4 8 12 video2360.mp4 7 11 201 | video8539.mp4 9 13 video4324.mp4 12 16 202 | video9791.mp4 8 12 video1159.mp4 9 13 203 | video8470.mp4 1 5 video3031.mp4 12 16 204 | video8539.mp4 22 26 video2647.mp4 1 5 205 | video9375.mp4 17 21 video5361.mp4 4 8 206 | video9768.mp4 0 4 video6548.mp4 0 4 207 | video8009.mp4 1 5 video2095.mp4 7 11 208 | video8586.mp4 0 4 video2647.mp4 2 6 209 | video9375.mp4 22 26 video2505.mp4 9 13 210 | video9868.mp4 6 10 video5290.mp4 2 6 211 | video8009.mp4 2 6 video2429.mp4 7 11 212 | video9375.mp4 22 26 video2360.mp4 5 9 213 | video8586.mp4 0 4 video6496.mp4 19 23 214 | video9632.mp4 6 10 video5594.mp4 7 11 215 | video9580.mp4 9 13 video838.mp4 11 15 216 | video8394.mp4 0 4 video1677.mp4 8 12 217 | video8275.mp4 9 13 video6101.mp4 10 14 218 | video8792.mp4 0 4 video5793.mp4 0 4 219 | video9710.mp4 5 9 video2429.mp4 7 11 220 | video9710.mp4 4 8 video2095.mp4 7 11 221 | video8586.mp4 0 4 video6255.mp4 22 26 222 | video7975.mp4 7 11 video1624.mp4 0 4 223 | video8537.mp4 17 21 video3556.mp4 9 13 224 | video7883.mp4 7 11 video6039.mp4 0 4 225 | video8539.mp4 19 23 video6255.mp4 13 17 226 | video7791.mp4 7 11 video5847.mp4 9 13 227 | video7159.mp4 6 10 video3895.mp4 1 5 228 | video7086.mp4 6 10 video2425.mp4 7 11 229 | video8443.mp4 2 6 video665.mp4 1 5 230 | video9375.mp4 24 28 video665.mp4 12 16 231 | video8009.mp4 3 7 video65.mp4 1 5 232 | video9710.mp4 6 10 video65.mp4 1 5 233 | video8757.mp4 3 7 video357.mp4 7 11 234 | video8575.mp4 4 8 video1159.mp4 9 13 235 | video7539.mp4 7 11 video110.mp4 0 4 236 | video7941.mp4 2 6 video2115.mp4 3 7 237 | video8537.mp4 17 21 video2213.mp4 0 4 238 | video7883.mp4 14 18 video6496.mp4 14 18 239 | video9710.mp4 5 9 video5290.mp4 3 7 240 | video9710.mp4 1 5 video1133.mp4 1 5 241 | video9064.mp4 0 4 video6740.mp4 6 10 242 | video9632.mp4 6 10 video2754.mp4 0 4 243 | video8443.mp4 2 6 video5361.mp4 5 9 244 | video7159.mp4 3 7 video3247.mp4 11 15 245 | video7625.mp4 3 7 video6332.mp4 0 4 246 | video9825.mp4 1 5 video6552.mp4 20 24 247 | video9710.mp4 0 4 video2515.mp4 3 7 248 | video8551.mp4 5 9 video2567.mp4 5 9 249 | video9778.mp4 1 5 video963.mp4 3 7 250 | video7118.mp4 4 8 video4238.mp4 7 11 251 | video9298.mp4 0 4 video3424.mp4 6 10 252 | video7014.mp4 6 10 video4060.mp4 5 9 253 | video7449.mp4 9 13 video6039.mp4 0 4 254 | video9825.mp4 9 13 video1830.mp4 5 9 255 | video9294.mp4 2 6 video6484.mp4 0 4 256 | video9623.mp4 1 5 video637.mp4 3 7 257 | video9064.mp4 5 9 video6521.mp4 0 4 258 | video7946.mp4 9 13 video1830.mp4 5 9 259 | video9084.mp4 2 6 video6032.mp4 1 5 260 | video8265.mp4 3 7 video6444.mp4 6 10 261 | video8557.mp4 0 4 video2428.mp4 2 6 262 | video9241.mp4 6 10 video50.mp4 0 4 263 | video7908.mp4 7 11 video6548.mp4 2 6 264 | video7667.mp4 7 11 video1877.mp4 8 12 265 | video9129.mp4 5 9 video6548.mp4 3 7 266 | video7472.mp4 6 10 video4515.mp4 2 6 267 | video9282.mp4 10 14 video2095.mp4 7 11 268 | video8009.mp4 3 7 video3698.mp4 1 5 269 | video7129.mp4 1 5 video4238.mp4 7 11 270 | video9710.mp4 6 10 video3698.mp4 1 5 271 | video8352.mp4 5 9 video3337.mp4 2 6 272 | video9632.mp4 6 10 video2425.mp4 7 11 273 | video8009.mp4 4 8 video3258.mp4 4 8 274 | video9868.mp4 6 10 video2246.mp4 6 10 275 | video7014.mp4 6 10 video65.mp4 5 9 276 | video7449.mp4 9 13 video6255.mp4 21 25 277 | video8394.mp4 0 4 video6150.mp4 6 10 278 | video8586.mp4 0 4 video6039.mp4 5 9 279 | video7014.mp4 2 6 video6355.mp4 7 11 280 | video9632.mp4 5 9 video6387.mp4 8 12 281 | video7524.mp4 6 10 video65.mp4 9 13 282 | -------------------------------------------------------------------------------- /duplicate_lists/lists/MSRVTT_MSVD.lst: -------------------------------------------------------------------------------- 1 | video9717.mp4 12 16 5HAf_INrFy0_3_25.avi 11 15 2 | -------------------------------------------------------------------------------- /duplicate_lists/lists/MSRVTT_TGIF.lst: -------------------------------------------------------------------------------- 1 | video9717.mp4 18 20 tumblr_nqd7kzqRFw1tyncywo1_400.gif 1 3 2 | video9460.mp4 2 4 tumblr_nrh8549DaU1ub1e03o1_500.gif 0 2 3 | video7802.mp4 8 10 tumblr_naz9dc592k1tdjuqvo1_400.gif 0 2 4 | video8478.mp4 9 11 tumblr_npa978lYjX1s5e5bko1_400.gif 0 2 5 | video8478.mp4 9 11 tumblr_nqpt0sYWFM1tv1bhvo1_400.gif 1 3 6 | video9672.mp4 7 9 tumblr_n8tlnsO2TR1sn75h6o1_400.gif 7 9 7 | video9672.mp4 7 9 tumblr_nqlh59763t1u4hkfto1_400.gif 7 9 8 | video9071.mp4 8 10 tumblr_nj5w9fjf7N1s10sito1_400.gif 1 3 9 | -------------------------------------------------------------------------------- /duplicate_lists/lists/MSRVTT_TwitterVines.lst: -------------------------------------------------------------------------------- 1 | video9717.mp4 18 20 C3D68AAECA1020864995245912064_1703ad5247c.4.4.1931727424554029248_E6XeAKOBPVHpWFqGvfSWAFD_kJ_9mRPAGir4AfUkiT_F1bB2bWCjZ3bOfyHe5gXU.mp4 1 3 2 | video8856.mp4 2 4 3FCAB23FA71160339750566445056_3a604fd3f0f.1.4.608534666586883998.mp4 3 5 3 | video8017.mp4 7 11 EED5F483271153395653666635776_3b8d5d82e61.1.1.16470876978662837027.mp4 0 4 4 | -------------------------------------------------------------------------------- /duplicate_lists/lists/MSRVTT_YouCook2.lst: -------------------------------------------------------------------------------- 1 | video8659.mp4 13 17 SuKgZbVHL2o.mp4 24 28 2 | video7968.mp4 9 13 X1mE2IWeamI.mp4 93 97 3 | video9705.mp4 0 4 SuKgZbVHL2o.mp4 89 93 4 | video8444.mp4 3 7 A68bBM_5wUY.mp4 342 346 5 | video8444.mp4 8 12 wKHC2gbRdA0.mp4 150 154 6 | video8834.mp4 6 10 AWVaYpPFJqk.mp4 385 389 7 | video9881.mp4 7 11 4B6j3gYkvr4.mp4 158 162 8 | video8643.mp4 5 9 SuKgZbVHL2o.mp4 60 64 9 | video9881.mp4 12 16 nqyO0ovASOg.mp4 188 192 10 | video7591.mp4 5 9 nQLUK4aKsg0.mp4 113 117 11 | video7406.mp4 1 5 nQLUK4aKsg0.mp4 112 116 12 | video8511.mp4 4 8 nqyO0ovASOg.mp4 146 150 13 | video7360.mp4 1 5 c87PnAWDbOA.mp4 23 27 14 | video9881.mp4 7 11 LRjJqoeprqg.mp4 356 360 15 | video9938.mp4 0 4 ZLA9W7R4a_c.mp4 118 122 16 | video9881.mp4 7 11 IvDEV7eROm4.mp4 123 127 17 | video9881.mp4 7 11 0xYOUNfzIn8.mp4 11 15 18 | video9881.mp4 7 11 ucky1nWb7LY.mp4 237 241 19 | video9881.mp4 7 11 RUnYJCdTLiY.mp4 95 99 20 | video8511.mp4 6 10 U5Eyu9IyG-I.mp4 118 122 21 | video8511.mp4 6 10 K16Rr-pPKKI.mp4 141 145 22 | video9881.mp4 7 11 PKcwRi9jh0E.mp4 72 76 23 | video8511.mp4 6 10 Ghefa-Q18Tg.mp4 598 602 24 | video7360.mp4 1 5 2Rn2tM9Rgg8.mp4 522 526 25 | video8511.mp4 6 10 f-h7OM5HM0Q.mp4 358 362 26 | video9881.mp4 6 10 W882NYaaiEs.mp4 380 384 27 | video8511.mp4 6 10 W882NYaaiEs.mp4 319 323 28 | video8511.mp4 6 10 p8ZGmL-8w6E.mp4 108 112 29 | video9881.mp4 7 11 fq37BTAjPHk.mp4 193 197 30 | video8511.mp4 6 10 sLFCqYYhrZM.mp4 275 279 31 | video8511.mp4 6 10 PKcwRi9jh0E.mp4 72 76 32 | video8511.mp4 6 10 LRjJqoeprqg.mp4 83 87 33 | video8511.mp4 5 9 mixdagZ-fwI.mp4 211 215 34 | video8596.mp4 5 9 ZvIXsbEUCa0.mp4 335 339 35 | -------------------------------------------------------------------------------- /duplicate_lists/pseudo_dup1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/papermsucode/mdmmt/1741ce301037d4ddfa9836854cdca1fade364d1b/duplicate_lists/pseudo_dup1.jpg -------------------------------------------------------------------------------- /duplicate_lists/pseudo_dup2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/papermsucode/mdmmt/1741ce301037d4ddfa9836854cdca1fade364d1b/duplicate_lists/pseudo_dup2.jpg -------------------------------------------------------------------------------- /lists/msrvtt/test_list_full.txt: -------------------------------------------------------------------------------- 1 | video7010 2 | video7011 3 | video7012 4 | video7013 5 | video7014 6 | video7015 7 | video7016 8 | video7017 9 | video7018 10 | video7019 11 | video7020 12 | video7021 13 | video7022 14 | video7023 15 | video7024 16 | video7025 17 | video7026 18 | video7027 19 | video7028 20 | video7029 21 | video7030 22 | video7031 23 | video7032 24 | video7033 25 | video7034 26 | video7035 27 | video7036 28 | video7037 29 | video7038 30 | video7039 31 | video7040 32 | video7041 33 | video7042 34 | video7043 35 | video7044 36 | video7045 37 | video7046 38 | video7047 39 | video7048 40 | video7049 41 | video7050 42 | video7051 43 | video7052 44 | video7053 45 | video7054 46 | video7055 47 | video7056 48 | video7057 49 | video7058 50 | video7059 51 | video7060 52 | video7061 53 | video7062 54 | video7063 55 | video7064 56 | video7065 57 | video7066 58 | video7067 59 | video7068 60 | video7069 61 | video7070 62 | video7071 63 | video7072 64 | video7073 65 | video7074 66 | video7075 67 | video7076 68 | video7077 69 | video7078 70 | video7079 71 | video7080 72 | video7081 73 | video7082 74 | video7083 75 | video7084 76 | video7085 77 | video7086 78 | video7087 79 | video7088 80 | video7089 81 | video7090 82 | video7091 83 | video7092 84 | video7093 85 | video7094 86 | video7095 87 | video7096 88 | video7097 89 | video7098 90 | video7099 91 | video7100 92 | video7101 93 | video7102 94 | video7103 95 | video7104 96 | video7105 97 | video7106 98 | video7107 99 | video7108 100 | video7109 101 | video7110 102 | video7111 103 | video7112 104 | video7113 105 | video7114 106 | video7115 107 | video7116 108 | video7117 109 | video7118 110 | video7119 111 | video7120 112 | video7121 113 | video7122 114 | video7123 115 | video7124 116 | video7125 117 | video7126 118 | video7127 119 | video7128 120 | video7129 121 | video7130 122 | video7131 123 | video7132 124 | video7133 125 | video7134 126 | video7135 127 | video7136 128 | video7137 129 | video7138 130 | video7139 131 | video7140 132 | video7141 133 | video7142 134 | video7143 135 | video7144 136 | video7145 137 | video7146 138 | video7147 139 | video7148 140 | video7149 141 | video7150 142 | video7151 143 | video7152 144 | video7153 145 | video7154 146 | video7155 147 | video7156 148 | video7157 149 | video7158 150 | video7159 151 | video7160 152 | video7161 153 | video7162 154 | video7163 155 | video7164 156 | video7165 157 | video7166 158 | video7167 159 | video7168 160 | video7169 161 | video7170 162 | video7171 163 | video7172 164 | video7173 165 | video7174 166 | video7175 167 | video7176 168 | video7177 169 | video7178 170 | video7179 171 | video7180 172 | video7181 173 | video7182 174 | video7183 175 | video7184 176 | video7185 177 | video7186 178 | video7187 179 | video7188 180 | video7189 181 | video7190 182 | video7191 183 | video7192 184 | video7193 185 | video7194 186 | video7195 187 | video7196 188 | video7197 189 | video7198 190 | video7199 191 | video7200 192 | video7201 193 | video7202 194 | video7203 195 | video7204 196 | video7205 197 | video7206 198 | video7207 199 | video7208 200 | video7209 201 | video7210 202 | video7211 203 | video7212 204 | video7213 205 | video7214 206 | video7215 207 | video7216 208 | video7217 209 | video7218 210 | video7219 211 | video7220 212 | video7221 213 | video7222 214 | video7223 215 | video7224 216 | video7225 217 | video7226 218 | video7227 219 | video7228 220 | video7229 221 | video7230 222 | video7231 223 | video7232 224 | video7233 225 | video7234 226 | video7235 227 | video7236 228 | video7237 229 | video7238 230 | video7239 231 | video7240 232 | video7241 233 | video7242 234 | video7243 235 | video7244 236 | video7245 237 | video7246 238 | video7247 239 | video7248 240 | video7249 241 | video7250 242 | video7251 243 | video7252 244 | video7253 245 | video7254 246 | video7255 247 | video7256 248 | video7257 249 | video7258 250 | video7259 251 | video7260 252 | video7261 253 | video7262 254 | video7263 255 | video7264 256 | video7265 257 | video7266 258 | video7267 259 | video7268 260 | video7269 261 | video7270 262 | video7271 263 | video7272 264 | video7273 265 | video7274 266 | video7275 267 | video7276 268 | video7277 269 | video7278 270 | video7279 271 | video7280 272 | video7281 273 | video7282 274 | video7283 275 | video7284 276 | video7285 277 | video7286 278 | video7287 279 | video7288 280 | video7289 281 | video7290 282 | video7291 283 | video7292 284 | video7293 285 | video7294 286 | video7295 287 | video7296 288 | video7297 289 | video7298 290 | video7299 291 | video7300 292 | video7301 293 | video7302 294 | video7303 295 | video7304 296 | video7305 297 | video7306 298 | video7307 299 | video7308 300 | video7309 301 | video7310 302 | video7311 303 | video7312 304 | video7313 305 | video7314 306 | video7315 307 | video7316 308 | video7317 309 | video7318 310 | video7319 311 | video7320 312 | video7321 313 | video7322 314 | video7323 315 | video7324 316 | video7325 317 | video7326 318 | video7327 319 | video7328 320 | video7329 321 | video7330 322 | video7331 323 | video7332 324 | video7333 325 | video7334 326 | video7335 327 | video7336 328 | video7337 329 | video7338 330 | video7339 331 | video7340 332 | video7341 333 | video7342 334 | video7343 335 | video7344 336 | video7345 337 | video7346 338 | video7347 339 | video7348 340 | video7349 341 | video7350 342 | video7351 343 | video7352 344 | video7353 345 | video7354 346 | video7355 347 | video7356 348 | video7357 349 | video7358 350 | video7359 351 | video7360 352 | video7361 353 | video7362 354 | video7363 355 | video7364 356 | video7365 357 | video7366 358 | video7367 359 | video7368 360 | video7369 361 | video7370 362 | video7371 363 | video7372 364 | video7373 365 | video7374 366 | video7375 367 | video7376 368 | video7377 369 | video7378 370 | video7379 371 | video7380 372 | video7381 373 | video7382 374 | video7383 375 | video7384 376 | video7385 377 | video7386 378 | video7387 379 | video7388 380 | video7389 381 | video7390 382 | video7391 383 | video7392 384 | video7393 385 | video7394 386 | video7395 387 | video7396 388 | video7397 389 | video7398 390 | video7399 391 | video7400 392 | video7401 393 | video7402 394 | video7403 395 | video7404 396 | video7405 397 | video7406 398 | video7407 399 | video7408 400 | video7409 401 | video7410 402 | video7411 403 | video7412 404 | video7413 405 | video7414 406 | video7415 407 | video7416 408 | video7417 409 | video7418 410 | video7419 411 | video7420 412 | video7421 413 | video7422 414 | video7423 415 | video7424 416 | video7425 417 | video7426 418 | video7427 419 | video7428 420 | video7429 421 | video7430 422 | video7431 423 | video7432 424 | video7433 425 | video7434 426 | video7435 427 | video7436 428 | video7437 429 | video7438 430 | video7439 431 | video7440 432 | video7441 433 | video7442 434 | video7443 435 | video7444 436 | video7445 437 | video7446 438 | video7447 439 | video7448 440 | video7449 441 | video7450 442 | video7451 443 | video7452 444 | video7453 445 | video7454 446 | video7455 447 | video7456 448 | video7457 449 | video7458 450 | video7459 451 | video7460 452 | video7461 453 | video7462 454 | video7463 455 | video7464 456 | video7465 457 | video7466 458 | video7467 459 | video7468 460 | video7469 461 | video7470 462 | video7471 463 | video7472 464 | video7473 465 | video7474 466 | video7475 467 | video7476 468 | video7477 469 | video7478 470 | video7479 471 | video7480 472 | video7481 473 | video7482 474 | video7483 475 | video7484 476 | video7485 477 | video7486 478 | video7487 479 | video7488 480 | video7489 481 | video7490 482 | video7491 483 | video7492 484 | video7493 485 | video7494 486 | video7495 487 | video7496 488 | video7497 489 | video7498 490 | video7499 491 | video7500 492 | video7501 493 | video7502 494 | video7503 495 | video7504 496 | video7505 497 | video7506 498 | video7507 499 | video7508 500 | video7509 501 | video7510 502 | video7511 503 | video7512 504 | video7513 505 | video7514 506 | video7515 507 | video7516 508 | video7517 509 | video7518 510 | video7519 511 | video7520 512 | video7521 513 | video7522 514 | video7523 515 | video7524 516 | video7525 517 | video7526 518 | video7527 519 | video7528 520 | video7529 521 | video7530 522 | video7531 523 | video7532 524 | video7533 525 | video7534 526 | video7535 527 | video7536 528 | video7537 529 | video7538 530 | video7539 531 | video7540 532 | video7541 533 | video7542 534 | video7543 535 | video7544 536 | video7545 537 | video7546 538 | video7547 539 | video7548 540 | video7549 541 | video7550 542 | video7551 543 | video7552 544 | video7553 545 | video7554 546 | video7555 547 | video7556 548 | video7557 549 | video7558 550 | video7559 551 | video7560 552 | video7561 553 | video7562 554 | video7563 555 | video7564 556 | video7565 557 | video7566 558 | video7567 559 | video7568 560 | video7569 561 | video7570 562 | video7571 563 | video7572 564 | video7573 565 | video7574 566 | video7575 567 | video7576 568 | video7577 569 | video7578 570 | video7579 571 | video7580 572 | video7581 573 | video7582 574 | video7583 575 | video7584 576 | video7585 577 | video7586 578 | video7587 579 | video7588 580 | video7589 581 | video7590 582 | video7591 583 | video7592 584 | video7593 585 | video7594 586 | video7595 587 | video7596 588 | video7597 589 | video7598 590 | video7599 591 | video7600 592 | video7601 593 | video7602 594 | video7603 595 | video7604 596 | video7605 597 | video7606 598 | video7607 599 | video7608 600 | video7609 601 | video7610 602 | video7611 603 | video7612 604 | video7613 605 | video7614 606 | video7615 607 | video7616 608 | video7617 609 | video7618 610 | video7619 611 | video7620 612 | video7621 613 | video7622 614 | video7623 615 | video7624 616 | video7625 617 | video7626 618 | video7627 619 | video7628 620 | video7629 621 | video7630 622 | video7631 623 | video7632 624 | video7633 625 | video7634 626 | video7635 627 | video7636 628 | video7637 629 | video7638 630 | video7639 631 | video7640 632 | video7641 633 | video7642 634 | video7643 635 | video7644 636 | video7645 637 | video7646 638 | video7647 639 | video7648 640 | video7649 641 | video7650 642 | video7651 643 | video7652 644 | video7653 645 | video7654 646 | video7655 647 | video7656 648 | video7657 649 | video7658 650 | video7659 651 | video7660 652 | video7661 653 | video7662 654 | video7663 655 | video7664 656 | video7665 657 | video7666 658 | video7667 659 | video7668 660 | video7669 661 | video7670 662 | video7671 663 | video7672 664 | video7673 665 | video7674 666 | video7675 667 | video7676 668 | video7677 669 | video7678 670 | video7679 671 | video7680 672 | video7681 673 | video7682 674 | video7683 675 | video7684 676 | video7685 677 | video7686 678 | video7687 679 | video7688 680 | video7689 681 | video7690 682 | video7691 683 | video7692 684 | video7693 685 | video7694 686 | video7695 687 | video7696 688 | video7697 689 | video7698 690 | video7699 691 | video7700 692 | video7701 693 | video7702 694 | video7703 695 | video7704 696 | video7705 697 | video7706 698 | video7707 699 | video7708 700 | video7709 701 | video7710 702 | video7711 703 | video7712 704 | video7713 705 | video7714 706 | video7715 707 | video7716 708 | video7717 709 | video7718 710 | video7719 711 | video7720 712 | video7721 713 | video7722 714 | video7723 715 | video7724 716 | video7725 717 | video7726 718 | video7727 719 | video7728 720 | video7729 721 | video7730 722 | video7731 723 | video7732 724 | video7733 725 | video7734 726 | video7735 727 | video7736 728 | video7737 729 | video7738 730 | video7739 731 | video7740 732 | video7741 733 | video7742 734 | video7743 735 | video7744 736 | video7745 737 | video7746 738 | video7747 739 | video7748 740 | video7749 741 | video7750 742 | video7751 743 | video7752 744 | video7753 745 | video7754 746 | video7755 747 | video7756 748 | video7757 749 | video7758 750 | video7759 751 | video7760 752 | video7761 753 | video7762 754 | video7763 755 | video7764 756 | video7765 757 | video7766 758 | video7767 759 | video7768 760 | video7769 761 | video7770 762 | video7771 763 | video7772 764 | video7773 765 | video7774 766 | video7775 767 | video7776 768 | video7777 769 | video7778 770 | video7779 771 | video7780 772 | video7781 773 | video7782 774 | video7783 775 | video7784 776 | video7785 777 | video7786 778 | video7787 779 | video7788 780 | video7789 781 | video7790 782 | video7791 783 | video7792 784 | video7793 785 | video7794 786 | video7795 787 | video7796 788 | video7797 789 | video7798 790 | video7799 791 | video7800 792 | video7801 793 | video7802 794 | video7803 795 | video7804 796 | video7805 797 | video7806 798 | video7807 799 | video7808 800 | video7809 801 | video7810 802 | video7811 803 | video7812 804 | video7813 805 | video7814 806 | video7815 807 | video7816 808 | video7817 809 | video7818 810 | video7819 811 | video7820 812 | video7821 813 | video7822 814 | video7823 815 | video7824 816 | video7825 817 | video7826 818 | video7827 819 | video7828 820 | video7829 821 | video7830 822 | video7831 823 | video7832 824 | video7833 825 | video7834 826 | video7835 827 | video7836 828 | video7837 829 | video7838 830 | video7839 831 | video7840 832 | video7841 833 | video7842 834 | video7843 835 | video7844 836 | video7845 837 | video7846 838 | video7847 839 | video7848 840 | video7849 841 | video7850 842 | video7851 843 | video7852 844 | video7853 845 | video7854 846 | video7855 847 | video7856 848 | video7857 849 | video7858 850 | video7859 851 | video7860 852 | video7861 853 | video7862 854 | video7863 855 | video7864 856 | video7865 857 | video7866 858 | video7867 859 | video7868 860 | video7869 861 | video7870 862 | video7871 863 | video7872 864 | video7873 865 | video7874 866 | video7875 867 | video7876 868 | video7877 869 | video7878 870 | video7879 871 | video7880 872 | video7881 873 | video7882 874 | video7883 875 | video7884 876 | video7885 877 | video7886 878 | video7887 879 | video7888 880 | video7889 881 | video7890 882 | video7891 883 | video7892 884 | video7893 885 | video7894 886 | video7895 887 | video7896 888 | video7897 889 | video7898 890 | video7899 891 | video7900 892 | video7901 893 | video7902 894 | video7903 895 | video7904 896 | video7905 897 | video7906 898 | video7907 899 | video7908 900 | video7909 901 | video7910 902 | video7911 903 | video7912 904 | video7913 905 | video7914 906 | video7915 907 | video7916 908 | video7917 909 | video7918 910 | video7919 911 | video7920 912 | video7921 913 | video7922 914 | video7923 915 | video7924 916 | video7925 917 | video7926 918 | video7927 919 | video7928 920 | video7929 921 | video7930 922 | video7931 923 | video7932 924 | video7933 925 | video7934 926 | video7935 927 | video7936 928 | video7937 929 | video7938 930 | video7939 931 | video7940 932 | video7941 933 | video7942 934 | video7943 935 | video7944 936 | video7945 937 | video7946 938 | video7947 939 | video7948 940 | video7949 941 | video7950 942 | video7951 943 | video7952 944 | video7953 945 | video7954 946 | video7955 947 | video7956 948 | video7957 949 | video7958 950 | video7959 951 | video7960 952 | video7961 953 | video7962 954 | video7963 955 | video7964 956 | video7965 957 | video7966 958 | video7967 959 | video7968 960 | video7969 961 | video7970 962 | video7971 963 | video7972 964 | video7973 965 | video7974 966 | video7975 967 | video7976 968 | video7977 969 | video7978 970 | video7979 971 | video7980 972 | video7981 973 | video7982 974 | video7983 975 | video7984 976 | video7985 977 | video7986 978 | video7987 979 | video7988 980 | video7989 981 | video7990 982 | video7991 983 | video7992 984 | video7993 985 | video7994 986 | video7995 987 | video7996 988 | video7997 989 | video7998 990 | video7999 991 | video8000 992 | video8001 993 | video8002 994 | video8003 995 | video8004 996 | video8005 997 | video8006 998 | video8007 999 | video8008 1000 | video8009 1001 | video8010 1002 | video8011 1003 | video8012 1004 | video8013 1005 | video8014 1006 | video8015 1007 | video8016 1008 | video8017 1009 | video8018 1010 | video8019 1011 | video8020 1012 | video8021 1013 | video8022 1014 | video8023 1015 | video8024 1016 | video8025 1017 | video8026 1018 | video8027 1019 | video8028 1020 | video8029 1021 | video8030 1022 | video8031 1023 | video8032 1024 | video8033 1025 | video8034 1026 | video8035 1027 | video8036 1028 | video8037 1029 | video8038 1030 | video8039 1031 | video8040 1032 | video8041 1033 | video8042 1034 | video8043 1035 | video8044 1036 | video8045 1037 | video8046 1038 | video8047 1039 | video8048 1040 | video8049 1041 | video8050 1042 | video8051 1043 | video8052 1044 | video8053 1045 | video8054 1046 | video8055 1047 | video8056 1048 | video8057 1049 | video8058 1050 | video8059 1051 | video8060 1052 | video8061 1053 | video8062 1054 | video8063 1055 | video8064 1056 | video8065 1057 | video8066 1058 | video8067 1059 | video8068 1060 | video8069 1061 | video8070 1062 | video8071 1063 | video8072 1064 | video8073 1065 | video8074 1066 | video8075 1067 | video8076 1068 | video8077 1069 | video8078 1070 | video8079 1071 | video8080 1072 | video8081 1073 | video8082 1074 | video8083 1075 | video8084 1076 | video8085 1077 | video8086 1078 | video8087 1079 | video8088 1080 | video8089 1081 | video8090 1082 | video8091 1083 | video8092 1084 | video8093 1085 | video8094 1086 | video8095 1087 | video8096 1088 | video8097 1089 | video8098 1090 | video8099 1091 | video8100 1092 | video8101 1093 | video8102 1094 | video8103 1095 | video8104 1096 | video8105 1097 | video8106 1098 | video8107 1099 | video8108 1100 | video8109 1101 | video8110 1102 | video8111 1103 | video8112 1104 | video8113 1105 | video8114 1106 | video8115 1107 | video8116 1108 | video8117 1109 | video8118 1110 | video8119 1111 | video8120 1112 | video8121 1113 | video8122 1114 | video8123 1115 | video8124 1116 | video8125 1117 | video8126 1118 | video8127 1119 | video8128 1120 | video8129 1121 | video8130 1122 | video8131 1123 | video8132 1124 | video8133 1125 | video8134 1126 | video8135 1127 | video8136 1128 | video8137 1129 | video8138 1130 | video8139 1131 | video8140 1132 | video8141 1133 | video8142 1134 | video8143 1135 | video8144 1136 | video8145 1137 | video8146 1138 | video8147 1139 | video8148 1140 | video8149 1141 | video8150 1142 | video8151 1143 | video8152 1144 | video8153 1145 | video8154 1146 | video8155 1147 | video8156 1148 | video8157 1149 | video8158 1150 | video8159 1151 | video8160 1152 | video8161 1153 | video8162 1154 | video8163 1155 | video8164 1156 | video8165 1157 | video8166 1158 | video8167 1159 | video8168 1160 | video8169 1161 | video8170 1162 | video8171 1163 | video8172 1164 | video8173 1165 | video8174 1166 | video8175 1167 | video8176 1168 | video8177 1169 | video8178 1170 | video8179 1171 | video8180 1172 | video8181 1173 | video8182 1174 | video8183 1175 | video8184 1176 | video8185 1177 | video8186 1178 | video8187 1179 | video8188 1180 | video8189 1181 | video8190 1182 | video8191 1183 | video8192 1184 | video8193 1185 | video8194 1186 | video8195 1187 | video8196 1188 | video8197 1189 | video8198 1190 | video8199 1191 | video8200 1192 | video8201 1193 | video8202 1194 | video8203 1195 | video8204 1196 | video8205 1197 | video8206 1198 | video8207 1199 | video8208 1200 | video8209 1201 | video8210 1202 | video8211 1203 | video8212 1204 | video8213 1205 | video8214 1206 | video8215 1207 | video8216 1208 | video8217 1209 | video8218 1210 | video8219 1211 | video8220 1212 | video8221 1213 | video8222 1214 | video8223 1215 | video8224 1216 | video8225 1217 | video8226 1218 | video8227 1219 | video8228 1220 | video8229 1221 | video8230 1222 | video8231 1223 | video8232 1224 | video8233 1225 | video8234 1226 | video8235 1227 | video8236 1228 | video8237 1229 | video8238 1230 | video8239 1231 | video8240 1232 | video8241 1233 | video8242 1234 | video8243 1235 | video8244 1236 | video8245 1237 | video8246 1238 | video8247 1239 | video8248 1240 | video8249 1241 | video8250 1242 | video8251 1243 | video8252 1244 | video8253 1245 | video8254 1246 | video8255 1247 | video8256 1248 | video8257 1249 | video8258 1250 | video8259 1251 | video8260 1252 | video8261 1253 | video8262 1254 | video8263 1255 | video8264 1256 | video8265 1257 | video8266 1258 | video8267 1259 | video8268 1260 | video8269 1261 | video8270 1262 | video8271 1263 | video8272 1264 | video8273 1265 | video8274 1266 | video8275 1267 | video8276 1268 | video8277 1269 | video8278 1270 | video8279 1271 | video8280 1272 | video8281 1273 | video8282 1274 | video8283 1275 | video8284 1276 | video8285 1277 | video8286 1278 | video8287 1279 | video8288 1280 | video8289 1281 | video8290 1282 | video8291 1283 | video8292 1284 | video8293 1285 | video8294 1286 | video8295 1287 | video8296 1288 | video8297 1289 | video8298 1290 | video8299 1291 | video8300 1292 | video8301 1293 | video8302 1294 | video8303 1295 | video8304 1296 | video8305 1297 | video8306 1298 | video8307 1299 | video8308 1300 | video8309 1301 | video8310 1302 | video8311 1303 | video8312 1304 | video8313 1305 | video8314 1306 | video8315 1307 | video8316 1308 | video8317 1309 | video8318 1310 | video8319 1311 | video8320 1312 | video8321 1313 | video8322 1314 | video8323 1315 | video8324 1316 | video8325 1317 | video8326 1318 | video8327 1319 | video8328 1320 | video8329 1321 | video8330 1322 | video8331 1323 | video8332 1324 | video8333 1325 | video8334 1326 | video8335 1327 | video8336 1328 | video8337 1329 | video8338 1330 | video8339 1331 | video8340 1332 | video8341 1333 | video8342 1334 | video8343 1335 | video8344 1336 | video8345 1337 | video8346 1338 | video8347 1339 | video8348 1340 | video8349 1341 | video8350 1342 | video8351 1343 | video8352 1344 | video8353 1345 | video8354 1346 | video8355 1347 | video8356 1348 | video8357 1349 | video8358 1350 | video8359 1351 | video8360 1352 | video8361 1353 | video8362 1354 | video8363 1355 | video8364 1356 | video8365 1357 | video8366 1358 | video8367 1359 | video8368 1360 | video8369 1361 | video8370 1362 | video8371 1363 | video8372 1364 | video8373 1365 | video8374 1366 | video8375 1367 | video8376 1368 | video8377 1369 | video8378 1370 | video8379 1371 | video8380 1372 | video8381 1373 | video8382 1374 | video8383 1375 | video8384 1376 | video8385 1377 | video8386 1378 | video8387 1379 | video8388 1380 | video8389 1381 | video8390 1382 | video8391 1383 | video8392 1384 | video8393 1385 | video8394 1386 | video8395 1387 | video8396 1388 | video8397 1389 | video8398 1390 | video8399 1391 | video8400 1392 | video8401 1393 | video8402 1394 | video8403 1395 | video8404 1396 | video8405 1397 | video8406 1398 | video8407 1399 | video8408 1400 | video8409 1401 | video8410 1402 | video8411 1403 | video8412 1404 | video8413 1405 | video8414 1406 | video8415 1407 | video8416 1408 | video8417 1409 | video8418 1410 | video8419 1411 | video8420 1412 | video8421 1413 | video8422 1414 | video8423 1415 | video8424 1416 | video8425 1417 | video8426 1418 | video8427 1419 | video8428 1420 | video8429 1421 | video8430 1422 | video8431 1423 | video8432 1424 | video8433 1425 | video8434 1426 | video8435 1427 | video8436 1428 | video8437 1429 | video8438 1430 | video8439 1431 | video8440 1432 | video8441 1433 | video8442 1434 | video8443 1435 | video8444 1436 | video8445 1437 | video8446 1438 | video8447 1439 | video8448 1440 | video8449 1441 | video8450 1442 | video8451 1443 | video8452 1444 | video8453 1445 | video8454 1446 | video8455 1447 | video8456 1448 | video8457 1449 | video8458 1450 | video8459 1451 | video8460 1452 | video8461 1453 | video8462 1454 | video8463 1455 | video8464 1456 | video8465 1457 | video8466 1458 | video8467 1459 | video8468 1460 | video8469 1461 | video8470 1462 | video8471 1463 | video8472 1464 | video8473 1465 | video8474 1466 | video8475 1467 | video8476 1468 | video8477 1469 | video8478 1470 | video8479 1471 | video8480 1472 | video8481 1473 | video8482 1474 | video8483 1475 | video8484 1476 | video8485 1477 | video8486 1478 | video8487 1479 | video8488 1480 | video8489 1481 | video8490 1482 | video8491 1483 | video8492 1484 | video8493 1485 | video8494 1486 | video8495 1487 | video8496 1488 | video8497 1489 | video8498 1490 | video8499 1491 | video8500 1492 | video8501 1493 | video8502 1494 | video8503 1495 | video8504 1496 | video8505 1497 | video8506 1498 | video8507 1499 | video8508 1500 | video8509 1501 | video8510 1502 | video8511 1503 | video8512 1504 | video8513 1505 | video8514 1506 | video8515 1507 | video8516 1508 | video8517 1509 | video8518 1510 | video8519 1511 | video8520 1512 | video8521 1513 | video8522 1514 | video8523 1515 | video8524 1516 | video8525 1517 | video8526 1518 | video8527 1519 | video8528 1520 | video8529 1521 | video8530 1522 | video8531 1523 | video8532 1524 | video8533 1525 | video8534 1526 | video8535 1527 | video8536 1528 | video8537 1529 | video8538 1530 | video8539 1531 | video8540 1532 | video8541 1533 | video8542 1534 | video8543 1535 | video8544 1536 | video8545 1537 | video8546 1538 | video8547 1539 | video8548 1540 | video8549 1541 | video8550 1542 | video8551 1543 | video8552 1544 | video8553 1545 | video8554 1546 | video8555 1547 | video8556 1548 | video8557 1549 | video8558 1550 | video8559 1551 | video8560 1552 | video8561 1553 | video8562 1554 | video8563 1555 | video8564 1556 | video8565 1557 | video8566 1558 | video8567 1559 | video8568 1560 | video8569 1561 | video8570 1562 | video8571 1563 | video8572 1564 | video8573 1565 | video8574 1566 | video8575 1567 | video8576 1568 | video8577 1569 | video8578 1570 | video8579 1571 | video8580 1572 | video8581 1573 | video8582 1574 | video8583 1575 | video8584 1576 | video8585 1577 | video8586 1578 | video8587 1579 | video8588 1580 | video8589 1581 | video8590 1582 | video8591 1583 | video8592 1584 | video8593 1585 | video8594 1586 | video8595 1587 | video8596 1588 | video8597 1589 | video8598 1590 | video8599 1591 | video8600 1592 | video8601 1593 | video8602 1594 | video8603 1595 | video8604 1596 | video8605 1597 | video8606 1598 | video8607 1599 | video8608 1600 | video8609 1601 | video8610 1602 | video8611 1603 | video8612 1604 | video8613 1605 | video8614 1606 | video8615 1607 | video8616 1608 | video8617 1609 | video8618 1610 | video8619 1611 | video8620 1612 | video8621 1613 | video8622 1614 | video8623 1615 | video8624 1616 | video8625 1617 | video8626 1618 | video8627 1619 | video8628 1620 | video8629 1621 | video8630 1622 | video8631 1623 | video8632 1624 | video8633 1625 | video8634 1626 | video8635 1627 | video8636 1628 | video8637 1629 | video8638 1630 | video8639 1631 | video8640 1632 | video8641 1633 | video8642 1634 | video8643 1635 | video8644 1636 | video8645 1637 | video8646 1638 | video8647 1639 | video8648 1640 | video8649 1641 | video8650 1642 | video8651 1643 | video8652 1644 | video8653 1645 | video8654 1646 | video8655 1647 | video8656 1648 | video8657 1649 | video8658 1650 | video8659 1651 | video8660 1652 | video8661 1653 | video8662 1654 | video8663 1655 | video8664 1656 | video8665 1657 | video8666 1658 | video8667 1659 | video8668 1660 | video8669 1661 | video8670 1662 | video8671 1663 | video8672 1664 | video8673 1665 | video8674 1666 | video8675 1667 | video8676 1668 | video8677 1669 | video8678 1670 | video8679 1671 | video8680 1672 | video8681 1673 | video8682 1674 | video8683 1675 | video8684 1676 | video8685 1677 | video8686 1678 | video8687 1679 | video8688 1680 | video8689 1681 | video8690 1682 | video8691 1683 | video8692 1684 | video8693 1685 | video8694 1686 | video8695 1687 | video8696 1688 | video8697 1689 | video8698 1690 | video8699 1691 | video8700 1692 | video8701 1693 | video8702 1694 | video8703 1695 | video8704 1696 | video8705 1697 | video8706 1698 | video8707 1699 | video8708 1700 | video8709 1701 | video8710 1702 | video8711 1703 | video8712 1704 | video8713 1705 | video8714 1706 | video8715 1707 | video8716 1708 | video8717 1709 | video8718 1710 | video8719 1711 | video8720 1712 | video8721 1713 | video8722 1714 | video8723 1715 | video8724 1716 | video8725 1717 | video8726 1718 | video8727 1719 | video8728 1720 | video8729 1721 | video8730 1722 | video8731 1723 | video8732 1724 | video8733 1725 | video8734 1726 | video8735 1727 | video8736 1728 | video8737 1729 | video8738 1730 | video8739 1731 | video8740 1732 | video8741 1733 | video8742 1734 | video8743 1735 | video8744 1736 | video8745 1737 | video8746 1738 | video8747 1739 | video8748 1740 | video8749 1741 | video8750 1742 | video8751 1743 | video8752 1744 | video8753 1745 | video8754 1746 | video8755 1747 | video8756 1748 | video8757 1749 | video8758 1750 | video8759 1751 | video8760 1752 | video8761 1753 | video8762 1754 | video8763 1755 | video8764 1756 | video8765 1757 | video8766 1758 | video8767 1759 | video8768 1760 | video8769 1761 | video8770 1762 | video8771 1763 | video8772 1764 | video8773 1765 | video8774 1766 | video8775 1767 | video8776 1768 | video8777 1769 | video8778 1770 | video8779 1771 | video8780 1772 | video8781 1773 | video8782 1774 | video8783 1775 | video8784 1776 | video8785 1777 | video8786 1778 | video8787 1779 | video8788 1780 | video8789 1781 | video8790 1782 | video8791 1783 | video8792 1784 | video8793 1785 | video8794 1786 | video8795 1787 | video8796 1788 | video8797 1789 | video8798 1790 | video8799 1791 | video8800 1792 | video8801 1793 | video8802 1794 | video8803 1795 | video8804 1796 | video8805 1797 | video8806 1798 | video8807 1799 | video8808 1800 | video8809 1801 | video8810 1802 | video8811 1803 | video8812 1804 | video8813 1805 | video8814 1806 | video8815 1807 | video8816 1808 | video8817 1809 | video8818 1810 | video8819 1811 | video8820 1812 | video8821 1813 | video8822 1814 | video8823 1815 | video8824 1816 | video8825 1817 | video8826 1818 | video8827 1819 | video8828 1820 | video8829 1821 | video8830 1822 | video8831 1823 | video8832 1824 | video8833 1825 | video8834 1826 | video8835 1827 | video8836 1828 | video8837 1829 | video8838 1830 | video8839 1831 | video8840 1832 | video8841 1833 | video8842 1834 | video8843 1835 | video8844 1836 | video8845 1837 | video8846 1838 | video8847 1839 | video8848 1840 | video8849 1841 | video8850 1842 | video8851 1843 | video8852 1844 | video8853 1845 | video8854 1846 | video8855 1847 | video8856 1848 | video8857 1849 | video8858 1850 | video8859 1851 | video8860 1852 | video8861 1853 | video8862 1854 | video8863 1855 | video8864 1856 | video8865 1857 | video8866 1858 | video8867 1859 | video8868 1860 | video8869 1861 | video8870 1862 | video8871 1863 | video8872 1864 | video8873 1865 | video8874 1866 | video8875 1867 | video8876 1868 | video8877 1869 | video8878 1870 | video8879 1871 | video8880 1872 | video8881 1873 | video8882 1874 | video8883 1875 | video8884 1876 | video8885 1877 | video8886 1878 | video8887 1879 | video8888 1880 | video8889 1881 | video8890 1882 | video8891 1883 | video8892 1884 | video8893 1885 | video8894 1886 | video8895 1887 | video8896 1888 | video8897 1889 | video8898 1890 | video8899 1891 | video8900 1892 | video8901 1893 | video8902 1894 | video8903 1895 | video8904 1896 | video8905 1897 | video8906 1898 | video8907 1899 | video8908 1900 | video8909 1901 | video8910 1902 | video8911 1903 | video8912 1904 | video8913 1905 | video8914 1906 | video8915 1907 | video8916 1908 | video8917 1909 | video8918 1910 | video8919 1911 | video8920 1912 | video8921 1913 | video8922 1914 | video8923 1915 | video8924 1916 | video8925 1917 | video8926 1918 | video8927 1919 | video8928 1920 | video8929 1921 | video8930 1922 | video8931 1923 | video8932 1924 | video8933 1925 | video8934 1926 | video8935 1927 | video8936 1928 | video8937 1929 | video8938 1930 | video8939 1931 | video8940 1932 | video8941 1933 | video8942 1934 | video8943 1935 | video8944 1936 | video8945 1937 | video8946 1938 | video8947 1939 | video8948 1940 | video8949 1941 | video8950 1942 | video8951 1943 | video8952 1944 | video8953 1945 | video8954 1946 | video8955 1947 | video8956 1948 | video8957 1949 | video8958 1950 | video8959 1951 | video8960 1952 | video8961 1953 | video8962 1954 | video8963 1955 | video8964 1956 | video8965 1957 | video8966 1958 | video8967 1959 | video8968 1960 | video8969 1961 | video8970 1962 | video8971 1963 | video8972 1964 | video8973 1965 | video8974 1966 | video8975 1967 | video8976 1968 | video8977 1969 | video8978 1970 | video8979 1971 | video8980 1972 | video8981 1973 | video8982 1974 | video8983 1975 | video8984 1976 | video8985 1977 | video8986 1978 | video8987 1979 | video8988 1980 | video8989 1981 | video8990 1982 | video8991 1983 | video8992 1984 | video8993 1985 | video8994 1986 | video8995 1987 | video8996 1988 | video8997 1989 | video8998 1990 | video8999 1991 | video9000 1992 | video9001 1993 | video9002 1994 | video9003 1995 | video9004 1996 | video9005 1997 | video9006 1998 | video9007 1999 | video9008 2000 | video9009 2001 | video9010 2002 | video9011 2003 | video9012 2004 | video9013 2005 | video9014 2006 | video9015 2007 | video9016 2008 | video9017 2009 | video9018 2010 | video9019 2011 | video9020 2012 | video9021 2013 | video9022 2014 | video9023 2015 | video9024 2016 | video9025 2017 | video9026 2018 | video9027 2019 | video9028 2020 | video9029 2021 | video9030 2022 | video9031 2023 | video9032 2024 | video9033 2025 | video9034 2026 | video9035 2027 | video9036 2028 | video9037 2029 | video9038 2030 | video9039 2031 | video9040 2032 | video9041 2033 | video9042 2034 | video9043 2035 | video9044 2036 | video9045 2037 | video9046 2038 | video9047 2039 | video9048 2040 | video9049 2041 | video9050 2042 | video9051 2043 | video9052 2044 | video9053 2045 | video9054 2046 | video9055 2047 | video9056 2048 | video9057 2049 | video9058 2050 | video9059 2051 | video9060 2052 | video9061 2053 | video9062 2054 | video9063 2055 | video9064 2056 | video9065 2057 | video9066 2058 | video9067 2059 | video9068 2060 | video9069 2061 | video9070 2062 | video9071 2063 | video9072 2064 | video9073 2065 | video9074 2066 | video9075 2067 | video9076 2068 | video9077 2069 | video9078 2070 | video9079 2071 | video9080 2072 | video9081 2073 | video9082 2074 | video9083 2075 | video9084 2076 | video9085 2077 | video9086 2078 | video9087 2079 | video9088 2080 | video9089 2081 | video9090 2082 | video9091 2083 | video9092 2084 | video9093 2085 | video9094 2086 | video9095 2087 | video9096 2088 | video9097 2089 | video9098 2090 | video9099 2091 | video9100 2092 | video9101 2093 | video9102 2094 | video9103 2095 | video9104 2096 | video9105 2097 | video9106 2098 | video9107 2099 | video9108 2100 | video9109 2101 | video9110 2102 | video9111 2103 | video9112 2104 | video9113 2105 | video9114 2106 | video9115 2107 | video9116 2108 | video9117 2109 | video9118 2110 | video9119 2111 | video9120 2112 | video9121 2113 | video9122 2114 | video9123 2115 | video9124 2116 | video9125 2117 | video9126 2118 | video9127 2119 | video9128 2120 | video9129 2121 | video9130 2122 | video9131 2123 | video9132 2124 | video9133 2125 | video9134 2126 | video9135 2127 | video9136 2128 | video9137 2129 | video9138 2130 | video9139 2131 | video9140 2132 | video9141 2133 | video9142 2134 | video9143 2135 | video9144 2136 | video9145 2137 | video9146 2138 | video9147 2139 | video9148 2140 | video9149 2141 | video9150 2142 | video9151 2143 | video9152 2144 | video9153 2145 | video9154 2146 | video9155 2147 | video9156 2148 | video9157 2149 | video9158 2150 | video9159 2151 | video9160 2152 | video9161 2153 | video9162 2154 | video9163 2155 | video9164 2156 | video9165 2157 | video9166 2158 | video9167 2159 | video9168 2160 | video9169 2161 | video9170 2162 | video9171 2163 | video9172 2164 | video9173 2165 | video9174 2166 | video9175 2167 | video9176 2168 | video9177 2169 | video9178 2170 | video9179 2171 | video9180 2172 | video9181 2173 | video9182 2174 | video9183 2175 | video9184 2176 | video9185 2177 | video9186 2178 | video9187 2179 | video9188 2180 | video9189 2181 | video9190 2182 | video9191 2183 | video9192 2184 | video9193 2185 | video9194 2186 | video9195 2187 | video9196 2188 | video9197 2189 | video9198 2190 | video9199 2191 | video9200 2192 | video9201 2193 | video9202 2194 | video9203 2195 | video9204 2196 | video9205 2197 | video9206 2198 | video9207 2199 | video9208 2200 | video9209 2201 | video9210 2202 | video9211 2203 | video9212 2204 | video9213 2205 | video9214 2206 | video9215 2207 | video9216 2208 | video9217 2209 | video9218 2210 | video9219 2211 | video9220 2212 | video9221 2213 | video9222 2214 | video9223 2215 | video9224 2216 | video9225 2217 | video9226 2218 | video9227 2219 | video9228 2220 | video9229 2221 | video9230 2222 | video9231 2223 | video9232 2224 | video9233 2225 | video9234 2226 | video9235 2227 | video9236 2228 | video9237 2229 | video9238 2230 | video9239 2231 | video9240 2232 | video9241 2233 | video9242 2234 | video9243 2235 | video9244 2236 | video9245 2237 | video9246 2238 | video9247 2239 | video9248 2240 | video9249 2241 | video9250 2242 | video9251 2243 | video9252 2244 | video9253 2245 | video9254 2246 | video9255 2247 | video9256 2248 | video9257 2249 | video9258 2250 | video9259 2251 | video9260 2252 | video9261 2253 | video9262 2254 | video9263 2255 | video9264 2256 | video9265 2257 | video9266 2258 | video9267 2259 | video9268 2260 | video9269 2261 | video9270 2262 | video9271 2263 | video9272 2264 | video9273 2265 | video9274 2266 | video9275 2267 | video9276 2268 | video9277 2269 | video9278 2270 | video9279 2271 | video9280 2272 | video9281 2273 | video9282 2274 | video9283 2275 | video9284 2276 | video9285 2277 | video9286 2278 | video9287 2279 | video9288 2280 | video9289 2281 | video9290 2282 | video9291 2283 | video9292 2284 | video9293 2285 | video9294 2286 | video9295 2287 | video9296 2288 | video9297 2289 | video9298 2290 | video9299 2291 | video9300 2292 | video9301 2293 | video9302 2294 | video9303 2295 | video9304 2296 | video9305 2297 | video9306 2298 | video9307 2299 | video9308 2300 | video9309 2301 | video9310 2302 | video9311 2303 | video9312 2304 | video9313 2305 | video9314 2306 | video9315 2307 | video9316 2308 | video9317 2309 | video9318 2310 | video9319 2311 | video9320 2312 | video9321 2313 | video9322 2314 | video9323 2315 | video9324 2316 | video9325 2317 | video9326 2318 | video9327 2319 | video9328 2320 | video9329 2321 | video9330 2322 | video9331 2323 | video9332 2324 | video9333 2325 | video9334 2326 | video9335 2327 | video9336 2328 | video9337 2329 | video9338 2330 | video9339 2331 | video9340 2332 | video9341 2333 | video9342 2334 | video9343 2335 | video9344 2336 | video9345 2337 | video9346 2338 | video9347 2339 | video9348 2340 | video9349 2341 | video9350 2342 | video9351 2343 | video9352 2344 | video9353 2345 | video9354 2346 | video9355 2347 | video9356 2348 | video9357 2349 | video9358 2350 | video9359 2351 | video9360 2352 | video9361 2353 | video9362 2354 | video9363 2355 | video9364 2356 | video9365 2357 | video9366 2358 | video9367 2359 | video9368 2360 | video9369 2361 | video9370 2362 | video9371 2363 | video9372 2364 | video9373 2365 | video9374 2366 | video9375 2367 | video9376 2368 | video9377 2369 | video9378 2370 | video9379 2371 | video9380 2372 | video9381 2373 | video9382 2374 | video9383 2375 | video9384 2376 | video9385 2377 | video9386 2378 | video9387 2379 | video9388 2380 | video9389 2381 | video9390 2382 | video9391 2383 | video9392 2384 | video9393 2385 | video9394 2386 | video9395 2387 | video9396 2388 | video9397 2389 | video9398 2390 | video9399 2391 | video9400 2392 | video9401 2393 | video9402 2394 | video9403 2395 | video9404 2396 | video9405 2397 | video9406 2398 | video9407 2399 | video9408 2400 | video9409 2401 | video9410 2402 | video9411 2403 | video9412 2404 | video9413 2405 | video9414 2406 | video9415 2407 | video9416 2408 | video9417 2409 | video9418 2410 | video9419 2411 | video9420 2412 | video9421 2413 | video9422 2414 | video9423 2415 | video9424 2416 | video9425 2417 | video9426 2418 | video9427 2419 | video9428 2420 | video9429 2421 | video9430 2422 | video9431 2423 | video9432 2424 | video9433 2425 | video9434 2426 | video9435 2427 | video9436 2428 | video9437 2429 | video9438 2430 | video9439 2431 | video9440 2432 | video9441 2433 | video9442 2434 | video9443 2435 | video9444 2436 | video9445 2437 | video9446 2438 | video9447 2439 | video9448 2440 | video9449 2441 | video9450 2442 | video9451 2443 | video9452 2444 | video9453 2445 | video9454 2446 | video9455 2447 | video9456 2448 | video9457 2449 | video9458 2450 | video9459 2451 | video9460 2452 | video9461 2453 | video9462 2454 | video9463 2455 | video9464 2456 | video9465 2457 | video9466 2458 | video9467 2459 | video9468 2460 | video9469 2461 | video9470 2462 | video9471 2463 | video9472 2464 | video9473 2465 | video9474 2466 | video9475 2467 | video9476 2468 | video9477 2469 | video9478 2470 | video9479 2471 | video9480 2472 | video9481 2473 | video9482 2474 | video9483 2475 | video9484 2476 | video9485 2477 | video9486 2478 | video9487 2479 | video9488 2480 | video9489 2481 | video9490 2482 | video9491 2483 | video9492 2484 | video9493 2485 | video9494 2486 | video9495 2487 | video9496 2488 | video9497 2489 | video9498 2490 | video9499 2491 | video9500 2492 | video9501 2493 | video9502 2494 | video9503 2495 | video9504 2496 | video9505 2497 | video9506 2498 | video9507 2499 | video9508 2500 | video9509 2501 | video9510 2502 | video9511 2503 | video9512 2504 | video9513 2505 | video9514 2506 | video9515 2507 | video9516 2508 | video9517 2509 | video9518 2510 | video9519 2511 | video9520 2512 | video9521 2513 | video9522 2514 | video9523 2515 | video9524 2516 | video9525 2517 | video9526 2518 | video9527 2519 | video9528 2520 | video9529 2521 | video9530 2522 | video9531 2523 | video9532 2524 | video9533 2525 | video9534 2526 | video9535 2527 | video9536 2528 | video9537 2529 | video9538 2530 | video9539 2531 | video9540 2532 | video9541 2533 | video9542 2534 | video9543 2535 | video9544 2536 | video9545 2537 | video9546 2538 | video9547 2539 | video9548 2540 | video9549 2541 | video9550 2542 | video9551 2543 | video9552 2544 | video9553 2545 | video9554 2546 | video9555 2547 | video9556 2548 | video9557 2549 | video9558 2550 | video9559 2551 | video9560 2552 | video9561 2553 | video9562 2554 | video9563 2555 | video9564 2556 | video9565 2557 | video9566 2558 | video9567 2559 | video9568 2560 | video9569 2561 | video9570 2562 | video9571 2563 | video9572 2564 | video9573 2565 | video9574 2566 | video9575 2567 | video9576 2568 | video9577 2569 | video9578 2570 | video9579 2571 | video9580 2572 | video9581 2573 | video9582 2574 | video9583 2575 | video9584 2576 | video9585 2577 | video9586 2578 | video9587 2579 | video9588 2580 | video9589 2581 | video9590 2582 | video9591 2583 | video9592 2584 | video9593 2585 | video9594 2586 | video9595 2587 | video9596 2588 | video9597 2589 | video9598 2590 | video9599 2591 | video9600 2592 | video9601 2593 | video9602 2594 | video9603 2595 | video9604 2596 | video9605 2597 | video9606 2598 | video9607 2599 | video9608 2600 | video9609 2601 | video9610 2602 | video9611 2603 | video9612 2604 | video9613 2605 | video9614 2606 | video9615 2607 | video9616 2608 | video9617 2609 | video9618 2610 | video9619 2611 | video9620 2612 | video9621 2613 | video9622 2614 | video9623 2615 | video9624 2616 | video9625 2617 | video9626 2618 | video9627 2619 | video9628 2620 | video9629 2621 | video9630 2622 | video9631 2623 | video9632 2624 | video9633 2625 | video9634 2626 | video9635 2627 | video9636 2628 | video9637 2629 | video9638 2630 | video9639 2631 | video9640 2632 | video9641 2633 | video9642 2634 | video9643 2635 | video9644 2636 | video9645 2637 | video9646 2638 | video9647 2639 | video9648 2640 | video9649 2641 | video9650 2642 | video9651 2643 | video9652 2644 | video9653 2645 | video9654 2646 | video9655 2647 | video9656 2648 | video9657 2649 | video9658 2650 | video9659 2651 | video9660 2652 | video9661 2653 | video9662 2654 | video9663 2655 | video9664 2656 | video9665 2657 | video9666 2658 | video9667 2659 | video9668 2660 | video9669 2661 | video9670 2662 | video9671 2663 | video9672 2664 | video9673 2665 | video9674 2666 | video9675 2667 | video9676 2668 | video9677 2669 | video9678 2670 | video9679 2671 | video9680 2672 | video9681 2673 | video9682 2674 | video9683 2675 | video9684 2676 | video9685 2677 | video9686 2678 | video9687 2679 | video9688 2680 | video9689 2681 | video9690 2682 | video9691 2683 | video9692 2684 | video9693 2685 | video9694 2686 | video9695 2687 | video9696 2688 | video9697 2689 | video9698 2690 | video9699 2691 | video9700 2692 | video9701 2693 | video9702 2694 | video9703 2695 | video9704 2696 | video9705 2697 | video9706 2698 | video9707 2699 | video9708 2700 | video9709 2701 | video9710 2702 | video9711 2703 | video9712 2704 | video9713 2705 | video9714 2706 | video9715 2707 | video9716 2708 | video9717 2709 | video9718 2710 | video9719 2711 | video9720 2712 | video9721 2713 | video9722 2714 | video9723 2715 | video9724 2716 | video9725 2717 | video9726 2718 | video9727 2719 | video9728 2720 | video9729 2721 | video9730 2722 | video9731 2723 | video9732 2724 | video9733 2725 | video9734 2726 | video9735 2727 | video9736 2728 | video9737 2729 | video9738 2730 | video9739 2731 | video9740 2732 | video9741 2733 | video9742 2734 | video9743 2735 | video9744 2736 | video9745 2737 | video9746 2738 | video9747 2739 | video9748 2740 | video9749 2741 | video9750 2742 | video9751 2743 | video9752 2744 | video9753 2745 | video9754 2746 | video9755 2747 | video9756 2748 | video9757 2749 | video9758 2750 | video9759 2751 | video9760 2752 | video9761 2753 | video9762 2754 | video9763 2755 | video9764 2756 | video9765 2757 | video9766 2758 | video9767 2759 | video9768 2760 | video9769 2761 | video9770 2762 | video9771 2763 | video9772 2764 | video9773 2765 | video9774 2766 | video9775 2767 | video9776 2768 | video9777 2769 | video9778 2770 | video9779 2771 | video9780 2772 | video9781 2773 | video9782 2774 | video9783 2775 | video9784 2776 | video9785 2777 | video9786 2778 | video9787 2779 | video9788 2780 | video9789 2781 | video9790 2782 | video9791 2783 | video9792 2784 | video9793 2785 | video9794 2786 | video9795 2787 | video9796 2788 | video9797 2789 | video9798 2790 | video9799 2791 | video9800 2792 | video9801 2793 | video9802 2794 | video9803 2795 | video9804 2796 | video9805 2797 | video9806 2798 | video9807 2799 | video9808 2800 | video9809 2801 | video9810 2802 | video9811 2803 | video9812 2804 | video9813 2805 | video9814 2806 | video9815 2807 | video9816 2808 | video9817 2809 | video9818 2810 | video9819 2811 | video9820 2812 | video9821 2813 | video9822 2814 | video9823 2815 | video9824 2816 | video9825 2817 | video9826 2818 | video9827 2819 | video9828 2820 | video9829 2821 | video9830 2822 | video9831 2823 | video9832 2824 | video9833 2825 | video9834 2826 | video9835 2827 | video9836 2828 | video9837 2829 | video9838 2830 | video9839 2831 | video9840 2832 | video9841 2833 | video9842 2834 | video9843 2835 | video9844 2836 | video9845 2837 | video9846 2838 | video9847 2839 | video9848 2840 | video9849 2841 | video9850 2842 | video9851 2843 | video9852 2844 | video9853 2845 | video9854 2846 | video9855 2847 | video9856 2848 | video9857 2849 | video9858 2850 | video9859 2851 | video9860 2852 | video9861 2853 | video9862 2854 | video9863 2855 | video9864 2856 | video9865 2857 | video9866 2858 | video9867 2859 | video9868 2860 | video9869 2861 | video9870 2862 | video9871 2863 | video9872 2864 | video9873 2865 | video9874 2866 | video9875 2867 | video9876 2868 | video9877 2869 | video9878 2870 | video9879 2871 | video9880 2872 | video9881 2873 | video9882 2874 | video9883 2875 | video9884 2876 | video9885 2877 | video9886 2878 | video9887 2879 | video9888 2880 | video9889 2881 | video9890 2882 | video9891 2883 | video9892 2884 | video9893 2885 | video9894 2886 | video9895 2887 | video9896 2888 | video9897 2889 | video9898 2890 | video9899 2891 | video9900 2892 | video9901 2893 | video9902 2894 | video9903 2895 | video9904 2896 | video9905 2897 | video9906 2898 | video9907 2899 | video9908 2900 | video9909 2901 | video9910 2902 | video9911 2903 | video9912 2904 | video9913 2905 | video9914 2906 | video9915 2907 | video9916 2908 | video9917 2909 | video9918 2910 | video9919 2911 | video9920 2912 | video9921 2913 | video9922 2914 | video9923 2915 | video9924 2916 | video9925 2917 | video9926 2918 | video9927 2919 | video9928 2920 | video9929 2921 | video9930 2922 | video9931 2923 | video9932 2924 | video9933 2925 | video9934 2926 | video9935 2927 | video9936 2928 | video9937 2929 | video9938 2930 | video9939 2931 | video9940 2932 | video9941 2933 | video9942 2934 | video9943 2935 | video9944 2936 | video9945 2937 | video9946 2938 | video9947 2939 | video9948 2940 | video9949 2941 | video9950 2942 | video9951 2943 | video9952 2944 | video9953 2945 | video9954 2946 | video9955 2947 | video9956 2948 | video9957 2949 | video9958 2950 | video9959 2951 | video9960 2952 | video9961 2953 | video9962 2954 | video9963 2955 | video9964 2956 | video9965 2957 | video9966 2958 | video9967 2959 | video9968 2960 | video9969 2961 | video9970 2962 | video9971 2963 | video9972 2964 | video9973 2965 | video9974 2966 | video9975 2967 | video9976 2968 | video9977 2969 | video9978 2970 | video9979 2971 | video9980 2972 | video9981 2973 | video9982 2974 | video9983 2975 | video9984 2976 | video9985 2977 | video9986 2978 | video9987 2979 | video9988 2980 | video9989 2981 | video9990 2982 | video9991 2983 | video9992 2984 | video9993 2985 | video9994 2986 | video9995 2987 | video9996 2988 | video9997 2989 | video9998 2990 | video9999 2991 | -------------------------------------------------------------------------------- /models/clip_model.py: -------------------------------------------------------------------------------- 1 | import torch 2 | import numpy as np 3 | import models.CLIP.clip as clip 4 | 5 | class CLIP: 6 | def __init__(self): 7 | self.device = "cuda" 8 | self.model, _ = clip.load("ViT-B/32", device=self.device) 9 | self.mean = torch.tensor([0.48145466, 0.4578275, 0.40821073])[None,:,None,None].cuda() 10 | self.std = torch.tensor([0.26862954, 0.26130258, 0.27577711])[None,:,None,None].cuda() 11 | 12 | @torch.no_grad() 13 | def __call__(self, frames): 14 | # frames: (bs, t, h, w, c), t=1 15 | frames = torch.from_numpy(frames.astype(np.float32)).squeeze(dim=1).to(self.device) # (bs, h, w, c) 16 | frames.div_(255.) 17 | frames = frames.permute(0, 3, 1, 2) 18 | frames = (frames - self.mean) / self.std 19 | embs = self.model.encode_image(frames) 20 | return embs.cpu().numpy().astype('float32') 21 | 22 | 23 | -------------------------------------------------------------------------------- /models/mmt/__init__.py: -------------------------------------------------------------------------------- 1 | import sys 2 | from collections import OrderedDict 3 | import types 4 | from models.mmt.bert_mmt import BertModel 5 | 6 | import torch as th 7 | import torch.nn as nn 8 | import torch.nn.functional as F 9 | from transformers.modeling_bert import BertModel as TxtBertModel 10 | from transformers import AutoTokenizer 11 | import torch 12 | import os 13 | 14 | 15 | def state_dict_txt_bert(state): 16 | state_dict1 = {} 17 | state_dict = state 18 | for key in state_dict.keys(): 19 | if key.startswith('text_GU.'): 20 | key1 = key.replace('text_GU.', 'text_gu.') 21 | else: 22 | key1 = key 23 | if not (\ 24 | key.startswith('txt_bert.') or \ 25 | key.startswith('text_gu.') or \ 26 | key.startswith('text_GU.') or \ 27 | 'moe_fc_txt' in key or \ 28 | 'moe_txt_dropout' in key \ 29 | ): 30 | continue 31 | state_dict1[key1] = state_dict[key] 32 | return state_dict1 33 | 34 | def state_dict_vid_bert(state): 35 | state1 = {} 36 | state_dict = state 37 | for key in state_dict: 38 | if key.startswith('vid_bert') or key.startswith('video_dim_reduce') or key.startswith('video_dim_reduce'): 39 | state1[key] = state_dict[key] 40 | return state1 41 | 42 | class ContextGating(nn.Module): 43 | def __init__(self, dimension, add_batch_norm=True): 44 | super(ContextGating, self).__init__() 45 | self.fc = nn.Linear(dimension, dimension) 46 | self.add_batch_norm = add_batch_norm 47 | self.batch_norm = nn.BatchNorm1d(dimension) 48 | 49 | def forward(self, x): 50 | x1 = self.fc(x) 51 | if self.add_batch_norm: 52 | x1 = self.batch_norm(x1) 53 | x = th.cat((x, x1), 1) 54 | return F.glu(x, 1) 55 | 56 | 57 | class GatedEmbeddingUnit(nn.Module): 58 | def __init__(self, input_dimension, output_dimension, use_bn, normalize): 59 | super(GatedEmbeddingUnit, self).__init__() 60 | self.fc = nn.Linear(input_dimension, output_dimension) 61 | self.cg = ContextGating(output_dimension, add_batch_norm=use_bn) 62 | self.normalize = normalize 63 | 64 | def forward(self, x): 65 | x = self.fc(x) 66 | x = self.cg(x) 67 | if self.normalize: 68 | x = F.normalize(x, dim=-1) 69 | return x 70 | 71 | 72 | class ReduceDim(nn.Module): 73 | def __init__(self, input_dimension, output_dimension): 74 | super(ReduceDim, self).__init__() 75 | self.fc = nn.Linear(input_dimension, output_dimension) 76 | 77 | def forward(self, x): 78 | x = self.fc(x) 79 | x = F.normalize(x, dim=-1) 80 | return x 81 | 82 | def get_maxp(embd, mask): 83 | # (bs, ntok, embdim) 84 | # (bs, ntok) 1==token, 0==pad 85 | mask = mask.clone().to(dtype=torch.float32) 86 | all_pad_idxs = (mask==0).all(dim=1) 87 | mask[mask == 0] = float('-inf') 88 | mask[mask == 1] = 0 89 | maxp = (embd + mask[..., None]).max(dim=1)[0] # (bs, embdim) 90 | maxp[all_pad_idxs] = 0 # if there is not embeddings, use zeros 91 | return maxp 92 | 93 | def pad(x, max_length): 94 | bs, n = x.shape 95 | if n < max_length: 96 | padding = torch.zeros(bs, max_length - n, dtype=x.dtype) 97 | x = torch.cat([x, padding], dim=1) 98 | return x 99 | 100 | 101 | class BertTXT(nn.Module): 102 | def __init__(self, 103 | txt_bert_config='/ssd/ssd_srv79/models/huggingface/bert-base-cased', 104 | max_length=30, 105 | modalities=['tf_s3dg_k600'], 106 | add_special_tokens=True, 107 | add_dot=True, 108 | same_dim=512, 109 | txt_bert_params = { 110 | 'hidden_dropout_prob': 0.1, 111 | 'attention_probs_dropout_prob': 0.1, 112 | }, 113 | ): 114 | super().__init__() 115 | self.orig_mmt_comaptible = int(os.environ.get('ORIG_MMT_COMPAT', 0)) 116 | if self.orig_mmt_comaptible: 117 | print('ORIG_MMT_COMPAT') 118 | dout_prob = txt_bert_params['hidden_dropout_prob'] 119 | self.add_dot = add_dot 120 | self.add_special_tokens = add_special_tokens 121 | self.modalities = modalities 122 | self.max_length = max_length 123 | self.tokenizer = AutoTokenizer.from_pretrained(txt_bert_config) 124 | self.txt_bert = TxtBertModel.from_pretrained(txt_bert_config, **txt_bert_params) 125 | text_dim = self.txt_bert.config.hidden_size 126 | 127 | self.text_gu = nn.ModuleDict() 128 | for mod in self.modalities: 129 | self.text_gu[mod] = GatedEmbeddingUnit(text_dim, 130 | same_dim, 131 | use_bn=True, 132 | normalize=True) 133 | 134 | self.moe_fc_txt = nn.ModuleDict() 135 | self.moe_txt_dropout = nn.Dropout(dout_prob) 136 | for mod in self.modalities: 137 | self.moe_fc_txt[mod] = nn.Linear(text_dim, 1) 138 | 139 | @property 140 | def device(self): 141 | return next(self.parameters()).data.device 142 | 143 | def compute_weights_from_emb(self, embd): 144 | embd = self.moe_txt_dropout(embd) 145 | m = len(self.modalities) 146 | moe_weights = th.cat([self.moe_fc_txt[mod](embd) for mod in self.modalities], dim=-1) 147 | moe_weights = F.softmax(moe_weights, dim=1) 148 | return moe_weights 149 | 150 | def forward(self, text_list): 151 | if self.add_dot: 152 | text_list1 = [] 153 | for x in text_list: 154 | x = x.strip() 155 | if x[-1] not in ('.', '?', '!'): 156 | x = x + '.' 157 | text_list1.append(x) 158 | text_list = text_list1 159 | device = self.device 160 | encoded_inputs = self.tokenizer(text_list, 161 | max_length=self.max_length, 162 | truncation=True, 163 | add_special_tokens=self.add_special_tokens, 164 | padding=True, 165 | return_tensors='pt') 166 | bs, ntok = encoded_inputs['input_ids'].shape 167 | if self.orig_mmt_comaptible: 168 | encoded_inputs = {key: pad(value, self.max_length).to(device) for key, value in encoded_inputs.items()} 169 | encoded_inputs['head_mask'] = None 170 | else: 171 | encoded_inputs = {key: value.to(device) for key, value in encoded_inputs.items()} 172 | x = self.txt_bert(**encoded_inputs)[0] # (bs, max_tokens, hidden_size) 173 | # authors of MMT take token 0 and think that it is CLS 174 | # but they dont provide CLS token to input 175 | text = x[:,0,:] 176 | text_embd = [] 177 | for mod in self.modalities: 178 | layer = self.text_gu[mod] # this layer containg F.normalize 179 | text_ = layer(text) # (bs, d_model) this is unit-length embs 180 | if self.orig_mmt_comaptible: 181 | text_ = F.normalize(text_) 182 | text_ = text_.unsqueeze(1) # (bs, 1, d_model) 183 | text_embd.append(text_) 184 | text_embd = torch.cat(text_embd, dim=1) # (bs, nmods, d_model) 185 | if len(self.modalities) > 1: 186 | text_weights = self.compute_weights_from_emb(text) # (bs, nmods) 187 | embd_wg = text_embd * text_weights[..., None] # (bs, nmods, d_model) 188 | else: 189 | embd_wg = text_embd 190 | 191 | bs = embd_wg.size(0) 192 | text_embd = embd_wg.view(bs, -1) 193 | 194 | return text_embd 195 | 196 | class BertVID(nn.Module): 197 | def __init__(self, 198 | expert_dims={ 199 | 'tf_s3dg_k600': dict(idx=0, dim=1024), 200 | }, 201 | same_dim=512, 202 | vid_bert_params=OrderedDict([ 203 | ('vocab_size_or_config_json_file', 10), 204 | ('hidden_size', 512), 205 | ('num_hidden_layers', 4), 206 | ('num_attention_heads', 4), 207 | ('intermediate_size', 3072), 208 | ('hidden_act', 'gelu'), 209 | ('hidden_dropout_prob', 0.1), 210 | ('attention_probs_dropout_prob', 0.1), 211 | ('max_position_embeddings', 32), 212 | ('type_vocab_size', 19), 213 | ('initializer_range', 0.02), 214 | ('layer_norm_eps', 1e-12) 215 | ]), 216 | ): 217 | super().__init__() 218 | self.modalities = list(expert_dims.keys()) 219 | self.same_dim = same_dim 220 | self.expert_dims = expert_dims 221 | self.vid_bert_params = vid_bert_params 222 | self.hidden_size = self.vid_bert_params["hidden_size"] 223 | 224 | vid_bert_config = types.SimpleNamespace(**self.vid_bert_params) 225 | self.vid_bert = BertModel(vid_bert_config) 226 | 227 | self.video_dim_reduce = nn.ModuleDict() 228 | for mod in self.modalities: 229 | in_dim = expert_dims[mod]['dim'] 230 | self.video_dim_reduce[mod] = ReduceDim(in_dim, self.hidden_size) 231 | 232 | if same_dim != self.hidden_size: 233 | self.video_dim_reduce_out = nn.ModuleDict() 234 | for mod in self.modalities: 235 | self.video_dim_reduce_out[mod] = ReduceDim(self.hidden_size, same_dim) 236 | 237 | @property 238 | def device(self): 239 | return next(self.parameters()).data.device 240 | 241 | def forward(self, 242 | features, # embs from pretrained models {modality: (bs, ntok, embdim)} 243 | features_t, # timings {modality: (bs, ntok)} each value is (emb_t_start + emb_t_end) / 2 244 | features_ind, # mask (modality: (bs, ntok)) 245 | features_maxp=None, 246 | ): 247 | device = self.device 248 | #for mod in features_t.keys(): 249 | # import pdb; pdb.set_trace() 250 | # features_t[mod][features_ind[mod]==0] = 1 251 | experts_feats = dict(features) 252 | experts_feats_t = dict(features_t) 253 | experts_feats_ind = dict(features_ind) 254 | ind = {} # 1 if there is at least one non-pad token in this modality 255 | for mod in self.modalities: 256 | ind[mod] = th.max(experts_feats_ind[mod], 1)[0] 257 | 258 | for mod in self.modalities: 259 | layer = self.video_dim_reduce[mod] 260 | experts_feats[mod] = layer(experts_feats[mod]) 261 | 262 | bs = next(iter(features.values())).size(0) 263 | ids_size = (bs,) 264 | input_ids_list = [] 265 | token_type_ids_list = [] # Modality id 266 | # Position (0 = no position, 1 = unknown, >1 = valid position) 267 | position_ids_list = [] 268 | features_list = [] # Semantics 269 | attention_mask_list = [] # Valid token or not 270 | 271 | modality_to_tok_map = OrderedDict() 272 | 273 | # 0=[CLS] 1=[SEP] 2=[AGG] 3=[MAXP] 4=[MNP] 5=[VLAD] 6=[FEA] 274 | # [CLS] token 275 | tok_id = 0 276 | input_ids_list.append(th.full(ids_size, 0, dtype=th.long)) 277 | token_type_ids_list.append(th.full(ids_size, 0, dtype=th.long)) 278 | position_ids_list.append(th.full(ids_size, 0, dtype=th.long).to(device)) 279 | features_list.append(th.full((bs, self.hidden_size), 0, dtype=th.float).to(device)) 280 | attention_mask_list.append(th.full(ids_size, 1, dtype=th.long).to(device)) 281 | 282 | # Number of temporal tokens per modality 283 | max_expert_tokens = OrderedDict() 284 | for modality in self.modalities: 285 | max_expert_tokens[modality] = experts_feats[modality].size()[1] 286 | 287 | # Clamp the position encoding to [0, max_position_embedding - 1] 288 | max_pos = self.vid_bert_params['max_position_embeddings'] - 1 289 | for modality in self.modalities: 290 | experts_feats_t[modality].clamp_(min=0, max=max_pos) 291 | experts_feats_t[modality] = experts_feats_t[modality].long().to(device) 292 | 293 | for modality in self.modalities: 294 | token_type = self.expert_dims[modality]['idx'] 295 | tok_id += 1 296 | 297 | # add aggregation token 298 | modality_to_tok_map[modality] = tok_id 299 | input_ids_list.append(th.full(ids_size, 2, dtype=th.long)) 300 | token_type_ids_list.append(th.full(ids_size, token_type, dtype=th.long)) 301 | position_ids_list.append(th.full(ids_size, 0, dtype=th.long).to(device)) 302 | layer = self.video_dim_reduce[modality] 303 | if features_maxp is not None: 304 | feat_maxp = features_maxp[modality] 305 | else: 306 | feat_maxp = get_maxp(features[modality], experts_feats_ind[modality]) # (bs, embdim) 307 | features_list.append(layer(feat_maxp)) 308 | attention_mask_list.append(ind[modality].to(dtype=th.long).to(device)) 309 | 310 | # add expert tokens 311 | for frame_id in range(max_expert_tokens[modality]): 312 | tok_id += 1 313 | position_ids_list.append(experts_feats_t[modality][:, frame_id]) 314 | input_ids_list.append(th.full(ids_size, 6, dtype=th.long)) 315 | token_type_ids_list.append(th.full(ids_size, token_type, dtype=th.long)) 316 | features_list.append(experts_feats[modality][:, frame_id, :]) 317 | attention_mask_list.append(experts_feats_ind[modality][:, frame_id].to(dtype=th.long)) 318 | 319 | features = th.stack(features_list, dim=1).to(self.device) 320 | input_ids = th.stack(input_ids_list, dim=1).to(self.device) 321 | token_type_ids = th.stack(token_type_ids_list, dim=1).to(self.device) 322 | position_ids = th.stack(position_ids_list, dim=1).to(self.device) 323 | attention_mask = th.stack(attention_mask_list, dim=1).to(self.device) 324 | vid_bert_output = self.vid_bert(input_ids, 325 | attention_mask=attention_mask, 326 | token_type_ids=token_type_ids, 327 | position_ids=position_ids, 328 | features=features) 329 | #return input_ids, attention_mask, token_type_ids, position_ids, features 330 | last_layer = vid_bert_output[0] 331 | vid_embd = last_layer[:, 0] 332 | #return vid_embd 333 | #experts = {} 334 | #for _, modality in enumerate(self.modalities): 335 | # experts[modality] = last_layer[:, modality_to_tok_map[modality]] 336 | 337 | experts = [] 338 | for modality in self.modalities: 339 | emb = last_layer[:, modality_to_tok_map[modality]] 340 | if self.same_dim != self.hidden_size: 341 | emb = self.video_dim_reduce_out[mod](emb) 342 | agg_tok_out = F.normalize(emb, dim=1) 343 | #if ind[modality].sum() > 0: 344 | # import pdb; pdb.set_trace() 345 | experts.append(agg_tok_out) # (bs, embdim) 346 | experts = torch.cat(experts, dim=1) 347 | return experts 348 | 349 | if __name__ == "__main__": 350 | torch.set_grad_enabled(False) 351 | #sys.path.insert(0, '/home/wx587276/shared_folder/src/mmt_orig') 352 | from model.model import CENet 353 | model_pt = '/ssd/ssd_srv79/dza/mmt/exps/cleaning/MSRVTT_jsfusion_trainval/orig/2/trained_model.pth' 354 | state = torch.load(model_pt, map_location=torch.device('cpu')) 355 | bs = 2 356 | 357 | expert_dims = { 358 | "face": { 359 | "dim": 512, 360 | "idx": 3, 361 | "max_tok": 30 362 | }, 363 | "ocr": { 364 | "dim": 300, 365 | "idx": 7, 366 | "max_tok": 30 367 | }, 368 | "rgb": { 369 | "dim": 2048, 370 | "idx": 5, 371 | "max_tok": 30 372 | }, 373 | "s3d": { 374 | "dim": 1024, 375 | "idx": 1, 376 | "max_tok": 30 377 | }, 378 | "scene": { 379 | "dim": 2208, 380 | "idx": 9, 381 | "max_tok": 30 382 | }, 383 | "speech": { 384 | "dim": 300, 385 | "idx": 6, 386 | "max_tok": 30 387 | }, 388 | "vggish": { 389 | "dim": 128, 390 | "idx": 2, 391 | "max_tok": 30 392 | } 393 | } 394 | 395 | def rand_batch(expert_dims, bs): 396 | features = {} 397 | features_t = {} 398 | features_ind = {} 399 | for mod, info in expert_dims.items(): 400 | dim = info['dim'] 401 | ntok = info['max_tok'] 402 | features[mod] = torch.randn(bs, ntok, dim) 403 | features_ind[mod] = torch.ones(bs, ntok) 404 | if mod in ['s3d', 'vggish', 'scene']: 405 | t1 = torch.arange(0, ntok) 406 | t2 = torch.arange(1, ntok+1) 407 | tt = 2 + (t1+t2) / 2 408 | features_t[mod] = tt[None,...].expand(bs,ntok).clone() 409 | elif mod in ['rgb']: 410 | t1 = torch.arange(0, ntok, 0.2)[:ntok] 411 | t2 = torch.arange(0.2, ntok, 0.2)[:ntok] 412 | tt = 2 + (t1+t2) / 2 413 | features_t[mod] = tt[None,...].expand(bs,ntok).clone() 414 | else: 415 | features_t[mod] = torch.ones(bs, ntok) 416 | return features, features_t, features_ind 417 | 418 | features, features_t, features_ind = rand_batch(expert_dims, bs=bs) 419 | features_ind['s3d'] = torch.zeros_like(features_ind['face']) 420 | 421 | features_maxpool = {modality: get_maxp(features[modality], features_ind[modality]) for modality in expert_dims.keys()} 422 | features_avgpool = features_maxpool 423 | 424 | text_list = ['I love my wife', 'my son is growing too fast'] 425 | 426 | 427 | vid_bert_params = OrderedDict([ 428 | ('vocab_size_or_config_json_file', 10), 429 | ('hidden_size', 512), 430 | ('num_hidden_layers', 4), 431 | ('num_attention_heads', 4), 432 | ('intermediate_size', 3072), 433 | ('hidden_act', 'gelu'), 434 | ('hidden_dropout_prob', 0.1), 435 | ('attention_probs_dropout_prob', 0.1), 436 | ('max_position_embeddings', 32), 437 | ('type_vocab_size', 19), 438 | ('initializer_range', 0.02), 439 | ('layer_norm_eps', 1e-12) 440 | ]) 441 | 442 | txt_bert_params = OrderedDict([ 443 | ('hidden_dropout_prob', 0.1), 444 | ('attention_probs_dropout_prob', 0.1) 445 | ]) 446 | 447 | 448 | print('Loading CENet ...') 449 | cenet = CENet( 450 | l2renorm=False, 451 | expert_dims=expert_dims, 452 | tokenizer=None, 453 | keep_missing_modalities=True, 454 | test_caption_mode='indep', 455 | freeze_weights=False, 456 | mimic_ce_dims=False, 457 | concat_experts=False, 458 | concat_mix_experts=False, 459 | use_experts='origfeat', 460 | txt_inp='bertftn', 461 | txt_agg='bertftn', 462 | txt_pro='gbn', 463 | txt_wgh='emb', 464 | vid_inp='both', 465 | vid_cont='bert', 466 | vid_wgh='none', 467 | pos_enc='tint', 468 | out_tok='mxp', 469 | use_mask='nomask', 470 | same_dim=512, 471 | vid_bert_params=vid_bert_params, 472 | txt_bert_params=txt_bert_params, 473 | agg_dims=None, 474 | normalize_experts=True) 475 | state1 = {key.replace('text_GU', 'text_gu'): val for key, val in state['state_dict'].items()} 476 | cenet.load_state_dict(state1) 477 | cenet.eval() 478 | 479 | print('Loading BertVID ...') 480 | vid_bert = BertVID(expert_dims=expert_dims, vid_bert_params=vid_bert_params) 481 | vid_bert.eval() 482 | vid_bert.load_state_dict(state_dict_vid_bert(state['state_dict']), strict=True) 483 | 484 | print('Loading BertTXT ...') 485 | txt_bert = BertTXT(txt_bert_params=txt_bert_params, modalities=list(expert_dims.keys())) 486 | txt_bert.eval() 487 | txt_bert.load_state_dict(state_dict_txt_bert(state['state_dict']), strict=True) 488 | 489 | vid_embd = vid_bert(features=features, features_t=features_t, features_ind=features_ind) 490 | txt_embd = txt_bert(text_list) 491 | 492 | max_text_words = 30 493 | ce_txt_input = torch.zeros(bs, 1, max_text_words, 2).long() 494 | text_list1 = [] 495 | for x in text_list: 496 | x = x.strip() 497 | if x[-1] not in ('.', '?', '!'): 498 | x = x + '.' 499 | text_list1.append(x) 500 | text_list = text_list1 501 | encoded_inputs = txt_bert.tokenizer(text_list, 502 | max_length=max_text_words, 503 | truncation=True, 504 | add_special_tokens=True, 505 | padding=True, 506 | return_tensors='pt') 507 | toks = encoded_inputs['input_ids'] 508 | bs_, ntoks = toks.shape 509 | ce_txt_input[:,0,:ntoks,0] = toks 510 | ce_txt_input[:,0,:ntoks,1] = (toks>0).long() 511 | 512 | ori_output = cenet( 513 | token_ids=ce_txt_input, 514 | features=dict(features), 515 | features_t=dict(features_t), 516 | features_ind=dict(features_ind), 517 | features_avgpool=dict(features_avgpool), 518 | features_maxpool=dict(features_maxpool), 519 | query_masks=None, 520 | out='embds' 521 | ) 522 | 523 | wgh_ori_text_embds = (ori_output['text_embds'] * ori_output['text_weights'].transpose(1,2)[..., None]).reshape(bs, -1) 524 | print('TEXT:', (wgh_ori_text_embds - txt_embd).norm(dim=1).max().item(), wgh_ori_text_embds.norm()) 525 | print('VIDEO:', (ori_output['vid_embds'].reshape(bs, -1) - vid_embd).norm(dim=1).max().item(), vid_embd.norm()) 526 | 527 | 528 | -------------------------------------------------------------------------------- /models/mmt/bert_mmt.py: -------------------------------------------------------------------------------- 1 | # Copyright 2020 Valentin Gabeur 2 | # Copyright 2018 The Google AI Language Team Authors and The HuggingFace Inc. 3 | # team. 4 | # Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | """Logic for the Transformer architecture used for MMT. 18 | 19 | Code based on @huggingface implementation of Transformers: 20 | https://github.com/huggingface/transformers 21 | """ 22 | 23 | from __future__ import absolute_import 24 | from __future__ import division 25 | from __future__ import print_function 26 | from __future__ import unicode_literals 27 | 28 | import logging 29 | import math 30 | 31 | import torch 32 | from torch import nn 33 | 34 | logger = logging.getLogger(__name__) 35 | 36 | 37 | def gelu(x): 38 | """Implementation of the gelu activation function. 39 | 40 | For information: OpenAI GPT's gelu is slightly different (and gives 41 | slightly different results): 42 | 0.5 * x * (1 + torch.tanh(math.sqrt(2 / math.pi) * (x + 0.044715 * 43 | torch.pow(x, 3)))) 44 | Also see https://arxiv.org/abs/1606.08415 45 | 46 | Args: 47 | x: input 48 | 49 | Returns: 50 | gelu(x) 51 | 52 | """ 53 | return x * 0.5 * (1.0 + torch.erf(x / math.sqrt(2.0))) 54 | 55 | 56 | def swish(x): 57 | return x * torch.sigmoid(x) 58 | 59 | 60 | ACT2FN = {"gelu": gelu, "relu": torch.nn.functional.relu, "swish": swish} 61 | 62 | # try: 63 | # import apex.normalization.fused_layer_norm.FusedLayerNorm as BertLayerNorm 64 | # except (ImportError, AttributeError) as e: 65 | # logger.info( 66 | # "Better speed can be achieved with apex installed from " 67 | # "https://www.github.com/nvidia/apex ." 68 | # ) 69 | # BertLayerNorm = torch.nn.LayerNorm 70 | 71 | BertLayerNorm = torch.nn.LayerNorm 72 | 73 | 74 | class BertEmbeddings(nn.Module): 75 | """Construct the embeddings from word, position and token_type embeddings.""" 76 | 77 | def __init__(self, config): 78 | super(BertEmbeddings, self).__init__() 79 | self.position_embeddings = nn.Embedding(config.max_position_embeddings, 80 | config.hidden_size) 81 | self.token_type_embeddings = nn.Embedding(config.type_vocab_size, 82 | config.hidden_size) 83 | self.layer_norm = BertLayerNorm(config.hidden_size, 84 | eps=config.layer_norm_eps) 85 | self.dropout = nn.Dropout(config.hidden_dropout_prob) 86 | 87 | def forward(self, 88 | input_ids, 89 | token_type_ids=None, 90 | position_ids=None, 91 | features=None): 92 | if token_type_ids is None: 93 | token_type_ids = torch.zeros_like(input_ids) 94 | 95 | token_type_embeddings = self.token_type_embeddings(token_type_ids) 96 | 97 | if position_ids is not None: 98 | position_embeddings = self.position_embeddings(position_ids) 99 | embeddings = position_embeddings + token_type_embeddings + features 100 | else: 101 | embeddings = token_type_embeddings + features 102 | 103 | embeddings = self.layer_norm(embeddings) 104 | embeddings = self.dropout(embeddings) 105 | return embeddings 106 | 107 | 108 | class BertSelfAttention(nn.Module): 109 | """Self-attention mechanism.""" 110 | 111 | def __init__(self, config): 112 | super(BertSelfAttention, self).__init__() 113 | if config.hidden_size % config.num_attention_heads != 0: 114 | raise ValueError( 115 | "The hidden size (%d) is not a multiple of the number of attention " 116 | "heads (%d)" % (config.hidden_size, config.num_attention_heads)) 117 | self.output_attentions = False 118 | 119 | self.num_attention_heads = config.num_attention_heads 120 | self.attention_head_size = int(config.hidden_size 121 | / config.num_attention_heads) 122 | self.all_head_size = self.num_attention_heads * self.attention_head_size 123 | 124 | self.query = nn.Linear(config.hidden_size, self.all_head_size) 125 | self.key = nn.Linear(config.hidden_size, self.all_head_size) 126 | self.value = nn.Linear(config.hidden_size, self.all_head_size) 127 | 128 | self.dropout = nn.Dropout(config.attention_probs_dropout_prob) 129 | 130 | def transpose_for_scores(self, x): 131 | new_x_shape = x.size()[:-1] + (self.num_attention_heads, 132 | self.attention_head_size) 133 | x = x.view(*new_x_shape) 134 | return x.permute(0, 2, 1, 3) 135 | 136 | def forward(self, hidden_states, attention_mask, head_mask=None): 137 | mixed_query_layer = self.query(hidden_states) 138 | mixed_key_layer = self.key(hidden_states) 139 | mixed_value_layer = self.value(hidden_states) 140 | 141 | query_layer = self.transpose_for_scores(mixed_query_layer) 142 | key_layer = self.transpose_for_scores(mixed_key_layer) 143 | value_layer = self.transpose_for_scores(mixed_value_layer) 144 | 145 | # Take the dot product between "query" and "key" to get the raw attention 146 | # scores. 147 | attention_scores = torch.matmul(query_layer, key_layer.transpose(-1, -2)) 148 | attention_scores = attention_scores / math.sqrt(self.attention_head_size) 149 | # Apply the attention mask is (precomputed for all layers in BertModel 150 | # forward() function) 151 | attention_scores = attention_scores + attention_mask 152 | 153 | # Normalize the attention scores to probabilities. 154 | attention_probs = nn.Softmax(dim=-1)(attention_scores) 155 | 156 | # This is actually dropping out entire tokens to attend to, which might 157 | # seem a bit unusual, but is taken from the original Transformer paper. 158 | attention_probs = self.dropout(attention_probs) 159 | 160 | # Mask heads if we want to 161 | if head_mask is not None: 162 | attention_probs = attention_probs * head_mask 163 | 164 | context_layer = torch.matmul(attention_probs, value_layer) 165 | 166 | context_layer = context_layer.permute(0, 2, 1, 3).contiguous() 167 | new_context_layer_shape = context_layer.size()[:-2] + (self.all_head_size,) 168 | context_layer = context_layer.view(*new_context_layer_shape) 169 | 170 | outputs = (context_layer, 171 | attention_probs) if self.output_attentions else (context_layer,) 172 | return outputs 173 | 174 | 175 | class BertSelfOutput(nn.Module): 176 | """Self-attention output.""" 177 | 178 | def __init__(self, config): 179 | super(BertSelfOutput, self).__init__() 180 | self.dense = nn.Linear(config.hidden_size, config.hidden_size) 181 | self.layer_norm = BertLayerNorm(config.hidden_size, 182 | eps=config.layer_norm_eps) 183 | self.dropout = nn.Dropout(config.hidden_dropout_prob) 184 | 185 | def forward(self, hidden_states, input_tensor): 186 | hidden_states = self.dense(hidden_states) 187 | hidden_states = self.dropout(hidden_states) 188 | hidden_states = self.layer_norm(hidden_states + input_tensor) 189 | return hidden_states 190 | 191 | 192 | class BertAttention(nn.Module): 193 | """Self-attention layer.""" 194 | 195 | def __init__(self, config): 196 | super(BertAttention, self).__init__() 197 | self.self = BertSelfAttention(config) 198 | self.output = BertSelfOutput(config) 199 | 200 | def forward(self, input_tensor, attention_mask, head_mask=None): 201 | self_outputs = self.self(input_tensor, attention_mask, head_mask) 202 | attention_output = self.output(self_outputs[0], input_tensor) 203 | outputs = (attention_output, 204 | ) + self_outputs[1:] # add attentions if we output them 205 | return outputs 206 | 207 | 208 | class BertIntermediate(nn.Module): 209 | """Fully-connected layer, part 1.""" 210 | 211 | def __init__(self, config): 212 | super(BertIntermediate, self).__init__() 213 | self.dense = nn.Linear(config.hidden_size, config.intermediate_size) 214 | self.intermediate_act_fn = ACT2FN[config.hidden_act] 215 | # self.intermediate_act_fn = config.hidden_act 216 | 217 | def forward(self, hidden_states): 218 | hidden_states = self.dense(hidden_states) 219 | hidden_states = self.intermediate_act_fn(hidden_states) 220 | return hidden_states 221 | 222 | 223 | class BertOutput(nn.Module): 224 | """Fully-connected layer, part 2.""" 225 | 226 | def __init__(self, config): 227 | super(BertOutput, self).__init__() 228 | self.dense = nn.Linear(config.intermediate_size, config.hidden_size) 229 | self.layer_norm = BertLayerNorm(config.hidden_size, 230 | eps=config.layer_norm_eps) 231 | self.dropout = nn.Dropout(config.hidden_dropout_prob) 232 | 233 | def forward(self, hidden_states, input_tensor): 234 | hidden_states = self.dense(hidden_states) 235 | hidden_states = self.dropout(hidden_states) 236 | hidden_states = self.layer_norm(hidden_states + input_tensor) 237 | return hidden_states 238 | 239 | 240 | class BertLayer(nn.Module): 241 | """Complete Bert layer.""" 242 | 243 | def __init__(self, config): 244 | super(BertLayer, self).__init__() 245 | self.attention = BertAttention(config) 246 | self.intermediate = BertIntermediate(config) 247 | self.output = BertOutput(config) 248 | 249 | def forward(self, hidden_states, attention_mask, head_mask=None): 250 | attention_outputs = self.attention(hidden_states, attention_mask, head_mask) 251 | attention_output = attention_outputs[0] 252 | intermediate_output = self.intermediate(attention_output) 253 | layer_output = self.output(intermediate_output, attention_output) 254 | outputs = (layer_output, 255 | ) + attention_outputs[1:] # add attentions if we output them 256 | return outputs 257 | 258 | 259 | class BertEncoder(nn.Module): 260 | """Complete Bert Model (Transformer encoder).""" 261 | 262 | def __init__(self, config): 263 | super(BertEncoder, self).__init__() 264 | self.output_attentions = False 265 | self.output_hidden_states = False 266 | self.layer = nn.ModuleList( 267 | [BertLayer(config) for _ in range(config.num_hidden_layers)]) 268 | 269 | def forward(self, hidden_states, attention_mask, head_mask=None): 270 | all_hidden_states = () 271 | all_attentions = () 272 | for i, layer_module in enumerate(self.layer): 273 | if self.output_hidden_states: 274 | all_hidden_states = all_hidden_states + (hidden_states,) 275 | 276 | layer_outputs = layer_module(hidden_states, attention_mask, head_mask[i]) 277 | hidden_states = layer_outputs[0] 278 | 279 | if self.output_attentions: 280 | all_attentions = all_attentions + (layer_outputs[1],) 281 | 282 | # Add last layer 283 | if self.output_hidden_states: 284 | all_hidden_states = all_hidden_states + (hidden_states,) 285 | 286 | outputs = (hidden_states,) 287 | if self.output_hidden_states: 288 | outputs = outputs + (all_hidden_states,) 289 | if self.output_attentions: 290 | outputs = outputs + (all_attentions,) 291 | # last-layer hidden state, (all hidden states), (all attentions) 292 | return outputs 293 | 294 | 295 | class BertPooler(nn.Module): 296 | """Extraction of a single output embedding.""" 297 | 298 | def __init__(self, config): 299 | super(BertPooler, self).__init__() 300 | self.dense = nn.Linear(config.hidden_size, config.hidden_size) 301 | self.activation = nn.Tanh() 302 | 303 | def forward(self, hidden_states): 304 | # We "pool" the model by simply taking the hidden state corresponding 305 | # to the first token. 306 | first_token_tensor = hidden_states[:, 0] 307 | pooled_output = self.dense(first_token_tensor) 308 | pooled_output = self.activation(pooled_output) 309 | return pooled_output 310 | 311 | 312 | class BertModel(nn.Module): 313 | r"""Bert Model. 314 | 315 | Outputs: `Tuple` comprising various elements depending on the configuration 316 | (config) and inputs: 317 | **last_hidden_state**: ``torch.FloatTensor`` of shape ``(batch_size, 318 | sequence_length, hidden_size)`` 319 | Sequence of hidden-states at the output of the last layer of the 320 | model. 321 | **pooler_output**: ``torch.FloatTensor`` of shape ``(batch_size, 322 | hidden_size)`` 323 | Last layer hidden-state of the first token of the sequence 324 | (classification token) 325 | further processed by a Linear layer and a Tanh activation function. 326 | The Linear 327 | layer weights are trained from the next sentence prediction 328 | (classification) 329 | objective during Bert pretraining. This output is usually *not* a 330 | good summary 331 | of the semantic content of the input, you're often better with 332 | averaging or pooling 333 | the sequence of hidden-states for the whole input sequence. 334 | **hidden_states**: (`optional`, returned when 335 | ``config.output_hidden_states=True``) 336 | list of ``torch.FloatTensor`` (one for the output of each layer + 337 | the output of the embeddings) 338 | of shape ``(batch_size, sequence_length, hidden_size)``: 339 | Hidden-states of the model at the output of each layer plus the 340 | initial embedding outputs. 341 | **attentions**: (`optional`, returned when 342 | ``config.output_attentions=True``) 343 | list of ``torch.FloatTensor`` (one for each layer) of shape 344 | ``(batch_size, num_heads, sequence_length, sequence_length)``: 345 | Attentions weights after the attention softmax, used to compute the 346 | weighted average in the self-attention heads. 347 | """ 348 | 349 | def __init__(self, config): 350 | super(BertModel, self).__init__() 351 | 352 | self.config = config 353 | 354 | self.embeddings = BertEmbeddings(config) 355 | self.encoder = BertEncoder(config) 356 | self.pooler = BertPooler(config) 357 | 358 | # Weights initialization 359 | self.apply(self._init_weights) 360 | 361 | def _init_weights(self, module): 362 | """Initialize the weights.""" 363 | if isinstance(module, (nn.Linear, nn.Embedding)): 364 | module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) 365 | elif isinstance(module, BertLayerNorm): 366 | module.bias.data.zero_() 367 | module.weight.data.fill_(1.0) 368 | if isinstance(module, nn.Linear) and module.bias is not None: 369 | module.bias.data.zero_() 370 | 371 | def forward(self, 372 | input_ids, 373 | attention_mask=None, 374 | token_type_ids=None, 375 | position_ids=None, 376 | features=None): 377 | if attention_mask is None: 378 | attention_mask = torch.ones_like(input_ids) 379 | if token_type_ids is None: 380 | token_type_ids = torch.zeros_like(input_ids) 381 | 382 | # We create a 3D attention mask from a 2D tensor mask. 383 | # Sizes are [batch_size, 1, 1, to_seq_length] 384 | # So we can broadcast to 385 | # [batch_size, num_heads, from_seq_length, to_seq_length] 386 | extended_attention_mask = attention_mask.unsqueeze(1).unsqueeze(2) 387 | 388 | # Since attention_mask is 1.0 for positions we want to attend and 0.0 for 389 | # masked positions, this operation will create a tensor which is 0.0 for 390 | # positions we want to attend and -10000.0 for masked positions. 391 | # Since we are adding it to the raw scores before the softmax, this is 392 | # effectively the same as removing these entirely. 393 | extended_attention_mask = extended_attention_mask.to( 394 | dtype=next(self.parameters()).dtype) # fp16 compatibility 395 | extended_attention_mask = (1.0 - extended_attention_mask) * -10000.0 396 | 397 | head_mask = [None] * self.config.num_hidden_layers 398 | 399 | embedding_output = self.embeddings(input_ids, 400 | position_ids=position_ids, 401 | token_type_ids=token_type_ids, 402 | features=features) 403 | encoder_outputs = self.encoder(embedding_output, 404 | extended_attention_mask, 405 | head_mask=head_mask) 406 | sequence_output = encoder_outputs[0] 407 | pooled_output = self.pooler(sequence_output) 408 | 409 | outputs = ( 410 | sequence_output, 411 | pooled_output, 412 | ) + encoder_outputs[1:] # add hidden_states and attentions if they are here 413 | # sequence_output, pooled_output, (hidden_states), (attentions) 414 | return outputs 415 | -------------------------------------------------------------------------------- /models/pt_utils.py: -------------------------------------------------------------------------------- 1 | import torch.nn as nn 2 | 3 | class IdLayer(nn.Module): 4 | def forward(self, x): 5 | return x 6 | -------------------------------------------------------------------------------- /models/vggish_model.py: -------------------------------------------------------------------------------- 1 | import os 2 | import numpy as np 3 | 4 | 5 | import tensorflow.compat.v1 as tf 6 | import vggish.vggish_input as vggish_input 7 | import vggish.vggish_params as vggish_params 8 | import vggish.vggish_postprocess as vggish_postprocess 9 | import vggish.vggish_slim as vggish_slim 10 | 11 | class VGGish: 12 | def __init__(self, ckpt_path, per_batch_size): 13 | os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2' 14 | self.per_batch_size = per_batch_size 15 | # sys.path.append('/home/wx762845/src/models-master/research/audioset/vggish/') # TODO 16 | 17 | config = tf.ConfigProto() 18 | config.gpu_options.per_process_gpu_memory_fraction = 0.2 19 | self.manager=tf.Graph().as_default() 20 | self.manager.__enter__() 21 | self.sess = tf.Session(config = config) 22 | 23 | vggish_slim.define_vggish_slim(training=False) 24 | vggish_slim.load_vggish_slim_checkpoint(self.sess, ckpt_path) # /home/wx762845/src/models-master/research/audioset/vggish/vggish_model.ckpt 25 | self.features_tensor = self.sess.graph.get_tensor_by_name( 26 | vggish_params.INPUT_TENSOR_NAME) 27 | self.embedding_tensor = self.sess.graph.get_tensor_by_name( 28 | vggish_params.OUTPUT_TENSOR_NAME) 29 | 30 | def __call__(self, frames): 31 | mel_features = np.stack(frames) 32 | 33 | [outputs] = self.sess.run([self.embedding_tensor], 34 | feed_dict={self.features_tensor: mel_features}) 35 | relu = lambda x: np.maximum(x, 0) 36 | embs = relu(outputs) 37 | 38 | return embs 39 | -------------------------------------------------------------------------------- /models/vmz/__init__.py: -------------------------------------------------------------------------------- 1 | from .csn import * 2 | from .r2plus1d import * 3 | -------------------------------------------------------------------------------- /models/vmz/csn.py: -------------------------------------------------------------------------------- 1 | import warnings 2 | 3 | import torch.hub 4 | import torch.nn as nn 5 | from torchvision.models.video.resnet import BasicStem, BasicBlock, Bottleneck 6 | 7 | from .utils import _generic_resnet, Conv3DDepthwise, BasicStem_Pool, IPConv3DDepthwise 8 | 9 | 10 | __all__ = ["ir_csn_152", "ip_csn_152"] 11 | 12 | 13 | def ir_csn_152(use_pool1=True, **kwargs): 14 | model = _generic_resnet( 15 | block=Bottleneck, 16 | conv_makers=[Conv3DDepthwise] * 4, 17 | layers=[3, 8, 36, 3], 18 | stem=BasicStem_Pool if use_pool1 else BasicStem, 19 | **kwargs) 20 | return model 21 | 22 | 23 | def ip_csn_152(use_pool1=True, **kwargs): 24 | model = _generic_resnet( 25 | block=Bottleneck, 26 | conv_makers=[IPConv3DDepthwise] * 4, 27 | layers=[3, 8, 36, 3], 28 | stem=BasicStem_Pool if use_pool1 else BasicStem, 29 | **kwargs) 30 | return model 31 | -------------------------------------------------------------------------------- /models/vmz/r2plus1d.py: -------------------------------------------------------------------------------- 1 | import torch.hub 2 | import torch.nn as nn 3 | from torchvision.models.video.resnet import R2Plus1dStem, BasicBlock, Bottleneck 4 | 5 | 6 | from .utils import _generic_resnet, R2Plus1dStem_Pool, Conv2Plus1D 7 | 8 | 9 | __all__ = ["r2plus1d_34", "r2plus1d_152"] 10 | 11 | 12 | def r2plus1d_34(use_pool1=False, **kwargs): 13 | model = _generic_resnet( 14 | block=BasicBlock, 15 | conv_makers=[Conv2Plus1D] * 4, 16 | layers=[3, 4, 6, 3], 17 | stem=R2Plus1dStem_Pool if use_pool1 else R2Plus1dStem, 18 | **kwargs, 19 | ) 20 | # We need exact Caffe2 momentum for BatchNorm scaling 21 | for m in model.modules(): 22 | if isinstance(m, nn.BatchNorm3d): 23 | m.eps = 1e-3 24 | m.momentum = 0.9 25 | 26 | return model 27 | 28 | 29 | def r2plus1d_152(use_pool1=True, **kwargs): 30 | model = _generic_resnet( 31 | block=Bottleneck, 32 | conv_makers=[Conv2Plus1D] * 4, 33 | layers=[3, 8, 36, 3], 34 | stem=R2Plus1dStem_Pool if use_pool1 else R2Plus1dStem, 35 | **kwargs, 36 | ) 37 | # We need exact Caffe2 momentum for BatchNorm scaling 38 | for m in model.modules(): 39 | if isinstance(m, nn.BatchNorm3d): 40 | m.eps = 1e-3 41 | m.momentum = 0.9 42 | 43 | return model 44 | -------------------------------------------------------------------------------- /models/vmz/utils.py: -------------------------------------------------------------------------------- 1 | import torch 2 | import torch.nn as nn 3 | from torchvision.models.video.resnet import VideoResNet 4 | 5 | 6 | def _generic_resnet(**kwargs): 7 | model = VideoResNet(**kwargs) 8 | 9 | # We need exact Caffe2 momentum for BatchNorm scaling 10 | for m in model.modules(): 11 | if isinstance(m, nn.BatchNorm3d): 12 | m.eps = 1e-3 13 | m.momentum = 0.9 14 | 15 | return model 16 | 17 | 18 | class BasicStem_Pool(nn.Sequential): 19 | def __init__(self): 20 | super(BasicStem_Pool, self).__init__( 21 | nn.Conv3d( 22 | 3, 23 | 64, 24 | kernel_size=(3, 7, 7), 25 | stride=(1, 2, 2), 26 | padding=(1, 3, 3), 27 | bias=False, 28 | ), 29 | nn.BatchNorm3d(64), 30 | nn.ReLU(inplace=True), 31 | nn.MaxPool3d(kernel_size=(1, 3, 3), stride=(1, 2, 2), padding=(0, 1, 1)), 32 | ) 33 | 34 | 35 | class R2Plus1dStem_Pool(nn.Sequential): 36 | """R(2+1)D stem is different than the default one as it uses separated 3D convolution 37 | """ 38 | 39 | def __init__(self): 40 | super(R2Plus1dStem_Pool, self).__init__( 41 | nn.Conv3d( 42 | 3, 43 | 45, 44 | kernel_size=(1, 7, 7), 45 | stride=(1, 2, 2), 46 | padding=(0, 3, 3), 47 | bias=False, 48 | ), 49 | nn.BatchNorm3d(45), 50 | nn.ReLU(inplace=True), 51 | nn.Conv3d( 52 | 45, 53 | 64, 54 | kernel_size=(3, 1, 1), 55 | stride=(1, 1, 1), 56 | padding=(1, 0, 0), 57 | bias=False, 58 | ), 59 | nn.BatchNorm3d(64), 60 | nn.ReLU(inplace=True), 61 | nn.MaxPool3d(kernel_size=(1, 3, 3), stride=(1, 2, 2), padding=(0, 1, 1)), 62 | ) 63 | 64 | 65 | class Conv3DDepthwise(nn.Conv3d): 66 | def __init__(self, in_planes, out_planes, midplanes=None, stride=1, padding=1): 67 | 68 | assert in_planes == out_planes 69 | super(Conv3DDepthwise, self).__init__( 70 | in_channels=in_planes, 71 | out_channels=out_planes, 72 | kernel_size=(3, 3, 3), 73 | stride=stride, 74 | padding=padding, 75 | groups=in_planes, 76 | bias=False, 77 | ) 78 | 79 | @staticmethod 80 | def get_downsample_stride(stride): 81 | return (stride, stride, stride) 82 | 83 | 84 | class IPConv3DDepthwise(nn.Sequential): 85 | def __init__(self, in_planes, out_planes, midplanes, stride=1, padding=1): 86 | 87 | assert in_planes == out_planes 88 | super(IPConv3DDepthwise, self).__init__( 89 | nn.Conv3d(in_planes, out_planes, kernel_size=1, bias=False), 90 | nn.BatchNorm3d(out_planes), 91 | # nn.ReLU(inplace=True), 92 | Conv3DDepthwise(out_planes, out_planes, None, stride), 93 | ) 94 | 95 | @staticmethod 96 | def get_downsample_stride(stride): 97 | return (stride, stride, stride) 98 | 99 | 100 | class Conv2Plus1D(nn.Sequential): 101 | def __init__(self, in_planes, out_planes, midplanes, stride=1, padding=1): 102 | 103 | midplanes = (in_planes * out_planes * 3 * 3 * 3) // ( 104 | in_planes * 3 * 3 + 3 * out_planes 105 | ) 106 | super(Conv2Plus1D, self).__init__( 107 | nn.Conv3d( 108 | in_planes, 109 | midplanes, 110 | kernel_size=(1, 3, 3), 111 | stride=(1, stride, stride), 112 | padding=(0, padding, padding), 113 | bias=False, 114 | ), 115 | nn.BatchNorm3d(midplanes), 116 | nn.ReLU(inplace=True), 117 | nn.Conv3d( 118 | midplanes, 119 | out_planes, 120 | kernel_size=(3, 1, 1), 121 | stride=(stride, 1, 1), 122 | padding=(padding, 0, 0), 123 | bias=False, 124 | ), 125 | ) 126 | 127 | @staticmethod 128 | def get_downsample_stride(stride): 129 | return (stride, stride, stride) 130 | -------------------------------------------------------------------------------- /models/vmz_model.py: -------------------------------------------------------------------------------- 1 | import torch 2 | import numpy as np 3 | 4 | 5 | from models.pt_utils import IdLayer 6 | from models.vmz.r2plus1d import r2plus1d_152, r2plus1d_34 7 | from models.vmz.csn import ip_csn_152, ir_csn_152 8 | 9 | 10 | class VMZ_base: 11 | def __init__(self, ckpt_path, model_cls): 12 | with torch.no_grad(): 13 | self.model = model = model_cls() 14 | model.fc = IdLayer() 15 | model.eval() 16 | state_dict = torch.load(ckpt_path) 17 | del state_dict['fc.weight'] 18 | del state_dict['fc.bias'] 19 | model.load_state_dict(state_dict) 20 | model.cuda() 21 | self.mean = torch.tensor([0.43216, 0.394666, 0.37645])[None,:,None,None,None].cuda() 22 | self.std = torch.tensor([0.22803, 0.22145, 0.216989])[None,:,None,None,None].cuda() 23 | @torch.no_grad() 24 | def __call__(self, batch_imgs): 25 | # (bs, t, h, w, c) each pixel in [0,255] 26 | imgs = torch.from_numpy(batch_imgs.astype(np.float32)).cuda() 27 | imgs.div_(255.) 28 | imgs = imgs.permute(0, 4, 1, 2, 3) 29 | imgs = (imgs - self.mean) / self.std 30 | embs = self.model(imgs) 31 | embs = embs.cpu().numpy() 32 | return embs 33 | 34 | class VMZ_r2plus1d_152(VMZ_base): 35 | def __init__(self, ckpt_path): 36 | super().__init__(ckpt_path, r2plus1d_152) 37 | 38 | class VMZ_r2plus1d_34(VMZ_base): 39 | def __init__(self, ckpt_path): 40 | super().__init__(ckpt_path, r2plus1d_34) 41 | 42 | class VMZ_ipCSN_152(VMZ_base): 43 | def __init__(self, ckpt_path): 44 | super().__init__(ckpt_path, ip_csn_152) 45 | 46 | class VMZ_irCSN_152(VMZ_base): 47 | def __init__(self, ckpt_path): 48 | super().__init__(ckpt_path, ir_csn_152) 49 | 50 | 51 | -------------------------------------------------------------------------------- /mp_utils.py: -------------------------------------------------------------------------------- 1 | import os 2 | import multiprocessing as mp 3 | import time 4 | import queue 5 | import threading 6 | 7 | #from linux_utils import init_rt_stacktrace 8 | #init_rt_stacktrace() 9 | 10 | 11 | class EntryPoint: 12 | def __init__(self): 13 | self.q = mp.Queue() 14 | def __next__(self): 15 | return self.q.get() 16 | def put(self, x): 17 | self.q.put(x) 18 | def __iter__(self): 19 | return self 20 | 21 | class _MpGen: 22 | def __init__(self, inp_it, maxsize=20, engine='mp'): 23 | self.done_cnt = mp.Value('i', 0) 24 | self.num_sent = mp.Value('i', 0) 25 | self.num_recv = mp.Value('i', 0) 26 | if engine=='mp': 27 | self.q = mp.Queue(maxsize) 28 | self.cv = mp.Condition() 29 | creat_fn = mp.Process 30 | else: 31 | self.q = queue.Queue(maxsize) 32 | self.cv = threading.Condition() 33 | creat_fn = threading.Thread 34 | self.p = creat_fn(target=self.feeder, args=(inp_it,)) 35 | self.p.start() 36 | 37 | def join(self): 38 | self.p.join() 39 | 40 | def __iter__(self): 41 | return self 42 | 43 | def feeder(self, inp_it): 44 | try: 45 | for x in inp_it: 46 | self.q.put(x) 47 | with self.cv: 48 | self.num_sent.value += 1 49 | finally: 50 | with self.cv: 51 | self.cv.wait_for(lambda: self.num_sent.value == self.num_recv.value) 52 | self.done_cnt.value += 1 53 | 54 | def __next__(self): 55 | while True: 56 | try: 57 | res = self.q.get(True, 1) 58 | with self.cv: 59 | self.num_recv.value += 1 60 | self.cv.notify_all() 61 | return res 62 | except queue.Empty: 63 | with self.cv: 64 | if self.num_sent.value == self.num_recv.value and self.done_cnt.value == 1: 65 | raise StopIteration 66 | 67 | 68 | class MpGen: 69 | def __init__(self, inp_it, worker_fn=None, num_workers=1, worker_cls=None, worker_cls_kw={}, streaming_mode=False, maxsize=20, engine='mp'): 70 | self.pid = os.getpid() 71 | if engine == 'mp': 72 | self.q = mp.Queue(maxsize) 73 | else: 74 | self.q = queue.Queue(maxsize) 75 | self.streaming_mode = streaming_mode 76 | self.done_cnt = mp.Value('i', 0) 77 | self.num_sent = mp.Value('i', 0) 78 | self.num_recv = mp.Value('i', 0) 79 | if engine == 'mp': 80 | self.cv = mp.Condition() 81 | else: 82 | self.cv = threading.Condition() 83 | self.num_workers = num_workers 84 | if num_workers > 0: 85 | if type(inp_it) is MpGen or type(inp_it) is _MpGen: 86 | self.inp_it = inp_it 87 | else: 88 | self.inp_it = _MpGen(inp_it, engine=engine) 89 | 90 | self.procs = [] 91 | for widx in range(num_workers): 92 | if engine == 'mp': 93 | creat_fn = mp.Process 94 | else: 95 | creat_fn = threading.Thread 96 | p = creat_fn(target=self.worker, args=(widx, self.q, worker_fn, worker_cls, worker_cls_kw)) 97 | p.start() 98 | self.procs.append(p) 99 | else: 100 | self.inp_it = inp_it 101 | if worker_cls is not None: 102 | self.worker_fn = worker_cls(rank=0, **worker_cls_kw) 103 | else: 104 | self.worker_fn = worker_fn 105 | def _input_it(): 106 | if self.streaming_mode: 107 | for x in self.worker_fn(self.inp_it, rank=0) or []: 108 | yield x 109 | else: 110 | for x in self.inp_it: 111 | for y in self.worker_fn(x): 112 | yield y 113 | self.input_it = _input_it() 114 | 115 | 116 | 117 | def join(self): 118 | for p in self.procs: 119 | p.join() 120 | self.inp_it.join() 121 | 122 | def worker(self, worker_idx, q, worker_fn=None, worker_cls=None, worker_cls_kw={}): 123 | if worker_cls is not None: 124 | worker_fn = worker_cls(rank=worker_idx, **worker_cls_kw) 125 | try: 126 | if self.streaming_mode: 127 | for x in worker_fn(self.inp_it, rank=worker_idx) or []: 128 | self.q.put(x) 129 | with self.cv: 130 | self.num_sent.value += 1 131 | else: 132 | for data in self.inp_it: 133 | res = worker_fn(data) 134 | for x in res or []: 135 | self.q.put(x) 136 | with self.cv: 137 | self.num_sent.value += 1 138 | finally: 139 | with self.cv: 140 | self.cv.wait_for(lambda: self.num_sent.value == self.num_recv.value) 141 | self.done_cnt.value += 1 142 | 143 | def __next__(self): 144 | if self.num_workers > 0: 145 | while True: 146 | try: 147 | res = self.q.get(True, 1) 148 | with self.cv: 149 | self.num_recv.value += 1 150 | self.cv.notify_all() 151 | return res 152 | except queue.Empty: 153 | with self.cv: 154 | if self.num_sent.value == self.num_recv.value and self.done_cnt.value == self.num_workers: 155 | if self.pid == os.getpid(): 156 | self.join() 157 | raise StopIteration 158 | else: 159 | return next(self.input_it) 160 | 161 | 162 | 163 | def __iter__(self): 164 | return self 165 | 166 | 167 | if __name__ == "__main__": 168 | def delay(fn): 169 | def _fn(*args, **kwargs): 170 | import random 171 | t = random.uniform(0,1) 172 | time.sleep(t) 173 | return fn(*args, **kwargs) 174 | return _fn 175 | 176 | def stream(iterable, rank): 177 | for x in iterable: 178 | yield x 179 | 180 | def counter(iterable, rank): 181 | for x in iterable: 182 | if x == 1: 183 | raise Exception 184 | print(x) 185 | return [] 186 | 187 | g0 = range(10) 188 | g1 = MpGen(g0, delay(lambda x: [x*x]), num_workers=0) 189 | g2 = MpGen(g1, delay(lambda x: [x+1]), num_workers=0) 190 | g3 = MpGen(g2, stream, streaming_mode=True, num_workers=0) 191 | for x in g3: 192 | print(x) 193 | print('PASS') 194 | 195 | g0 = range(10) 196 | g1 = MpGen(g0, delay(lambda x: [x*x]), num_workers=3) 197 | g2 = MpGen(g1, delay(lambda x: [x+1]), num_workers=2) 198 | g3 = MpGen(g2, stream, streaming_mode=True, num_workers=2) 199 | g4 = MpGen(g3, counter, streaming_mode=True, num_workers=2) 200 | for x in g4: 201 | print(x) 202 | print('PASS') 203 | -------------------------------------------------------------------------------- /test.py: -------------------------------------------------------------------------------- 1 | import argparse 2 | import os 3 | 4 | import torch 5 | 6 | from models.mmt import BertTXT, BertVID 7 | from validate import validate 8 | from data_loader.msrvtt_dataset import MSRVTT 9 | from data_loader.activitynet_dataset import ActivityNet 10 | from data_loader.lsmdc_dataset import LSMDC 11 | 12 | 13 | def main(): 14 | parser = argparse.ArgumentParser() 15 | parser.add_argument('--checkpoint', required=True) 16 | parser.add_argument('--dataset_root', required=True) 17 | parser.add_argument('--dataset_name', required=True, choices=[ 18 | 'MSRVTT_1kA', 19 | 'MSRVTT_1kB', 20 | 'MSRVTT_full', 21 | 'lsmdc_publictest', 22 | 'ActivityNet']) 23 | parser.add_argument('--gpu', default=0, type=int) 24 | parser.add_argument('--video_batch_size', type=int, default=32) 25 | parser.add_argument('--text_batch_size', type=int, default=32) 26 | args = parser.parse_args() 27 | 28 | os.environ['CUDA_VISIBLE_DEVICES'] = f'{args.gpu}' 29 | 30 | state = torch.load(args.checkpoint, map_location='cpu') 31 | 32 | print('Loading video model ...') 33 | experts_info = { 34 | 'VIDEO': dict(dim=2048, idx=1, max_tok=30), 35 | 'CLIP': dict(dim=512, idx=2, max_tok=30), 36 | 'tf_vggish': dict(dim=128, idx=3, max_tok=30), 37 | } 38 | vid_bert_params = { 39 | 'vocab_size_or_config_json_file': 10, 40 | 'hidden_size': 512, 41 | 'num_hidden_layers': 9, 42 | 'intermediate_size': 3072, 43 | 'hidden_act': 'gelu', 44 | 'hidden_dropout_prob': 0.2, 45 | 'attention_probs_dropout_prob': 0.2, 46 | 'max_position_embeddings': 32, 47 | 'type_vocab_size': 19, 48 | 'initializer_range': 0.02, 49 | 'layer_norm_eps': 1e-12, 50 | 'num_attention_heads': 8, 51 | } 52 | model_vid = BertVID(expert_dims=experts_info, vid_bert_params=vid_bert_params) 53 | model_vid = model_vid.eval() 54 | model_vid.load_state_dict(state['vid_state_dict']) 55 | model_vid = model_vid.cuda() 56 | print('done') 57 | 58 | print('Loading text model ...') 59 | txt_bert_params = { 60 | 'hidden_dropout_prob': 0.2, 61 | 'attention_probs_dropout_prob': 0.2, 62 | } 63 | model_txt = BertTXT( 64 | modalities=list(experts_info.keys()), 65 | add_special_tokens=True, 66 | txt_bert_params=txt_bert_params, 67 | ) 68 | model_txt = model_txt.eval() 69 | model_txt.load_state_dict(state['txt_state_dict']) 70 | model_txt = model_txt.cuda() 71 | print('done') 72 | 73 | 74 | print('Loading dataset ...') 75 | dataset_name = args.dataset_name 76 | if dataset_name == 'MSRVTT_full': 77 | dataset = MSRVTT( 78 | cut_name="full", 79 | split_name="test", 80 | data_dir=args.dataset_root, 81 | experts_info=experts_info, 82 | training=False) 83 | elif dataset_name == 'lsmdc_publictest': 84 | dataset = LSMDC( 85 | cut_name="mrc", 86 | split_name="test", 87 | data_dir=args.dataset_root, 88 | experts_info=experts_info, 89 | training=False) 90 | elif dataset_name == 'ActivityNet': 91 | dataset = ActivityNet( 92 | cut_name="mrc", 93 | split_name="val", 94 | data_dir=args.dataset_root, 95 | experts_info=experts_info, 96 | training=False) 97 | else: 98 | raise NotImplementedError(dataset_name) 99 | 100 | print('done') 101 | 102 | 103 | print('Validate ...') 104 | all_topk_t2v, all_topk_v2t = validate( 105 | video_model=model_vid, 106 | text_model=model_txt, 107 | dataset=dataset, 108 | embdim=3*512, 109 | rank=0, 110 | world_size=1, 111 | video_batch_size=args.video_batch_size, 112 | text_batch_size=args.text_batch_size, 113 | with_v2t=True) 114 | print('done') 115 | 116 | metrics = {} 117 | metrics["t2v/R1"] = 100 * float((all_topk_t2v==0).sum()) / len(all_topk_t2v) 118 | metrics["t2v/R5"] = 100 * float((all_topk_t2v < 5).sum()) / len(all_topk_t2v) 119 | metrics["t2v/R10"] = 100 * float((all_topk_t2v < 10).sum()) / len(all_topk_t2v) 120 | metrics["t2v/R50"] = 100 * float((all_topk_t2v < 50).sum()) / len(all_topk_t2v) 121 | metrics["t2v/MedR"] = all_topk_t2v.median().item() + 1 122 | metrics["t2v/MeanR"] = all_topk_t2v.mean().item() + 1 123 | metrics["v2t/R1"] = 100 * float((all_topk_v2t==0).sum()) / len(all_topk_v2t) 124 | metrics["v2t/R5"] = 100 * float((all_topk_v2t < 5).sum()) / len(all_topk_v2t) 125 | metrics["v2t/R10"] = 100 * float((all_topk_v2t < 10).sum()) / len(all_topk_v2t) 126 | metrics["v2t/R50"] = 100 * float((all_topk_v2t < 50).sum()) / len(all_topk_v2t) 127 | metrics["v2t/MedR"] = all_topk_v2t.median().item() + 1 128 | metrics["v2t/MeanR"] = all_topk_v2t.mean().item() + 1 129 | for key, val in metrics.items(): 130 | print(f'{key}: {val}') 131 | 132 | 133 | 134 | if __name__ == "__main__": 135 | main() 136 | 137 | 138 | 139 | -------------------------------------------------------------------------------- /validate.py: -------------------------------------------------------------------------------- 1 | from collections import OrderedDict, defaultdict 2 | from torch.utils.data import Dataset 3 | 4 | import torch 5 | import torch.distributed as dist 6 | import numpy as np 7 | 8 | 9 | def move_dict_to_device(res, device, only_tensors=True): 10 | """Move a dictionnary to another device memory.""" 11 | for key in list(res.keys()): 12 | value = res[key] 13 | if isinstance(value, np.ndarray): 14 | res[key] = torch.from_numpy(res[key]) 15 | if device is not None: 16 | res[key] = res[key].to(device) 17 | elif isinstance(value, torch.Tensor): 18 | if device is not None: 19 | res[key] = value.to(device) 20 | elif isinstance(value, collections.OrderedDict) or isinstance(value, dict): 21 | res[key] = move_dict_to_device(res[key], device) 22 | else: 23 | if only_tensors: 24 | res.pop(key) 25 | return res 26 | 27 | class DummySampler(torch.utils.data.Sampler): 28 | def __init__(self, data): 29 | self.data = data 30 | 31 | def __len__(self): 32 | return len(self.data) 33 | 34 | def __iter__(self): 35 | return iter(self.data) 36 | 37 | class DatasetWrapper(Dataset): 38 | def __init__(self, dataset): 39 | self.dataset = dataset 40 | 41 | def __getitem__(self, key): 42 | item_idx, cap_idx = key 43 | return self.dataset.__getitem__(item_idx, cap_idx) 44 | 45 | def _batchify(batch_size, iterable): 46 | items = [] 47 | for item in iterable: 48 | items.append(item) 49 | if len(items) == batch_size: 50 | yield items 51 | items = [] 52 | if len(items) > 0: 53 | yield items 54 | 55 | def batchify(batch_size, *iterables): 56 | b_iterables = [_batchify(batch_size, it) for it in iterables] 57 | while True: 58 | try: 59 | yield tuple([next(b_it) for b_it in b_iterables]) 60 | except StopIteration: 61 | return 62 | 63 | @torch.no_grad() 64 | def validate(video_model, text_model, dataset, embdim, rank, world_size, video_batch_size, text_batch_size, with_v2t=True): 65 | device = torch.device('cuda') 66 | vidxs = list(range(rank, len(dataset), world_size)) 67 | 68 | seed = 42 69 | captions = dataset.get_val_captions(seed=seed) # [(vid, capidx, text, t0, t1), ...] 70 | 71 | # capsegmidx --> (temb_idx, vemb_idx) 72 | 73 | capsegmidx_2_embidxs = {} 74 | temb_idx_cnt = 0 75 | vemb_idx_cnt = 0 76 | text_2_idx = OrderedDict() 77 | segm_2_idx = OrderedDict() 78 | segm_2_vidcap0 = {} 79 | cap_2_capsegmidx = {} 80 | for capsegmidx, (vid, capidx, cap, t0, t1) in enumerate(captions): 81 | if cap not in cap_2_capsegmidx: 82 | cap_2_capsegmidx[cap] = [capsegmidx] 83 | else: 84 | cap_2_capsegmidx[cap].append(capsegmidx) 85 | if cap in text_2_idx: 86 | temb_idx = text_2_idx[cap] 87 | else: 88 | temb_idx = temb_idx_cnt 89 | temb_idx_cnt += 1 90 | text_2_idx[cap] = temb_idx 91 | 92 | segm = (vid, t0, t1) 93 | if segm in segm_2_idx: 94 | vemb_idx = segm_2_idx[segm] 95 | else: 96 | vemb_idx = vemb_idx_cnt 97 | vemb_idx_cnt += 1 98 | segm_2_idx[segm] = vemb_idx 99 | segm_2_vidcap0[segm] = (vid, capidx) 100 | capsegmidx_2_embidxs[capsegmidx] = (temb_idx, vemb_idx) 101 | #from remote_pdb import set_trace; set_trace() 102 | # dumps texts 103 | texts = list(text_2_idx.keys()) 104 | embs_txt = torch.zeros(len(texts), embdim).cuda() 105 | local_text_idxs = range(rank, len(texts), world_size) 106 | local_texts = [texts[idx] for idx in local_text_idxs] 107 | for batch_texts, batch_idxs in batchify(text_batch_size, local_texts, local_text_idxs): 108 | embs = text_model(batch_texts) 109 | embs_txt[batch_idxs] = embs 110 | if world_size > 1: 111 | dist.all_reduce(embs_txt) 112 | 113 | #dump video segments 114 | segms = list(segm_2_idx.keys()) 115 | embs_vid = torch.zeros(len(segms), embdim).cuda() 116 | local_segm_idxs = range(rank, len(segms), world_size) 117 | local_segms = [segms[idx] for idx in local_segm_idxs] 118 | # now we gonna convert local_segms to pairs (idx, capidx) 119 | vid_2_itemidx = {vid: itemidx for itemidx, vid in enumerate(dataset.vid_list)} 120 | access_keys = [] 121 | for segm in local_segms: 122 | vid, capidx = segm_2_vidcap0[segm] 123 | itemidx = vid_2_itemidx[vid] 124 | access_keys.append((itemidx, capidx)) 125 | embs_vid = torch.zeros(len(segms), embdim).cuda() 126 | 127 | loader = torch.utils.data.DataLoader( 128 | dataset=DatasetWrapper(dataset), 129 | batch_size=video_batch_size, 130 | sampler=DummySampler(access_keys), 131 | num_workers=0, 132 | collate_fn=getattr(dataset, 'collate_fn', None)) 133 | segms_it = iter(local_segms) 134 | for batch in loader: 135 | if len(batch) == 6: 136 | _captions, _captions_t, features, features_t, features_mask, features_maxp = batch 137 | elif len(batch) == 5: 138 | _captions, _captions_t, features, features_t, features_mask = batch 139 | features_maxp = None 140 | bs = next(iter(features.values())).size(0) 141 | vidxs = [segm_2_idx[next(segms_it)] for _ in range(bs)] 142 | features = move_dict_to_device(features, device) 143 | features_t = move_dict_to_device(features_t, device) 144 | features_mask = move_dict_to_device(features_mask, device) 145 | if features_maxp is not None: 146 | features_maxp = move_dict_to_device(features_maxp, device) 147 | embs = video_model(features, features_t, features_mask, features_maxp) 148 | embs_vid[vidxs] = embs 149 | if world_size > 1: 150 | dist.all_reduce(embs_vid) 151 | assert not embs_vid.isnan().any() 152 | 153 | all_topk = torch.zeros(len(captions)).cuda() 154 | if with_v2t: 155 | all_topk_v2t = torch.zeros(len(captions)).cuda() 156 | same_segments = defaultdict(list) 157 | for x_idx, (x_vid, _, _, x_t0, x_t1) in enumerate(captions): 158 | temb_idx, vemb_idx = capsegmidx_2_embidxs[x_idx] 159 | same_segments[(x_vid, x_t0, x_t1)].append(temb_idx) 160 | else: 161 | all_topk_v2t = None 162 | for capsegmidx in range(rank, len(captions), world_size): 163 | vid, _capidx, cap, t0, t1 = captions[capsegmidx] 164 | samecap_idxs = cap_2_capsegmidx[cap] # this is capsegmidxs 165 | ign_vid_idxs = [capsegmidx_2_embidxs[scidx][1] for scidx in samecap_idxs] 166 | (temb_idx, vemb_idx) = capsegmidx_2_embidxs[capsegmidx] 167 | temb = embs_txt[temb_idx] 168 | scores = torch.matmul(embs_vid, temb) 169 | score = scores[vemb_idx].clone() 170 | assert vemb_idx in ign_vid_idxs 171 | scores[ign_vid_idxs] = -999 172 | best = scores >= score 173 | all_topk[capsegmidx] = best.sum() # how many segments have same score or higher 174 | 175 | if with_v2t: 176 | vemb = embs_vid[vemb_idx] 177 | scores = torch.matmul(embs_txt, vemb) 178 | ign_idxs = same_segments[(vid, t0, t1)] 179 | scores[ign_idxs] = -999 # ignore other captions which describing this segment 180 | best = scores >= score 181 | all_topk_v2t[capsegmidx] = best.sum() 182 | 183 | if world_size > 1: 184 | dist.all_reduce(all_topk) 185 | if with_v2t: 186 | dist.all_reduce(all_topk_v2t) 187 | dist.barrier() 188 | 189 | return all_topk, all_topk_v2t 190 | 191 | 192 | --------------------------------------------------------------------------------