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

我发现在生成第二个token的时候才会调用attention.py的增强图像注意力模块。 #11

Open
FanshuoZeng opened this issue Nov 14, 2024 · 6 comments

Comments

@FanshuoZeng
Copy link

您好,我研究您的代码的时候发现在生成第2个及之后的token的时候才会运行图像注意力增强的代码:
image

也就是说如果max_new_tokens=1,图像注意力增强模块就不能起作用了。但是直观上来看应该在每一次生成新的token的时候都要使用到这个模块。

请问您可以为我解答一下吗,非常感谢!

@LALBJ
Copy link
Owner

LALBJ commented Nov 18, 2024

你好,感谢对于我们工作的关注!

这种写法不会影响生成的 token,但是对于输入的 token 没有作用。即使是在第一次 token 生成时,也是先通过 attention layers 再输出第一个 token 的 logits。而 -1 正是对应着第一个生成 token hidden states 的索引。所以对于所有的输出 token 是持续作用的。

对于输入 token,因为我们的扰动只选择了 -1 索引,也就是当前 token,所以对于输入的 token 并没有影响。

其实这里的 -1 就是为了处理第一个生成的 token 而加的。只有在第一次 forward 时,attn_weights 的 shape 为 ( _, _, sequence_lens, sequence_lens)。在后续的 forward 中 attn_weights 的 shape 因为 kv cache 的实现,均为 ( _, _, 1, sequence_lens)。所以,第一次 forward 时需要通过 -1 进行索引,取出被扰动的 token。

@FanshuoZeng
Copy link
Author

你好,在生成第一个token的时候的确会通过 attention layers。但是这时候use_cfg为True,所以不会执行attention.py的第90-94行代码。我debug试了一下也确实如此。只有在生成第二个及以后的token的时候才会执行第90-94行代码。

@LALBJ
Copy link
Owner

LALBJ commented Nov 25, 2024

哈喽,

你可以参考一下这个 issues

所以,如果同时打开 CFG.py 组件去 debug 的话,生成一个 token 时会 forward 两次,一次会执行 90-94 行的逻辑,一次不会。

@FanshuoZeng
Copy link
Author

FanshuoZeng commented Nov 25, 2024

你好,当我同时使用这两个组件的时候,use_attn和use_cfg都为True。在生成第一个token的时候,第一次forward在attention.py的第90行进行判断,( not use_cfg)为False,这时候不会执行90-94 行。然后在CFG.py文件的第33行将use_cfg设置为True,之后执行第二次forward,即只有文本没有图像token的推理,同样不会执行90-94行。之后在CFG.py的第49行将use_cfg 设置为False,之后执行余下的操作,生成第一个token。在生成第二个token的时候,use_cfg 为False,第一次forward的时候在attention.py的90行进行判断,( not use_cfg)为True,执行90-94行。同样在第二次forward的时候不会执行90-94行。之后的token都像第二个token一样,第一次forward执行90-94行,第二次forward不会执行。

我debug的结果是:生成第一个token两次forward都不会执行90-94行的逻辑,在生成之后的token时,第一次forward会执行90-94行,第二次forward不会执行90-94行,除了第一个token外,其余的token与您给出的issues中的解释一致。

我是不是遗漏了一些信息或者对代码理解有误,请您指正。

@sleepyshep
Copy link

你好,感谢对于我们工作的关注!

这种写法不会影响生成的 token,但是对于输入的 token 没有作用。即使是在第一次 token 生成时,也是先通过 attention layers 再输出第一个 token 的 logits。而 -1 正是对应着第一个生成 token hidden states 的索引。所以对于所有的输出 token 是持续作用的。

对于输入 token,因为我们的扰动只选择了 -1 索引,也就是当前 token,所以对于输入的 token 并没有影响。

其实这里的 -1 就是为了处理第一个生成的 token 而加的。只有在第一次 forward 时,attn_weights 的 shape 为 ( _, _, sequence_lens, sequence_lens)。在后续的 forward 中 attn_weights 的 shape 因为 kv cache 的实现,均为 ( _, _, 1, sequence_lens)。所以,第一次 forward 时需要通过 -1 进行索引,取出被扰动的 token。

您好!请问为什么说“对于输入的 token 没有作用”,在生成的过程中修改attn_weights的最后一行也会导致attn_output发生改变,从而使hidden_states改变

@hxhcreate
Copy link

+1,如果只生成一个token的话,似乎不会调用attention中的90-95行

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

4 participants