Skip to content

[docs] Output capturing - #50529

Merged
stevhliu merged 2 commits into
huggingface:mainfrom
stevhliu:output-capturing
Nov 10, 2026
Merged

stevhliu merged 2 commits into
huggingface:mainfrom
stevhliu:output-capturing

Conversation

@stevhliu

@stevhliu stevhliu commented Nov 9, 2026

Copy link
Copy Markdown
Member

Adds docs for #49594:

  • pass an index or list of indices to output_hidden_states to capture only the hidden states you need (this is for readers using a model)
  • use @select_hidden_states to capture only the hidden states a method uses (this is for readers adding a model)

@HuggingFaceDocBuilderDev

Copy link
Copy Markdown

The docs for this PR live here. All of your documentation changes will be reflected on that endpoint. The docs are available until 30 days after the last update.

Pages changed in this PR:

@vasqu vasqu left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just some nits but overall lgtm 🫡

Comment thread docs/source/en/model_output_tracing.md Resolved
Comment thread docs/source/en/model_output_tracing.md Resolved
Comment thread docs/source/en/model_output_tracing.md Outdated
class LlavaModel(LlavaPreTrainedModel):

@merge_with_config_defaults
@can_return_tuple

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm can we have one that does not need the merge config with defaults (because llava is a bit exotic tbh)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, probably better to use a generic example so readers can just focus on the important bits

Comment thread docs/source/en/model_output_tracing.md Resolved

@zucchini-nlp zucchini-nlp left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sgtm, tho i am not happy with a new decorator that overlaps hugely with existing one 🥹 Not on you, would be nice to merge them into one some time in the future

Comment on lines +34 to +35
> [!CAUTION]
> From v5.17 to v5.22, a list index `k` selected the output of layer `k` and left out the embedding output. It now selects `hidden_states[k]`, so add one to any positive index written for those versions.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good point!

Comment on lines +108 to +110
Feature extraction methods like `get_image_features` often read one or a few hidden states from a submodel, such as the vision tower. Requesting `output_hidden_states=True` keeps every layer alive to use only a few of them. Decorate the method with `@select_hidden_states` instead. It sets `output_hidden_states` to the indices the method uses, and the `@capture_outputs` of the submodel that receives the kwargs captures only those.

Pass the name of the method argument that holds the indices. The decorator reads the argument's value, including its default, and forwards it as `output_hidden_states`.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wait what, we added select_hidden_states on top of filter_hidden_states 😭
nooo

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The difference:

  • select_hidden_states only materialises and returns the requested states eagerly
  • filter_output_hidden_states materialises them all and filters to the requested states lazily

Ideally, the mechanism in filter_output_hidden_states should never have existed because it performs worse

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, if that filters afterwards - defi not the winning option. We should remove and replace it for next releases

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is an additional difference tho, in select hidden states we can handle the hidden states after the fact

hidden_states = model(...).hidden_states
# do smthn with hidden states
...

while output hidden states is filtering at the end of the model output

hidden_states = model(...).hidden_states
return ModelOutput(..., hidden_states=hidden_states)  # filters this hidden states out if not explicitly requested

Imo both could be fused into one but there is this difference that should be noted so it's not the same. In filter_output_hidden_states it's also mostly bound to backbones which need most hidden states anyways afaik

@stevhliu
stevhliu added this pull request to the merge queue Nov 10, 2026
Merged via the queue into huggingface:main with commit 7ebb132 Nov 10, 2026
42 checks passed
@stevhliu
stevhliu deleted the output-capturing branch November 10, 2026 17:05
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

Successfully merging this pull request may close these issues.

5 participants