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

Integrate KBNF grammar #815

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open

Integrate KBNF grammar #815

wants to merge 7 commits into from

Conversation

EricLBuehler
Copy link
Owner

No description provided.

Copy link

github-actions bot commented Oct 2, 2024

Code Metrics Report
  ===============================================================================
 Language            Files        Lines         Code     Comments       Blanks
===============================================================================
 C Header                2           35           28            0            7
 Dockerfile              1           34           25            0            9
 Happy                   1          442          369            0           73
 JSON                   12          105          104            0            1
 Python                 52         2268         1930           69          269
 TOML                   20          625          559            2           64
 YAML                    2           21           19            2            0
-------------------------------------------------------------------------------
 Jupyter Notebooks       4            0            0            0            0
 |- Markdown             2           77           32           31           14
 |- Python               2          196          169            1           26
 (Total)                            273          201           32           40
-------------------------------------------------------------------------------
 Markdown               38         2759            0         2093          666
 |- BASH                 6          103          100            0            3
 |- JSON                 1           12           12            0            0
 |- Python               5           92           82            0           10
 |- Rust                 9          322          274            0           48
 |- TOML                 2           75           63            0           12
 (Total)                           3363          531         2093          739
-------------------------------------------------------------------------------
 Rust                  260        75643        68177         1547         5919
 |- Markdown           123         1217           25         1117           75
 (Total)                          76860        68202         2664         5994
===============================================================================
 Total                 393        81932        71211         3713         7008
===============================================================================
  

Copy link
Owner Author

@EricLBuehler EricLBuehler left a comment

Choose a reason for hiding this comment

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

@Dan-wanna-M I was wondering if you could perhaps review some of this code and take a look at some of the review comments I made?

Copy link
Owner Author

Choose a reason for hiding this comment

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

Are the grammars here correct? Perhaps we can have a simpler example.

Choose a reason for hiding this comment

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

They look mostly correct to me; I have added some comments that can make the grammar more familiar and/or simpler to general users. In terms of simpler example, I think we can use something within regular grammar's capacity but can be more clearly written in kbnf. I think markdown list and the kbnf for a concrete json schema both qualify. Which one do you prefer, or you would like some examples in other areas?

Ok(second_sampled)
}
KbnfGrammarBias::FinishedGeneration => {
todo!()
Copy link
Owner Author

Choose a reason for hiding this comment

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

TODO: Need to mark the sequence as done.

Copy link
Owner Author

Choose a reason for hiding this comment

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

I was wondering if this file generally looks correct? It is paired with the sampling routines in sampling.rs and initialized in engine/mod.rs.

Copy link

@Dan-wanna-M Dan-wanna-M left a comment

Choose a reason for hiding this comment

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

@EricLBuehler I have reviewed the PR and suggested some changes.

(* JSON Grammar *)

(* JSON text must contain a single JSON value *)
start = value ;

Choose a reason for hiding this comment

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

Should be start ::= value;

| "null" ;

(* A JSON object is a collection of key/value pairs enclosed in curly braces *)
object ::= "{" [ members ] "}" ;

Choose a reason for hiding this comment

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

You can use both [members] and members? to express optional nonterminal


(* A JSON object is a collection of key/value pairs enclosed in curly braces *)
object ::= "{" [ members ] "}" ;
members ::= pair { "," pair } ;

Choose a reason for hiding this comment

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

You can use both {members} and members* to express 0 or infinite repetition.

elements ::= value { "," value } ;

(* A JSON string is a sequence of Unicode characters enclosed in double quotes *)
string ::= "\"" { character } "\"" ;

Choose a reason for hiding this comment

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

Choose a reason for hiding this comment

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

They look mostly correct to me; I have added some comments that can make the grammar more familiar and/or simpler to general users. In terms of simpler example, I think we can use something within regular grammar's capacity but can be more clearly written in kbnf. I think markdown list and the kbnf for a concrete json schema both qualify. Which one do you prefer, or you would like some examples in other areas?


client = OpenAI(api_key="foobar", base_url="http://localhost:1234/v1/")

JSON_KBNF = '''

Choose a reason for hiding this comment

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

You may also want to take a look at https://github.com/Dan-wanna-M/formatron/blob/master/src/formatron/formats/json.py where I put a json grammar definition. It also contains whitespace pattern that makes llm generate better json.


impl KbnfGrammar {
pub fn new(grammar: &str, tokenizer: &Tokenizer) -> Result<Self> {
let tokenizer_vocab = tokenizer.get_vocab(true);

Choose a reason for hiding this comment

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

I think we still need to "unpreprocess" the vocabulary or the control ASCII characters(like \n) and all non-ASCII characters will not be recognized correctly.

let mut bias = vec![0f32; self.vocab_size];
match self.engine.mask_logits(&mut bias) {
Ok(()) => {
let new_logits = (logits.to_device(&Device::Cpu)?.to_dtype(DType::F32)?

Choose a reason for hiding this comment

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

It might not be a good idea to move logits back to CPU due to potential CUDA synchronization issues. I think we can benchmark this to check latency. If it does bring too much latency, we can follow a strategy like this file which essentially only moves the indices tensor(tends to be smaller than the whole logits) to GPU and operate there.

}
}

/// Add a token, also to the trie.

Choose a reason for hiding this comment

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

technically speaking the cache is a hashmap, not a trie.

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.

2 participants