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

[OPIK-415] Compute traces cost based on token usage #703

Conversation

BorisTkachenko
Copy link
Contributor

Details

Computes trace cost based on token usage

Resolves #OPIK-415

Testing

Added integration tests

Documentation

https://www.notion.so/cometml/Opik-Span-Cost-tracking-13c7124010a380a7ad36ced128a26dc7

@BorisTkachenko BorisTkachenko self-assigned this Nov 22, 2024
@BorisTkachenko BorisTkachenko requested a review from a team as a code owner November 22, 2024 17:00
@BorisTkachenko BorisTkachenko force-pushed the boryst/OPIK-415-tracing-compute-traces-cost-based-on-token-usage branch from 00b21ea to dd0b37f Compare November 22, 2024 17:01
@@ -581,7 +581,7 @@ AND id in (
""";

private static final String ESTIMATED_COST_VERSION = "1.0";
private static final BigDecimal ZERO_COST = new BigDecimal("0.00000000");
public static final BigDecimal ZERO_COST = new BigDecimal("0.00000000");
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
public static final BigDecimal ZERO_COST = new BigDecimal("0.00000000");
public static final BigDecimal ZERO_COST = new BigDecimal.ZERO;

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Updated

@@ -747,6 +753,9 @@ private Publisher<Trace> mapToDto(Result result) {
.filter(it -> !it.isEmpty())
.orElse(null))
.usage(row.get("usage", Map.class))
.totalEstimatedCost(row.get("total_estimated_cost", BigDecimal.class).equals(ZERO_COST)
Copy link
Contributor

Choose a reason for hiding this comment

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

We probably should use compareTo

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, now it's a must, since we changed to BigDecimal.ZERO.
equals works only for the same precision comparison and is not robust. Good catch.

@BorisTkachenko BorisTkachenko force-pushed the boryst/OPIK-415-tracing-compute-traces-cost-based-on-token-usage branch 3 times, most recently from d8a8ec8 to 2be4465 Compare November 25, 2024 14:34
@@ -581,7 +581,7 @@ AND id in (
""";

private static final String ESTIMATED_COST_VERSION = "1.0";
private static final BigDecimal ZERO_COST = new BigDecimal("0.00000000");
public static final BigDecimal ZERO_COST = BigDecimal.ZERO;
Copy link
Contributor

Choose a reason for hiding this comment

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

No need for this constant just use the one from BigDecimal

Copy link
Contributor Author

Choose a reason for hiding this comment

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

updated

.toBuilder()
.id(null)
.projectName(projectName)
.usage(Map.of("completion_tokens", 200 * 5L, "prompt_tokens", 300 * 5L, "total_tokens", 4 * 5L))
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we generate random values to make the test more robust?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No we can't. It should be related to spans to assert and also usage keys should be specific for cost calculation and can't be random.

Copy link
Contributor

@thiagohora thiagohora Nov 25, 2024

Choose a reason for hiding this comment

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

I mean something like this:

Spans

.usage(Map.of("completion_tokens", factory. manufacturePojo(Integer.class), "prompt_tokens", factory. manufacturePojo(Integer.class), "total_tokens",  factory. manufacturePojo(Integer.class)))

Then, in the traces, we just group by usage name and calculate the avg expected

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I updated per your request. But could you please explain how hardcoded usage values might introduce flakiness?

@BorisTkachenko BorisTkachenko force-pushed the boryst/OPIK-415-tracing-compute-traces-cost-based-on-token-usage branch from 2be4465 to 9215e66 Compare November 25, 2024 15:19
@BorisTkachenko BorisTkachenko force-pushed the boryst/OPIK-415-tracing-compute-traces-cost-based-on-token-usage branch from 9215e66 to 6a2f37b Compare November 25, 2024 16:33
@BorisTkachenko BorisTkachenko force-pushed the boryst/OPIK-415-tracing-compute-traces-cost-based-on-token-usage branch from 6a2f37b to 2ea154e Compare November 26, 2024 08:10
@BorisTkachenko BorisTkachenko merged commit 1d68993 into main Nov 26, 2024
7 checks passed
@BorisTkachenko BorisTkachenko deleted the boryst/OPIK-415-tracing-compute-traces-cost-based-on-token-usage branch November 26, 2024 08:16
Comment on lines +3264 to +3267
assertThat(traceExpectedCost.compareTo(BigDecimal.ZERO) == 0 ?
createdTrace.totalEstimatedCost() == null :
traceExpectedCost.compareTo(createdTrace.totalEstimatedCost()) == 0)
.isEqualTo(true);
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
assertThat(traceExpectedCost.compareTo(BigDecimal.ZERO) == 0 ?
createdTrace.totalEstimatedCost() == null :
traceExpectedCost.compareTo(createdTrace.totalEstimatedCost()) == 0)
.isEqualTo(true);
var actual = createdTrace.totalEstimatedCost();
traceExpectedCost = traceExpectedCost.compareTo(BigDecimal.ZERO) == 0 ? null : traceExpectedCost;
assertThat(actual)
.usingRecursiveComparison(RecursiveComparisonConfiguration.builder()
.withComparatorForType(BigDecimal::compareTo, BigDecimal.class)
.build())
.isEqualTo(traceExpectedCost);

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