chenbhao commited on
Commit
a4fb8db
·
1 Parent(s): 9a1a7d2

feat: add interactive mode to eval_vlm.py with auto <image> insertion, update README

Browse files
Files changed (2) hide show
  1. README.md +13 -4
  2. scripts/eval_vlm.py +43 -5
README.md CHANGED
@@ -195,13 +195,17 @@ python scripts/eval_llm.py --load_from checkpoint/lm_full_sft_mini/hf \
195
  # 多模态(VLM / VAM)
196
  # 原生 torch 格式(.pth)
197
  python scripts/eval_vlm.py --native --save_dir checkpoint/vlm_sft_mini \
198
- --weight sft_vlm --hidden_size 768 \
199
- --image_dir dataset/eval_images
 
 
200
 
201
  # VLM HF 格式(需先 convert;注:转换不含 vision encoder,为纯文本 LM)
202
  python scripts/eval_vlm.py --load_from checkpoint/vlm_sft_mini/hf \
203
- --tokenizer_path checkpoint/omni/native_hf \
204
- --image_dir dataset/eval_images
 
 
205
 
206
  python scripts/eval_vam.py --save_dir checkpoint/vam --weight full_sft
207
  ```
@@ -219,6 +223,11 @@ python scripts/convert_model.py checkpoint/vlm_sft_mini/sft_vlm_768.pth \
219
  checkpoint/vlm_sft_mini/hf \
220
  --tokenizer_path checkpoint/omni/native_hf
221
 
 
 
 
 
 
222
  # 从 .pth 转换到指定目录
223
  python scripts/convert_model.py checkpoint/omni/omni.pth checkpoint/omni/native_hf \
224
  --tokenizer_path <训练所用的 tokenizer 目录>
 
195
  # 多模态(VLM / VAM)
196
  # 原生 torch 格式(.pth)
197
  python scripts/eval_vlm.py --native --save_dir checkpoint/vlm_sft_mini \
198
+ --weight sft_vlm --hidden_size 768
199
+
200
+ python scripts/eval_vlm.py --native --save_dir checkpoint/omni-v \
201
+ --weight omni-v --hidden_size 768
202
 
203
  # VLM HF 格式(需先 convert;注:转换不含 vision encoder,为纯文本 LM)
204
  python scripts/eval_vlm.py --load_from checkpoint/vlm_sft_mini/hf \
205
+ --tokenizer_path checkpoint/omni/native_hf
206
+
207
+ python scripts/eval_vlm.py --load_from checkpoint/omni-v/hf \
208
+ --tokenizer_path checkpoint/omni/native_hf
209
 
210
  python scripts/eval_vam.py --save_dir checkpoint/vam --weight full_sft
211
  ```
 
223
  checkpoint/vlm_sft_mini/hf \
224
  --tokenizer_path checkpoint/omni/native_hf
225
 
226
+ # VLM Pretrain
227
+ python scripts/convert_model.py checkpoint/omni-v/omni-v.pth \
228
+ checkpoint/omni-v/hf \
229
+ --tokenizer_path checkpoint/omni/native_hf
230
+
231
  # 从 .pth 转换到指定目录
232
  python scripts/convert_model.py checkpoint/omni/omni.pth checkpoint/omni/native_hf \
233
  --tokenizer_path <训练所用的 tokenizer 目录>
scripts/eval_vlm.py CHANGED
@@ -13,8 +13,10 @@ warnings.filterwarnings('ignore')
13
  def init_model(args):
14
  tokenizer = AutoTokenizer.from_pretrained(args.tokenizer_path, trust_remote_code=True)
15
  if args.native:
16
- moe_suffix = '_moe' if args.use_moe else ''
17
- ckp = f'{args.save_dir}/{args.weight}_{args.hidden_size}{moe_suffix}.pth'
 
 
18
  state = torch.load(ckp, map_location=args.device)
19
  n_layers = max(int(k.split('.')[2]) for k in state if k.startswith('model.layers.')) + 1
20
  model = VLM(
@@ -55,9 +57,13 @@ def main():
55
 
56
  model, tokenizer, preprocess = init_model(args)
57
  streamer = TextStreamer(tokenizer, skip_prompt=True, skip_special_tokens=True)
58
- prompt = "<image>\n请描述这张图中的主要物体和场景。"
59
- for image_file in sorted(os.listdir(args.image_dir)):
60
- if image_file.lower().endswith(('.png', '.jpg', '.jpeg', '.bmp')):
 
 
 
 
61
  setup_seed(random.randint(1, 31415926))
62
  image_path = os.path.join(args.image_dir, image_file)
63
  image = Image.open(image_path).convert('RGB')
@@ -79,6 +85,38 @@ def main():
79
  )
80
  gen_tokens = len(generated_ids[0]) - len(inputs["input_ids"][0])
81
  print(f'\n[Speed]: {gen_tokens / (time.time() - st):.2f} tokens/s\n\n') if args.show_speed else print('\n\n')
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
82
 
83
  if __name__ == "__main__":
84
  main()
 
13
  def init_model(args):
14
  tokenizer = AutoTokenizer.from_pretrained(args.tokenizer_path, trust_remote_code=True)
15
  if args.native:
16
+ ckp = f'{args.save_dir}/{args.weight}.pth'
17
+ if not os.path.exists(ckp):
18
+ moe_suffix = '_moe' if args.use_moe else ''
19
+ ckp = f'{args.save_dir}/{args.weight}_{args.hidden_size}{moe_suffix}.pth'
20
  state = torch.load(ckp, map_location=args.device)
21
  n_layers = max(int(k.split('.')[2]) for k in state if k.startswith('model.layers.')) + 1
22
  model = VLM(
 
57
 
58
  model, tokenizer, preprocess = init_model(args)
59
  streamer = TextStreamer(tokenizer, skip_prompt=True, skip_special_tokens=True)
60
+
61
+ mode = input('[0] 自动测试目录图片\n[1] 手动输入(图片路径 + 文本)\n')
62
+ if mode == '0':
63
+ prompt = "<image>\n请描述这张图中的主要物体和场景。"
64
+ for image_file in sorted(os.listdir(args.image_dir)):
65
+ if not image_file.lower().endswith(('.png', '.jpg', '.jpeg', '.bmp')):
66
+ continue
67
  setup_seed(random.randint(1, 31415926))
68
  image_path = os.path.join(args.image_dir, image_file)
69
  image = Image.open(image_path).convert('RGB')
 
85
  )
86
  gen_tokens = len(generated_ids[0]) - len(inputs["input_ids"][0])
87
  print(f'\n[Speed]: {gen_tokens / (time.time() - st):.2f} tokens/s\n\n') if args.show_speed else print('\n\n')
88
+ else:
89
+ while True:
90
+ image_path = input('图片路径(留空跳过): ').strip()
91
+ prompt = input('💬: ').strip()
92
+ if not prompt:
93
+ break
94
+ setup_seed(random.randint(1, 31415926))
95
+ pixel_values = None
96
+ if image_path and os.path.exists(image_path):
97
+ image = Image.open(image_path).convert('RGB')
98
+ pixel_values = {k: v.to(args.device) for k, v in VLM.image2tensor(image, preprocess).items()}
99
+ if '<image>' not in prompt:
100
+ prompt = '<image>\n' + prompt
101
+
102
+ content = prompt.replace('<image>', getattr(model.config, 'image_special_token', '<|image_pad|>') * getattr(model.config, 'image_token_len', 64))
103
+ messages = [{"role": "user", "content": content}]
104
+ inputs_text = tokenizer.apply_chat_template(messages, tokenize=False, add_generation_prompt=True, open_thinking=bool(args.open_thinking))
105
+ inputs = tokenizer(inputs_text, return_tensors="pt", truncation=True).to(args.device)
106
+
107
+ print('🤖: ', end='')
108
+ st = time.time()
109
+ gen_kwargs = dict(
110
+ inputs=inputs["input_ids"], attention_mask=inputs["attention_mask"],
111
+ max_new_tokens=args.max_new_tokens, do_sample=True, streamer=streamer,
112
+ pad_token_id=tokenizer.pad_token_id, eos_token_id=tokenizer.eos_token_id,
113
+ top_p=args.top_p, temperature=args.temperature,
114
+ )
115
+ if pixel_values is not None:
116
+ gen_kwargs['pixel_values'] = pixel_values
117
+ generated_ids = model.generate(**gen_kwargs)
118
+ gen_tokens = len(generated_ids[0]) - len(inputs["input_ids"][0])
119
+ print(f'\n[Speed]: {gen_tokens / (time.time() - st):.2f} tokens/s\n') if args.show_speed else print()
120
 
121
  if __name__ == "__main__":
122
  main()