You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Originally posted by joerunde March 5, 2025
cc @cpfiffer, following up on the discussion from #180
My colleague @frankdvd has done some analysis of the time it takes to build a RegexGuide based on the complexity of the input json schema, which I'll paste below. We also saw similar results using the Vocabulary, Index, Guide method shown on the readme.
It looks like we're doing something wrong, since it's taking quite a long time to compile these guides for relatively simple json schemas. When we try the same thing with lm-format-enforcer, we don't see a meaningful increase in time taken to compile a token enforcer for the same schemas.
On the related issue where we had a user passing in an invalid schema, you had mentioned I was able to get this to compile in 80-90ms using our internal API. I had assumed you were talking about outlines-core, but maybe not? If there is a super secret sauce that y'all aren't open sourcing, I'd be happy to email you about it, but I did want to have this discussion in the open if we're just using outlines-core wrong.
Here's the anaylsis:
I did some experiments to measure the performance of the outlines, and try to find the root case of the hang/slowness. At first I thought it was some special keyword or syntax that was causing the hang, so I wasted some time trying to troubleshoot what was causing the problem. I eventually realized that the root cause of the problem was so simple that the number of fileds in an object would exponentially affect the computation time.
if we want to control the size of the input to avoid timeout or hang, the regex generation needs to less than 30s(I guess):
According to test1/3/4, the maximum number of fields in each object must be less than 9. And the total number of fields in the whole json needs to be less than 20.
I'm not sure how many tools/api's would still be available if the above restrictions were applied to our api.......
Python code to reproduce this:
importoutlinesfromoutlines_core.fsm.json_schemaimportbuild_regex_from_schemafromoutlines.fsm.guideimportRegexGuideimportjsonfromtransformersimportAutoTokenizerimporttimeimportcopyimportmatplotlib.pyplotaspltimportnumpyasnptk=AutoTokenizer.from_pretrained("meta-llama/Meta-Llama-3-8B")
outlines_tokenizer=outlines.models.TransformerTokenizer(
tk
)
simple_field= {
"type": "string"
}
simple_obj= {
"type": "object",
"description": "simple obj",
"properties": {}
}
root_schema= {
"type": "object",
"properties": {}
}
defgenerateTime(n, generateJsonObj):
t= []
foriinrange(n+1):
schema_str=json.dumps(generateJsonObj(i))
#print(schema_str)start_time=time.time()
regex=build_regex_from_schema(schema_str)
guide=RegexGuide.from_regex(regex, outlines_tokenizer)
end_time=time.time()
elapsed_time=end_time-start_timet.append(elapsed_time)
print(f"Elapsed time for build regex: {elapsed_time:.4f} seconds")
# we use 0 to warmup, now remove itdelt[0]
returntdefplot(n, t, factor, name):
# Data for plottingx=np.arange(1, n+1) *factorfig, ax=plt.subplots()
ax.plot(x, t)
ax.set(xlabel='n', ylabel='regex build time',
title=name)
ax.grid()
fig.savefig(name+".png")
defn_widths(base):
deff(n):
schema=copy.deepcopy(root_schema)
foriinrange(1, n+1):
schema["properties"][ "w"+str(i) ] =basereturnschemareturnfdefn_depths(base):
deff(n):
schema=copy.deepcopy(root_schema)
root=schemaforiinrange(1, n+1):
root["properties"][ "d"+str(i) ] =copy.deepcopy(base)
root=root["properties"][ "d"+str(i) ]
returnschemareturnf# test widthmax_width=10t=generateTime(max_width, n_widths(simple_field))
plot(max_width, t, 1, "num_fields_in_width_vs_time")
print("num_fields_in_width_vs_time json example:")
print(json.dumps(n_widths(simple_field)(3)))
# test depthmax_depth=50t=generateTime(max_depth, n_depths(simple_obj))
plot(max_depth, t, 1, "num_fields_in_depth_vs_time")
print("num_fields_in_depth_vs_time json example:")
print(json.dumps(n_depths(simple_obj)(3)))
# test n by 6 jsonmax_width=5base_json=n_widths(simple_field)(6)
t=generateTime(max_width, n_widths(base_json))
plot(max_width, t, 6, "total_num_fields_with_6_fields_base_vs_time")
print("total_num_fields_with_6_fields_base_vs_time json example:")
print(json.dumps(n_widths(base_json)(3)))
# test n by 3 jsonmax_width=8base_json=n_widths(simple_field)(3)
t=generateTime(max_width, n_widths(base_json))
plot(max_width, t, 3, "total_num_fields_with_3_fields_base_vs_time")
print("total_num_fields_with_3_fields_base_vs_time json example:")
print(json.dumps(n_widths(base_json)(3)))
The text was updated successfully, but these errors were encountered:
@joerunde (and @rlouf )
Did you check that the tests have been made with release mod activated ?
I got fooled myself.
Every benchmark times that I got here #194 are bad because it's in debug mod.
ASV (The framework used inside the benchmark worflow) use by default the release mod.
And When I use the release mod, All my times have been divide by ten.
For sample schema we are not talking anymore about second but ms.
Discussed in #192
Originally posted by joerunde March 5, 2025
cc @cpfiffer, following up on the discussion from #180
My colleague @frankdvd has done some analysis of the time it takes to build a
RegexGuide
based on the complexity of the input json schema, which I'll paste below. We also saw similar results using theVocabulary, Index, Guide
method shown on the readme.It looks like we're doing something wrong, since it's taking quite a long time to compile these guides for relatively simple json schemas. When we try the same thing with
lm-format-enforcer
, we don't see a meaningful increase in time taken to compile a token enforcer for the same schemas.On the related issue where we had a user passing in an invalid schema, you had mentioned I was able to get this to compile in 80-90ms using our internal API. I had assumed you were talking about
outlines-core
, but maybe not? If there is a super secret sauce that y'all aren't open sourcing, I'd be happy to email you about it, but I did want to have this discussion in the open if we're just usingoutlines-core
wrong.Here's the anaylsis:
I did some experiments to measure the performance of the
outlines
, and try to find the root case of the hang/slowness. At first I thought it was some special keyword or syntax that was causing the hang, so I wasted some time trying to troubleshoot what was causing the problem. I eventually realized that the root cause of the problem was so simple that the number of fileds in an object would exponentially affect the computation time.Test 1: # of fields in 1 objects vs time
Example schema when n = 3:
We can see that the time grows exponentially as n increases.
Test 2: # of json object in depth nested vs time
Example schema when n = 3:
We can see that the time grows linearly as n increases, so the depth is not the root cause.
Test 3: total number of fields in a 2 depth json with nested object contains 6 fields vs time
Example schema when n = 12:
Test 4: total number of fields in a 2 depth json with nested object contains 3 fields vs time
Example schema when n = 9:
conclusion
if we want to control the size of the input to avoid timeout or hang, the regex generation needs to less than 30s(I guess):
According to test1/3/4, the maximum number of fields in each object must be less than 9. And the total number of fields in the whole json needs to be less than 20.
I'm not sure how many tools/api's would still be available if the above restrictions were applied to our api.......
Python code to reproduce this:
The text was updated successfully, but these errors were encountered: