-
Notifications
You must be signed in to change notification settings - Fork 549
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
Add Outline
s
#1364
base: main
Are you sure you want to change the base?
Add Outline
s
#1364
Conversation
8cb052d
to
26b14b9
Compare
We should allow functions that are not decorated, such as def build_prompt(a: int) -> str:
return f"What is {a} squared?" Because we do not want to force the use of templates on users. |
Also you can deprecate the code in |
outlines/outline.py
Outdated
prompt = self.template(*args) | ||
|
||
# Generate the response using the model | ||
response = self.model.generate(prompt) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should use either outlines.generate.json
, outlines.generate.regex
, etc. The interface is necessarily going to be brittle for now. You can take a look at the v1 branch to see how this is going to be more robust with the undergoing refactor.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, okay, but which one of those should I use by default? And how should I let users switch to the other one, by adding a fourth optional argument, e.g. generation_kind
, WDYT?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just realized that maybe I misunderstood the issue, and this PR should infer the correct regex to match the user's required output type. E.g., if a user asks for an int
, I should ask outlines.generate.regex
something like ^[+-]?[0-9]+$
. IIUC, I'm unsure how to scale this to arbitrary return types. Should we define a list of supported basic return types? Using ast.literal_eval
was the most flexible solution I came up with, but I'm not sure how well it handles custom data structures. In such cases (when the return type isn't in the list of straightforward Python builtins), I think we should check that users provide types that implement deserialization from JSON (and then use outlines.generate.json
), WDYT?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's only accept Pydantic models / JSON Schema strings for now and use outlines.generate.json
. We'll be able to easily generalise after we push the refactor in the v1 branch.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've updated the PR (and the usage example in the docstring). Does it still look like what we want?
26b14b9
to
e328144
Compare
That's already how this PR works, I just wanted to confirm that this was the intended design and not an omission!
Should I handle that in this PR or a separate one? By deprecate, do you mean adding a user-facing warning when it's used, rather than removing it entirely? |
We can do it in this PR. Let's add a user-facing warning, and announce that it will be removed in favour of the |
ddd5409
to
214a2f3
Compare
b2512e9
to
9a9acba
Compare
9a9acba
to
90361fa
Compare
outlines/outline.py
Outdated
try: | ||
if isinstance(self.output_type, str): | ||
return json.loads(response) | ||
return self.output_type.model_validate_json(response) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's instantiate the model with the JSON data, like we do here to keep a consistent interface.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I got this linter warning:
The method "parse_raw" in class "BaseModel" is deprecated
Theparse_raw
method is deprecated; if your data is JSON usemodel_validate_json
, otherwise load the data then usemodel_validate
instead.Pylance
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right, my bad
1892f30
to
aa4a904
Compare
I'm a bit frustrated by this failing test, I can't reproduce it locally, and I'm not sure how to work around it :/ |
Update the tests to not use deprecated (Nice to see the deprecation working properly though!) |
Also, found mention in quickstart docs, needs to be updated too: Lines 186 to 190 in 79100b2
|
aa4a904
to
7991d18
Compare
|
|
I’m definitely struggling with this issue. Thanks to action-tmate, I was able to get an interactive shell in a GitHub Action job, but I’m not sure what to do next? Maybe I should compare my local and CI pip freeze outputs? I’d really like to avoid this kind of issue in the future, I’ve tried to address it in #1387! |
Can you run |
And the `output_type` should now be a Pydantic model or a JSON Schema str
Since the module was deprecated the tests were failing with a warning.
Thanks for the tips! I ran it inside the GitHub Action job and got the following traceback: outlines/fsm/guide.py:76: in cached_create_states_mapping
return uncached_create_states_mapping(regex_string, tokenizer, *args, **kwargs)
/opt/hostedtoolcache/Python/3.10.16/x64/lib/python3.10/site-packages/outlines_core/fsm/guide.py:141: in create_states_mapping
return create_states_mapping_from_fsm(regex_fsm, tokenizer, frozen_tokens)
/opt/hostedtoolcache/Python/3.10.16/x64/lib/python3.10/site-packages/outlines_core/fsm/guide.py:178: in create_states_mapping_from_fsm
states_to_token_maps, empty_token_ids = create_fsm_index_tokenizer(
/opt/hostedtoolcache/Python/3.10.16/x64/lib/python3.10/site-packages/outlines_core/fsm/regex.py:473: in create_fsm_index_tokenizer
tokens_to_token_ids, empty_token_ids = reduced_vocabulary(tokenizer)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
tokenizer = <Mock name='mock.tokenizer' id='140081937198256'>
@lru_cache
def reduced_vocabulary(
tokenizer,
) -> Tuple[Dict[str, List[int]], Set[int]]:
"""Create a map from decoded vocabulary tokens to lists of equivalent token ids."""
# TODO FIXME: See if we can get the underlying Rust tokenizers from HF and
# do all this in Rust
empty_token_ids = set()
vocabulary: Dict[str, List[int]] = {}
> for token, token_idx in tokenizer.vocabulary.items():
E TypeError: 'Mock' object is not iterable
/opt/hostedtoolcache/Python/3.10.16/x64/lib/python3.10/site-packages/outlines_core/fsm/regex.py:394: TypeError
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> entering PDB >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> PDB post_mortem (IO-capturing turned off) >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
> /opt/hostedtoolcache/Python/3.10.16/x64/lib/python3.10/site-packages/outlines_core/fsm/regex.py(394)reduced_vocabulary()
-> for token, token_idx in tokenizer.vocabulary.items():
(Pdb) p tokenizer
<Mock name='mock.tokenizer' id='140081937198256'>
(Pdb) p dir(tokenizer)
['assert_any_call', 'assert_called', 'assert_called_once', 'assert_called_once_with', 'assert_called_with', 'assert_has_calls', 'assert_not_called', 'attach_mock', 'call_args', 'call_args_list', 'call_
count', 'called', 'configure_mock', 'method_calls', 'mock_add_spec', 'mock_calls', 'reset_mock', 'return_value', 'side_effect', 'vocabulary']
(Pdb) p tokenizer.vocabulary
<Mock name='mock.tokenizer.vocabulary' id='140081937198736'>
(Pdb) p tokenizer.vocabulary.items
<Mock name='mock.tokenizer.vocabulary.items' id='140081937198832'> This made me realize that |
8bf90a8
to
535cd5a
Compare
Fix #1346, WDYT about the integration with
outlines.prompt
? (Here, the template argument is just a function that returns astr
, so it could be either an@outlines.prompt
-decorated function or a regular one)