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

Restore the ability to stop when a specified string has been generated #451

Merged
merged 6 commits into from
Dec 23, 2023

Conversation

RobinPicard
Copy link
Contributor

This PR aims at solving #417

The proposed change does 2 main things:

  • break the generation loop in SequenceGenerator.__call__ if all sequences contain at least one of the stop_sequences provided by the user
  • format the generated sequences to truncate them once the first stop_sequence is found in them

A downside of adding this logic at the level of the SequenceGenerator is that we generate text that is later discarded. However, incorporating this logic in the fsm would require much bigger change as we need to decode the token_ids to check whether the stop_sequences are found. Maybe this could be a first solution before some future refactoring.

As suggested in #433, I think we could treat the max_tokens parameter in a similar way as what's proposed here for the stop_sequences

I've only modified the tests required to pass the tests and the linting, but will modify them further along with documentation in another commit if you think this PR is going in the right direction.

@rlouf
Copy link
Member

rlouf commented Dec 20, 2023

Go ahead, this is the right direction! We'll be able to simplify greatly StopAtFSM and rename it to BaseFSM or something like that.

@@ -17,13 +18,16 @@ def json(
"The old import path will be removed in Outlines v0.1.0.",
DeprecationWarning,
)
return outlines.generate.json(model, schema_object, max_tokens, sampler=sampler)
return outlines.generate.json(
model, schema_object, max_tokens, stop, sampler=sampler
Copy link
Member

Choose a reason for hiding this comment

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

The old interface used stop_at, we should keep that name at least here

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I put stop because it's what continuation seemed to expect on line 49 and what you removed in your big PR. Was it stop_at in an earlier version?

Copy link
Member

Choose a reason for hiding this comment

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

Yes it was. stop_at sounds like a better name anyway, wdyt?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Absolutely!

@RobinPicard
Copy link
Contributor Author

I have a few questions @rlouf:

  • For passing the max_tokens argument when calling the generator instead of initializing it, should we keep both options for the moment not to break the existing interface or should we already remove the parameter in the __init__ method?
  • Should we also pass end when calling the generator instead of initializing it?
  • Should those 2 parameters be available for all the generate functions even for those for which it makes less sense (for instance json)?

@rlouf
Copy link
Member

rlouf commented Dec 21, 2023

  • For passing the max_tokens argument when calling the generator instead of initializing it, should we keep both options for the moment not to break the existing interface or should we already remove the parameter in the __init__ method?

We can do both with a deprecation warning if passed in __init__ (same version as for /txt/generate/api.py)

  • Should we also pass end when calling the generator instead of initializing it?

Yes. Should call it end_at to be consistent with stop_at.

  • Should those 2 parameters be available for all the generate functions even for those for which it makes less sense (for instance json)?

I don't think it's necessary for JSON, Regex, format. But might be useful for grammar-guided generation.

@rlouf
Copy link
Member

rlouf commented Dec 22, 2023

Is it ready for review? I can take a look at these merge conflicts later.

@RobinPicard
Copy link
Contributor Author

Is it ready for review? I can take a look at these merge conflicts later.

Yes!

@rlouf
Copy link
Member

rlouf commented Dec 23, 2023

I made a few cosmetic changes (naming and docstrings) + rebased on main. Otherwise, looks great! You can have a last look and if you're good with the changes I made we can merge.

@RobinPicard
Copy link
Contributor Author

I made a few cosmetic changes (naming and docstrings) + rebased on main. Otherwise, looks great! You can have a last look and if you're good with the changes I made we can merge.

Looks great! Thanks for adding the docstrings

@rlouf rlouf merged commit 3508cd9 into outlines-dev:main Dec 23, 2023
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
2 participants