【VLM】——vlm计算ppl损失

计算vlm模型的ppl损失。

代码:

python 复制代码
from transformers import Qwen2VLForConditionalGeneration, AutoProcessor
import torch
from torch.nn import CrossEntropyLoss
from PIL import Image


# 配置
DEVICE = "cuda:0"
MODEL_NAME = "/data1/chenjun/huf/Qwen2-VL-2B-Instruct"
IMAGE_SIZE = 384


def resize_image(path, max_side=384):
    """调整图片大小,保持宽高比"""
    image = Image.open(path).convert("RGB")
    width, height = image.size
    if width > height:
        new_width = max_side
        new_height = int(height * (max_side / width))
    else:
        new_height = max_side
        new_width = int(width * (max_side / height))
    return [image.resize((new_width, new_height), Image.Resampling.LANCZOS)]


def main():
    # 加载模型和处理器
    model = Qwen2VLForConditionalGeneration.from_pretrained(
        MODEL_NAME, dtype=torch.float32, device_map=DEVICE
    )
    processor = AutoProcessor.from_pretrained(MODEL_NAME)

    # 构建消息
    file = 'outputs/ppl_vlm_qwen3-vl-2b-axera-384/vit/0000.png'
    messages = [
        {
            "role": "user",
            "content": [
                {"type": "image", "image": file},
                {"type": "text", "text": "描述这张图片"},
            ],
        }
    ]

    # 应用chat模板
    text = processor.apply_chat_template(
        messages, tokenize=False, add_generation_prompt=True
    )

    # 处理图片
    image_inputs = resize_image(file, IMAGE_SIZE)
    inputs = processor(text=[text], images=image_inputs, return_tensors="pt").to(DEVICE)
    gen_idx = inputs['input_ids'].shape[1]

    # 生成文本
    generated_ids = model.generate(**inputs, max_new_tokens=256)
    generated_ids_trimmed = [
        out_ids[len(in_ids):]
        for in_ids, out_ids in zip(inputs.input_ids, generated_ids)
    ]
    output_text = processor.batch_decode(
        generated_ids_trimmed, skip_special_tokens=True, clean_up_tokenization_spaces=False
    )[0]

    # 计算PPL
    text_with_response = text + output_text
    image_inputs = resize_image(file, IMAGE_SIZE)
    inputs2 = processor(text=[text_with_response], images=image_inputs, return_tensors="pt").to(DEVICE)


    with torch.no_grad():
        outputs = model(**inputs2, max_new_tokens=1)
        logits = outputs.logits

        # 计算交叉熵损失
        shift_labels = inputs2['input_ids'][..., gen_idx+1:].contiguous().to(DEVICE)
        shift_logits = logits[..., gen_idx:-1, :].contiguous().to(dtype=torch.float32)
        loss_fct = CrossEntropyLoss()
        ce_loss = loss_fct(
            shift_logits.view(-1, shift_logits.size(-1)),
            shift_labels.view(-1)
        )
        print(f"ce_loss: {ce_loss:.3f}, ppl: {ce_loss.exp():.3f}")


if __name__ == "__main__":
    main()
相关推荐
找方案26 分钟前
AI 视觉创作工具 Claude Design 来了!Anthropic 的野心远不止 AI 作图
人工智能·原型设计·ai工具·claude design
wltx168837 分钟前
谷歌SEO+外贸版GEO优化步骤?
人工智能·python
龙腾AI白云38 分钟前
智能体如何配知识库?
人工智能·机器学习·数据挖掘
IT_陈寒1 小时前
Vue的响应式把我坑惨了,原来问题出在这
前端·人工智能·后端
key_3_feng1 小时前
ADI边缘AI开发板MAX78000FTHR开发实战:从零开始点亮LED
人工智能·开发板
胡志辉的博客1 小时前
多智能体协作,不是多开几个 Agent:从中介者模式看 OpenClaw 和 Hermes Agent
人工智能·设计模式·ai·agent·中介者模式·openclaw·herman
QQ676580081 小时前
智慧工厂之扬尘识别 铲车装载识别 工程重型机械识别 磁铁识别 深度学习YOLO格式图像识别第10435期
人工智能·深度学习·yolo·扬尘识别·铲车装载·工程重型机械·磁铁识别
Raink老师1 小时前
【AI面试临阵磨枪】KV Cache 是什么?为什么能加速推理?如何实现?
人工智能·ai 面试
newsxun2 小时前
第十六届北京国际电影节东郎分会场启幕
人工智能
大嘴皮猴儿2 小时前
从零开始学商品图翻译:小白也能快速掌握的多语言文字处理与上架技巧
大数据·ide·人工智能·macos·新媒体运营·xcode·自动翻译