Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

logits的获取 #1933

Open
2 tasks done
AIFFFENG opened this issue Jul 5, 2024 · 12 comments
Open
2 tasks done

logits的获取 #1933

AIFFFENG opened this issue Jul 5, 2024 · 12 comments
Assignees

Comments

@AIFFFENG
Copy link

AIFFFENG commented Jul 5, 2024

Checklist

  • 1. I have searched related issues but cannot get the expected help.
  • 2. The bug has not been fixed in the latest version.

Describe the bug

模型为Qwenvl

Reproduction

image_list =[image_path]*100
prompts = [(instruct_question, load_image(img_url)) for img_url in image_list]
response = pipe(prompts,gen_config=gen_config)
批量推理

Environment

Error traceback

No response

@AIFFFENG
Copy link
Author

AIFFFENG commented Jul 5, 2024

主要是想知道log probs是怎么获取结果的,需要取模型每次解码的logits分数,有什么办法获取每次解码过程中所有词表对应的logits输出吗?

@AIFFFENG
Copy link
Author

AIFFFENG commented Jul 7, 2024

仔细看了代码,不知道你们是否有支持输出greddy search配合输出logits的计划,现在虽然可以通过设置top p和top k实现greedy search,但是输出的logprobs只有一个token,无法查看不同token之间的概率分布。另外一点,虽然可以通过设置topk的数量看到指定数量token的token概率,但是这样输出的结果变成随机了,不利于确定性任务的部署(比如分类任务,毕竟从topk里面随机采样待来的随机性不能接受)

@AIFFFENG AIFFFENG changed the title [Bug] 想用vscode debug 代码的运行,发现debug到模型运行的时候直接返回结果,无法得知把处理好的输入送入模型得到输出的中间过程 [Bug] logits的获取 Jul 8, 2024
@AIFFFENG AIFFFENG changed the title [Bug] logits的获取 logits的获取 Jul 8, 2024
@RunningLeon
Copy link
Collaborator

@AIFFFENG
Copy link
Author

AIFFFENG commented Jul 8, 2024

@AIFFFENG hi, you can refer to this example: https://lmdeploy.readthedocs.io/en/latest/inference/vl_pipeline.html#calculate-logits

这个只是得到了输入的logits吧?

@lvhan028
Copy link
Collaborator

lvhan028 commented Jul 9, 2024

You can set logprobs in GenerationConfig.

logprobs: int = None

@lvhan028 lvhan028 self-assigned this Jul 9, 2024
@AIFFFENG
Copy link
Author

You can set logprobs in GenerationConfig.

logprobs: int = None

是的,我确实可以通过设置logprobs得到概率,但是这样需要同时设置topk才能得到topk的概率,我想要的是能够支持输出原始的logits信息(词表大小,同时greddy search)

@lvhan028
Copy link
Collaborator

这篇文档中,介绍了获取 logits 的方式。
在获取了logits后,在vocab_size维度上求个最大值,就知道greedy search要选哪个token了吧

from transformers import AutoTokenizer
from lmdeploy import pipeline
model_repoid_or_path='internlm/internlm2_5-7b-chat'
pipe = pipeline(model_repoid_or_path)
tokenizer = AutoTokenizer.from_pretrained(model_repoid_or_path, trust_remote_code=True)

# logits
messages = [
   {"role": "user", "content": "Hello, how are you?"},
]
input_ids = tokenizer.apply_chat_template(messages)
logits = pipe.get_logits(input_ids)

@AIFFFENG
Copy link
Author

这篇文档中,介绍了获取 logits 的方式。 在获取了logits后,在vocab_size维度上求个最大值,就知道greedy search要选哪个token了吧

from transformers import AutoTokenizer
from lmdeploy import pipeline
model_repoid_or_path='internlm/internlm2_5-7b-chat'
pipe = pipeline(model_repoid_or_path)
tokenizer = AutoTokenizer.from_pretrained(model_repoid_or_path, trust_remote_code=True)

# logits
messages = [
   {"role": "user", "content": "Hello, how are you?"},
]
input_ids = tokenizer.apply_chat_template(messages)
logits = pipe.get_logits(input_ids)

我做过这个的实验,但是这个获取的logits应该是输入的logits吧?我看模型并没有输出其他的token

@lvhan028
Copy link
Collaborator

如果是要所有output_token的logits,确实没有这个功能。可以看看其他框架,或者用transformers吧

@AIFFFENG
Copy link
Author

如果是要所有output_token的logits,确实没有这个功能。可以看看其他框架,或者用transformers吧

其他框架支持的不是很好。我有个疑问,按理说解码过程应该是会输出词表中每个token的概率吧,然后这时候根据topk和topp去选取对应的token,最后再通过log softmax得到ogprob,既然可以得到logprob,按理说只要将解码过程中每个token的概率保存并且返回即可吧?(我在c++源码里面有发现is_return_logits等变量(我猜是这个),在python的generate 传入该变量,模型报错了),总结来说还是想很好奇框架不支持返回logits的原因,理论上应该保存即可实现。

@lvhan028
Copy link
Collaborator

我个人的看法是:

  1. 要求输出每个token的logits,对显存是一个巨大的开销
  2. 显存管理不好做,也会增加异常处理的难度。kv cache 会预分配。logits是不是要预分配,如果是预分配,但是请求却不要求ret_logits,那这块预分配的内存就浪费了。如果不预分配,等请求来了再分配,会造成内存碎片化,或者开不出所需大小的内存
  3. 输出每个token的logits是不是真的有必要?

@AIFFFENG
Copy link
Author

我个人的看法是:

  1. 要求输出每个token的logits,对显存是一个巨大的开销
  2. 显存管理不好做,也会增加异常处理的难度。kv cache 会预分配。logits是不是要预分配,如果是预分配,但是请求却不要求ret_logits,那这块预分配的内存就浪费了。如果不预分配,等请求来了再分配,会造成内存碎片化,或者开不出所需大小的内存
  3. 输出每个token的logits是不是真的有必要?

感谢回复,前两点确实解决了我对于输出logits的困惑,我解释一下第三点的原因。
1.简化一下问题场景,对于一个分类任务(a,b),a表示该图片是高伤害的图片(需要剔除,如果不输出logits的话,我们不能做到卡阈值的操作去减少高伤害的图片漏召的概率。
2.我们其实也尝试了通过设置topk和log prob的数量来实现概率的获取,但是毕竟topk的内部逻辑导致在输出结果上a和b都有可能被随机选取,这样就导致结果出现问题。
3.而这里按照您的说法,我有个 个人的想法。既然无法保留全部token的logits,能不能实现一个greddy decode+设定一定数量的token的logits的功能,毕竟现在logprob在topk的情况下也实现了这个功能,这部分预分配的内存是否也能够通过greddy decode进行使用呢?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants