Current section
Files
Jump to
Current section
Files
examples/metrics_live.exs
defmodule Tinkex.Examples.MetricsLive do
@moduledoc false
alias Tinkex.Error
def run do
{:ok, _} = Application.ensure_all_started(:tinkex)
api_key =
System.get_env("TINKER_API_KEY") ||
raise "Set TINKER_API_KEY to run this example"
base_url =
System.get_env(
"TINKER_BASE_URL",
"https://tinker.thinkingmachines.dev/services/tinker-prod"
)
base_model = System.get_env("TINKER_BASE_MODEL", "meta-llama/Llama-3.1-8B")
prompt_text = System.get_env("TINKER_PROMPT", "Quick metrics check from Tinkex")
max_tokens = env_integer("TINKER_MAX_TOKENS", 32)
temperature = env_float("TINKER_TEMPERATURE", 0.7)
num_samples = env_integer("TINKER_NUM_SAMPLES", 1)
await_timeout = env_integer("TINKER_SAMPLE_TIMEOUT", 30_000)
:ok = Tinkex.Metrics.reset()
config = Tinkex.Config.new(api_key: api_key, base_url: base_url)
{:ok, service} = Tinkex.ServiceClient.start_link(config: config)
{:ok, sampler} = Tinkex.ServiceClient.create_sampling_client(service, base_model: base_model)
{:ok, prompt} = Tinkex.Types.ModelInput.from_text(prompt_text, model_name: base_model)
params = %Tinkex.Types.SamplingParams{max_tokens: max_tokens, temperature: temperature}
IO.puts("Sampling #{num_samples} sequence(s) from #{base_model} ...")
{:ok, task} =
Tinkex.SamplingClient.sample(sampler, prompt, params,
num_samples: num_samples,
prompt_logprobs: false
)
result =
task
|> Task.await(await_timeout)
|> format_result(base_model)
IO.puts(result)
:ok = Tinkex.Metrics.flush()
snapshot = Tinkex.Metrics.snapshot()
render_snapshot(snapshot)
end
defp format_result({:ok, response}, model) do
text =
case List.first(response.sequences) do
nil ->
"[no sequences returned]"
seq ->
case Tinkex.Tokenizer.decode(seq.tokens, model) do
{:ok, decoded} -> decoded
{:error, reason} -> "[decode failed: #{inspect(reason)}]"
end
end
"Sampled text: #{text}"
end
defp format_result({:error, %Error{} = error}, _model), do: Error.format(error)
defp format_result({:error, other}, _model), do: inspect(other)
defp render_snapshot(snapshot) do
IO.puts("\n=== Metrics Snapshot ===")
IO.puts("Counters:")
snapshot.counters
|> Enum.sort()
|> Enum.each(fn {name, value} ->
IO.puts(" #{name}: #{value}")
end)
IO.puts("\nLatency (ms):")
case Map.get(snapshot.histograms, :tinkex_request_duration_ms) do
nil ->
IO.puts(" no data yet")
hist ->
IO.puts(" count: #{hist.count}")
IO.puts(" mean: #{format_float(hist.mean)}")
IO.puts(" p50: #{format_float(hist.p50)}")
IO.puts(" p95: #{format_float(hist.p95)}")
IO.puts(" p99: #{format_float(hist.p99)}")
end
end
defp format_float(nil), do: "n/a"
defp format_float(value), do: :erlang.float_to_binary(value, decimals: 2)
defp env_integer(var, default) do
case System.get_env(var) do
nil ->
default
value ->
try do
String.to_integer(value)
rescue
_ -> default
end
end
end
defp env_float(var, default) do
case System.get_env(var) do
nil ->
default
value ->
try do
String.to_float(value)
rescue
_ -> default
end
end
end
end
Tinkex.Examples.MetricsLive.run()