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

Improve multi-CTA algorithm #492

Open
wants to merge 10 commits into
base: branch-25.02
Choose a base branch
from

Conversation

anaruse
Copy link
Contributor

@anaruse anaruse commented Nov 25, 2024

It has been reported that when the number of search results is large, for example 100, using the multi-CTA algorithm can cause a decrease in recall. This PR is intended to alleviate this low recall issue.

close #208

@anaruse anaruse requested a review from a team as a code owner November 25, 2024 10:46
Copy link

copy-pr-bot bot commented Nov 25, 2024

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@github-actions github-actions bot added the cpp label Nov 25, 2024
@tfeher tfeher added improvement Improves an existing functionality non-breaking Introduces a non-breaking change labels Nov 25, 2024
@cjnolet
Copy link
Member

cjnolet commented Dec 3, 2024

/ok to test

Copy link
Contributor

@tfeher tfeher left a comment

Choose a reason for hiding this comment

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

Thanks @anaruse for this PR, it is great to see these improvements. Overall the changes look good, and the benchmarks that you have shared offline look very encouraging. I just have a few questions below.

@tfeher
Copy link
Contributor

tfeher commented Dec 5, 2024

@anaruse there are some unsigned commits, that blocks CI from testing the changes automatically. To fix this issue, could you rebase the PR?

@cjnolet
Copy link
Member

cjnolet commented Dec 5, 2024

/ok to test

…when the number of results is large

Fix some issues

Fix lower recall issue with new multi-cta algo

Removing redundant code and changing some parameters

Update cpp/src/neighbors/detail/cagra/search_plan.cuh

Co-authored-by: Tamas Bela Feher <tfeher@nvidia.com>

Remove an unnecessary line and satisfy clang-format
@anaruse anaruse force-pushed the improved_multi_cta_algo branch from 3dce160 to 6223fd2 Compare December 5, 2024 06:58
Copy link
Contributor

@tfeher tfeher left a comment

Choose a reason for hiding this comment

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

Thanks Akira for the updates, the PR looks good to me.

@cjnolet
Copy link
Member

cjnolet commented Dec 5, 2024

/merge

@cjnolet
Copy link
Member

cjnolet commented Dec 5, 2024

/ok to test

@tfeher
Copy link
Contributor

tfeher commented Dec 5, 2024

/ok to test

@cjnolet
Copy link
Member

cjnolet commented Dec 5, 2024

/merge

@cjnolet
Copy link
Member

cjnolet commented Dec 5, 2024

/ok to test

@cjnolet
Copy link
Member

cjnolet commented Dec 5, 2024

/merge

@cjnolet
Copy link
Member

cjnolet commented Dec 5, 2024

We are on the brink of missing code freeze for this PR. Please anyone reading this, don't click the "update" button. It inserts a merge commit, which reruns CI in its entirety and this is not needed to merge the PR. We can re-run individual flaky tests that fail without having to rerun the entire CI (the former takes minutes and the latter can take several hours).

@cjnolet
Copy link
Member

cjnolet commented Dec 6, 2024

@anaruse @tfeher CI seems to be running successfully for other PRs but the gtests seem to be consistently timing out for this PR. As far as I can tell, there's no updates to any of the tests, in this PR, but the timeouts don't seem flaky, they seem isolated to these changes, somehow.

We are pushing back code freeze by 1 day. Do you guys think we can still make this in time for 24.12?

@achirkin achirkin changed the base branch from branch-24.12 to branch-25.02 December 9, 2024 09:55
Handle the case when the search result contains invalid indices when building the updated graph in add_nodes.
For debugging purposes, fail if any invalid indices found; in future, we can replace RAFT_FAIL with RAFT_LOG_WARN to make the add_nodes routine more robust.
@achirkin
Copy link
Contributor

achirkin commented Dec 9, 2024

I took the liberty to add a workaround to add_nodes, which handles the case when CAGRA search doesn't return enough valid indices. With this, the tests should fail with a descriptive message in place of the segfault.
When we find the source of the bug, we can relax the RAFT_FAIL with RAFT_LOG_WARN.

@achirkin
Copy link
Contributor

achirkin commented Dec 9, 2024

/ok to test

@anaruse
Copy link
Contributor Author

anaruse commented Dec 10, 2024

The cause has not yet been identified, but it seems that this problem only occurs when the dimensionality of the dataset is 1.

@anaruse
Copy link
Contributor Author

anaruse commented Dec 23, 2024

The problem of invalid results being included in the search results when the number of dimensions in the data set is small has been improved in the case of the new multi-CTA algorithm.
As a result of the checks that @achirkin added to add_nodes, it was found that even in the case of single-CTA or multi-Kernel algo, if the dimensionality of the dataset is small, for example 1, the search results may include invalid results. Even if some of the search results are invalid, it is possible to execute add_nodes without error, so I have made the necessary changes to add_nodes.

@anaruse
Copy link
Contributor Author

anaruse commented Dec 23, 2024

If the search results for add_nodes include invalid results, a message is output using RAFT_LOG_WARN, and if there are too many invalid results to execute add_nodes without error, it is terminated using RAFT_FAIL.

@anaruse
Copy link
Contributor Author

anaruse commented Dec 23, 2024

@enp1s0 , Could you please check the changes I made to add_nodes?

Copy link
Member

@enp1s0 enp1s0 left a comment

Choose a reason for hiding this comment

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

@anaruse Thank you for adding invalid node handling to the node addition function. I have a minor comment, but the changes look good to me.

@@ -136,9 +153,13 @@ void add_node_core(
for (std::uint32_t i = 0; i < base_degree; i++) {
std::uint32_t detourable_node_count = 0;
const auto a_id = host_neighbor_indices(vec_i, i);
if (a_id >= idx.size()) {
detourable_node_count_list[i] = std::make_pair(a_id, base_degree + 1);
Copy link
Member

Choose a reason for hiding this comment

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

It would be good to write a comment about this process, e.g., in what case this conditional branch becomes true and why the detourable node count is set to base_degree + 1.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks, I've added the comments.

Copy link
Contributor

@achirkin achirkin left a comment

Choose a reason for hiding this comment

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

I think the error in add_nodes is not observed prior to this PR (without the safeguard RAFT_FAIL, the tests segfault in this PR, but not in the main branch). This leads me to believe that the problem in the search may be related (either introduced or just surfaced) by the new changes.
In any case, I don't see a reason why the cagra search algorithms have to return invalid values under the small dimensionality condition, and thus I believe we should fix the search rather throwing the error at the use-site. Where you able to pinpoint why the search returns the invalid values in the small dimensionality cases?

Comment on lines 136 to 142
RAFT_LOG_WARN(
"Invalid edges found in search results "
"(vec_i:%lu, invalid_edges:%lu, degree:%lu, base_degree:%lu)",
(uint64_t)vec_i,
(uint64_t)invalid_edges,
(uint64_t)degree,
(uint64_t)base_degree);
Copy link
Contributor

Choose a reason for hiding this comment

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

I believe it's good to have this check here, but I'm afraid it could be a bit too much when printed in the loop. Could you please add some sort of internal counter to prevent it spitting out too many lines (let say, no more than ten messages)?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks. It is undesirable to have lots of warnings output. Changed to limit the number of warnings output to 3.

@anaruse
Copy link
Contributor Author

anaruse commented Dec 23, 2024

It is not easy to explain why the new multi-CTA algo sometimes produces invalid search results, but it is mainly because it allows multiple CTAs to use the same node as a search path, and it allows multiple CTAs to have the same node in their local itopk buffer. If the number of dimensions is small, the paths to reach the query are rather limited, so it is likely that many nodes will be in the local itopk buffers of multiple CTAs at the same time. Even the, duplications are eventually removed using hash tables, but the result of that de-duplication is that the specified number of valid results may not be output.

So far, we know that the problem only occurs when the dimensionality of the dataset is 1. And a dataset with dimension 1 is not originally a target for vector search. Although not ideal, one way to deal with this is to stop testing on datasets with a dimension of 1.

@anaruse anaruse force-pushed the improved_multi_cta_algo branch from 5a3519a to b61126a Compare December 25, 2024 09:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cpp improvement Improves an existing functionality non-breaking Introduces a non-breaking change
Projects
Status: In Progress
Development

Successfully merging this pull request may close these issues.

[BUG] Decreasing recall when increasing threads in ANN benchmark
5 participants