///|
let runs : Int = 100
///|
let seed : Bytes = b"moonmask-monkey-typewriter-00042"
///|
fn is_valid(text : Bytes, validator : @moonschema.Schema) -> Bool {
try {
let value = @json.parse(@utf8.decode(text))
validator.valid(value)
} catch {
_ => false
} noraise {
ok => ok
}
}
///|
fn preview(text : Bytes) -> String {
let buf = StringBuilder()
let mut n = 0
for c in @utf8.decode_lossy(text) {
if n == 100 {
buf.write_string("...")
break
}
buf.write_char(c)
n += 1
}
buf.to_string()
}
///|
fn run(args : Array[String]) -> Unit raise {
let whitespace = args[1] == "--whitespace"
let offset = if whitespace { 2 } else { 1 }
if args.length() < offset + 2 {
fail("expected tokenizer and at least one schema")
}
let tok = @tokenizer.from_file(args[offset])
let vocab = @vocab.from_tokenizer(tok, eos_token="<|endoftext|>")
println("vocab size: \{vocab.size()}, runs per schema: \{runs}")
println("JSON whitespace: \{whitespace}; uniform random sampling, no model")
let samples : Array[String] = []
let mut timed = false
let rows : Array[String] = []
for path in args[offset + 1:] {
let schema = @json.parse(@fs.read_file_to_string(path))
let dfa = @schema.compile(schema, whitespace~)
let guide = @mask.Guide::new(dfa, vocab)
if !timed {
let started = @bench.monotonic_clock_start()
let mask = guide.transitions(guide.start())
let elapsed_us = @bench.monotonic_clock_end(started)
println(
"prefix-tree token mask, one DFA state, vocab \{vocab.size()}, allowed \{mask.length()}: \{elapsed_us} us (\{path})",
)
timed = true
}
let validator = @moonschema.Schema::new(schema)
let rand = @random.Rand::chacha8(seed~)
let mut masked_ok = 0
let mut unmasked_ok = 0
let mut total_tokens = 0
for k in 0.. ...",
)
panic()
}
run(args) catch {
e => {
println("moonmask: \{e}")
panic()
}
}
}