okami.mom/albedo
git clone https://git.nkp.pet/okami.mom/albedo
3846f03
main
1//// Run explicitly with: gleam run -m manual/benchmark 2//// ALBEDO_BENCH_URL, ALBEDO_BENCH_MODEL, ALBEDO_BENCH_KEY are environment variables. 3//// Makes at most three requests per protocol; stops a protocol on its first error. 4 5import albedo/openai_api as openai 6import albedo/openai_api/types 7import gleam/io 8import gleam/json 9import gleam/list 10import gleam/option .{ type Option , None , Some } 11import gleam/string 12 13pub type Metrics { 14Metrics ( 15elapsed_ms : Float , 16first_text_ms : Option ( Float ), 17text_bytes : Int , 18chunks : Int , 19peak_process_bytes : Int , 20peak_vm_binary_growth_bytes : Int , 21reductions : Int , 22) 23} 24 25@external ( erlang , "albedo_openai_bench" , "env" ) 26fn env ( name : String ) -> String 27 28@external ( erlang , "albedo_openai_bench" , "measure" ) 29fn measure ( run : fn () -> a) -> #( a, Metrics ) 30 31@external ( erlang , "albedo_openai_bench" , "text" ) 32fn text ( bytes : Int ) -> Nil 33 34pub fn main () -> Nil { 35let key = env ( "ALBEDO_BENCH_KEY" ) 36let url = env ( "ALBEDO_BENCH_URL" ) 37let model = env ( "ALBEDO_BENCH_MODEL" ) 38case key == "" || url == "" || model == "" { 39True -> 40io . println ( "missing benchmark environment variables; no requests made" ) 41False -> { 42let protocols = case env ( "ALBEDO_BENCH_PROTOCOL" ) { 43"responses" -> [ types . Responses ] 44"chat_completions" -> [ types . ChatCompletions ] 45_ -> [ types . Responses , types . ChatCompletions ] 46} 47list . each ( protocols , fn ( protocol ) { 48run ( openai . client ( protocol , url , key ), model , 1 ) 49}) 50} 51} 52} 53 54fn run ( client : types . Client , model : String , iteration : Int ) -> Nil { 55let client = types . Client (.. client , timeout_ms : 90_000 ) 56let request = 57openai . request ( model , [ 58types . User ( 59"Write the integers from 1 through 80, separated by spaces. Do not include any other text." , 60), 61]) 62let request = types . Request (.. request , max_output_tokens : Some ( 256 )) 63let #( result , metrics ) = 64measure ( fn () { 65openai . stream ( client , request , fn ( event ) { 66case event { 67types . TextDelta ( _ , _ , value ) -> text ( string . byte_size ( value )) 68_ -> Nil 69} 70types . Continue 71}) 72}) 73let protocol = case client . protocol { 74types . Responses -> "responses" 75types . ChatCompletions -> "chat_completions" 76} 77let fields = [ 78#( "protocol" , json . string ( protocol )), 79#( "iteration" , json . int ( iteration )), 80#( "elapsed_ms" , json . float ( metrics . elapsed_ms )), 81#( "first_text_ms" , json . nullable ( metrics . first_text_ms , json . float )), 82#( "text_bytes" , json . int ( metrics . text_bytes )), 83#( "text_chunks" , json . int ( metrics . chunks )), 84#( "sampled_peak_process_bytes" , json . int ( metrics . peak_process_bytes )), 85#( 86"sampled_peak_vm_binary_growth_bytes" , 87json . int ( metrics . peak_vm_binary_growth_bytes ), 88), 89#( "worker_reductions" , json . int ( metrics . reductions )), 90] 91let fields = case result { 92Ok ( turn ) -> [ 93#( "ok" , json . bool ( True )), 94#( "finish" , json . string ( string . inspect ( turn . finish ))), 95#( 96"input_tokens" , 97json . nullable ( option_tokens ( turn . usage , True ), json . int ), 98), 99#( 100"output_tokens" , 101json . nullable ( option_tokens ( turn . usage , False ), json . int ), 102), 103.. fields 104] 105Error ( error ) -> [ 106#( "ok" , json . bool ( False )), 107#( 108"error" , 109json . string ( 110string . inspect ( error ) 111|> string . replace ( client . api_key , "[redacted]" ) 112|> string . slice ( 0 , 2000 ), 113), 114), 115.. fields 116] 117} 118fields |> json . object |> json . to_string |> io . println 119case result , iteration < 3 { 120Ok ( _ ), True -> run ( client , model , iteration + 1 ) 121_ , _ -> Nil 122} 123} 124 125fn option_tokens ( usage : Option ( types . Usage ), input : Bool ) -> Option ( Int ) { 126case usage , input { 127None , _ -> None 128Some ( usage ), True -> Some ( usage . input_tokens ) 129Some ( usage ), False -> Some ( usage . output_tokens ) 130} 131}