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

Subsampling for IVF-PQ codebook generation #2052

Merged
merged 25 commits into from
Jan 25, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
00d1ece
Add subsample support for PQ codebook generation. More benchmark needed.
abc99lr Dec 8, 2023
7332a27
Add knob to control the amount of PQ codebook training subsampling.
abc99lr Jan 6, 2024
3153f0e
Fix if-statement dependency issue in parse build parameter.
abc99lr Jan 13, 2024
a03f0af
DOC v24.04 Updates [skip ci]
raydouglass Jan 18, 2024
9165d89
Merge pull request #2100 from rapidsai/branch-24.02
GPUtester Jan 19, 2024
c3b30f3
Merge pull request #2101 from rapidsai/branch-24.02
GPUtester Jan 19, 2024
3790c2a
Merge pull request #2103 from rapidsai/branch-24.02
GPUtester Jan 19, 2024
5464ae7
Merge pull request #2112 from rapidsai/branch-24.02
GPUtester Jan 23, 2024
e9ba740
Merge pull request #2114 from rapidsai/branch-24.02
GPUtester Jan 23, 2024
38d154e
Merge pull request #2115 from rapidsai/branch-24.02
GPUtester Jan 23, 2024
20b0869
Merge branch 'branch-24.02' of https://github.com/rapidsai/raft into …
Jan 23, 2024
c90cdfa
Merge pull request #2116 from rapidsai/branch-24.02
GPUtester Jan 23, 2024
aea3d44
Merge remote-tracking branch 'upstream/branch-24.04' into subsampling…
Jan 23, 2024
fdd4ad2
Revert "Allow topk larger than 1024 in CAGRA (#2097)"
Jan 23, 2024
f8bc4ff
Revert "Revert "Allow topk larger than 1024 in CAGRA (#2097)""
Jan 23, 2024
2856bff
Revert "Merge remote-tracking branch 'upstream/branch-24.04' into sub…
Jan 23, 2024
49112dd
Revert "Merge pull request #2116 from rapidsai/branch-24.02"
Jan 23, 2024
a70a745
Change to max point based subsampling.
Jan 24, 2024
f480c13
Add max_train_points_per_pq_code row in benchmark tuning guide.
abc99lr Jan 24, 2024
c2b2715
Address comments.
abc99lr Jan 24, 2024
9395be8
Merge remote-tracking branch 'upstream/branch-24.02' into subsampling…
abc99lr Jan 24, 2024
aa1a3e5
Run format checker.
abc99lr Jan 24, 2024
cc88715
Fix formatting issue.
abc99lr Jan 24, 2024
67205f9
More format changes.
abc99lr Jan 25, 2024
4352489
Merge remote-tracking branch 'upstream/branch-24.02' into subsampling…
abc99lr Jan 25, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions cpp/bench/ann/src/raft/raft_ann_bench_param_parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ void parse_build_param(const nlohmann::json& conf,
throw std::runtime_error("codebook_kind: '" + kind +
"', should be either 'cluster' or 'subspace'");
}
if (conf.contains("pq_codebook_ratio")) {
param.pq_codebook_trainset_fraction = 1.0 / (double)conf.at("pq_codebook_ratio"); }
}
}

Expand Down
16 changes: 10 additions & 6 deletions cpp/include/raft/neighbors/detail/ivf_pq_build.cuh
Original file line number Diff line number Diff line change
Expand Up @@ -395,14 +395,17 @@ void train_per_subset(raft::resources const& handle,
const float* trainset, // [n_rows, dim]
const uint32_t* labels, // [n_rows]
uint32_t kmeans_n_iters,
double pq_codebook_trainset_fraction,
rmm::mr::device_memory_resource* managed_memory)
{
auto stream = resource::get_cuda_stream(handle);
auto device_memory = resource::get_workspace_resource(handle);

rmm::device_uvector<float> pq_centers_tmp(index.pq_centers().size(), stream, device_memory);
rmm::device_uvector<float> sub_trainset(n_rows * size_t(index.pq_len()), stream, device_memory);
rmm::device_uvector<uint32_t> sub_labels(n_rows, stream, device_memory);
// Subsampling the train set for codebook generation based on pq_codebook_trainset_fraction.
auto pq_n_rows = uint32_t(n_rows * pq_codebook_trainset_fraction);
rmm::device_uvector<float> sub_trainset(pq_n_rows * size_t(index.pq_len()), stream, device_memory);
rmm::device_uvector<uint32_t> sub_labels(pq_n_rows, stream, device_memory);

rmm::device_uvector<uint32_t> pq_cluster_sizes(index.pq_book_size(), stream, device_memory);

Expand All @@ -413,7 +416,7 @@ void train_per_subset(raft::resources const& handle,
// Get the rotated cluster centers for each training vector.
// This will be subtracted from the input vectors afterwards.
utils::copy_selected<float, float, size_t, uint32_t>(
n_rows,
pq_n_rows,
index.pq_len(),
index.centers_rot().data_handle() + index.pq_len() * j,
labels,
Expand All @@ -429,7 +432,7 @@ void train_per_subset(raft::resources const& handle,
true,
false,
index.pq_len(),
n_rows,
pq_n_rows,
index.dim(),
&alpha,
index.rotation_matrix().data_handle() + index.dim() * index.pq_len() * j,
Expand All @@ -443,12 +446,12 @@ void train_per_subset(raft::resources const& handle,

// train PQ codebook for this subspace
auto sub_trainset_view =
raft::make_device_matrix_view<const float, IdxT>(sub_trainset.data(), n_rows, index.pq_len());
raft::make_device_matrix_view<const float, IdxT>(sub_trainset.data(), pq_n_rows, index.pq_len());
auto centers_tmp_view = raft::make_device_matrix_view<float, IdxT>(
pq_centers_tmp.data() + index.pq_book_size() * index.pq_len() * j,
index.pq_book_size(),
index.pq_len());
auto sub_labels_view = raft::make_device_vector_view<uint32_t, IdxT>(sub_labels.data(), n_rows);
auto sub_labels_view = raft::make_device_vector_view<uint32_t, IdxT>(sub_labels.data(), pq_n_rows);
auto cluster_sizes_view =
raft::make_device_vector_view<uint32_t, IdxT>(pq_cluster_sizes.data(), index.pq_book_size());
raft::cluster::kmeans_balanced_params kmeans_params;
Expand Down Expand Up @@ -1858,6 +1861,7 @@ auto build(raft::resources const& handle,
trainset.data(),
labels.data(),
params.kmeans_n_iters,
params.pq_codebook_trainset_fraction,
&managed_memory_upstream);
break;
case codebook_gen::PER_CLUSTER:
abc99lr marked this conversation as resolved.
Show resolved Hide resolved
Expand Down
6 changes: 6 additions & 0 deletions cpp/include/raft/neighbors/ivf_pq_types.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,12 @@ struct index_params : ann::index_params {
* flag to `true` if you prefer to use as little GPU memory for the database as possible.
*/
bool conservative_memory_allocation = false;
/**
* The fraction of data to use during PQ codebook generation on top of the subsampled data
* controlled by kmeans_trainset_fraction. The parameter is only used when PQ codebook generation
* kind is PER_SUBSPACE and ignored when PQ codebook generation kind is PER_CLUSTER.
*/
double pq_codebook_trainset_fraction = 1;
abc99lr marked this conversation as resolved.
Show resolved Hide resolved
};

struct search_params : ann::search_params {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,8 @@ cdef extern from "raft/neighbors/ivf_pq_types.hpp" \
codebook_gen codebook_kind
bool force_random_rotation
bool conservative_memory_allocation

double pq_codebook_trainset_fraction

cdef cppclass index[IdxT](ann_index):
index(const device_resources& handle,
DistanceType metric,
Expand Down
15 changes: 14 additions & 1 deletion python/pylibraft/pylibraft/neighbors/ivf_pq/ivf_pq.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,13 @@ cdef class IndexParams:
repeated calls to `extend` (extending the database).
To disable this behavior and use as little GPU memory for the
database as possible, set this flat to `True`.
pq_codebook_trainset_fraction : int, default = 0.5
If pq_codebook_trainset_fraction is less than 1, then the dataset is
subsampled for PQ codebook generation, and only n_samples *
pq_codebook_trainset_fraction rows are used for PQ codebook generation.
This subsampling is applied after kmeans_trainset subsampling,
controlled by kmeans_trainset_fraction and only used when codebook_kind
is PER_SUBSPACE.
"""
def __init__(self, *,
n_lists=1024,
Expand All @@ -167,7 +174,8 @@ cdef class IndexParams:
codebook_kind="subspace",
force_random_rotation=False,
add_data_on_build=True,
conservative_memory_allocation=False):
conservative_memory_allocation=False,
pq_codebook_trainset_fraction=0.5):
self.params.n_lists = n_lists
self.params.metric = _get_metric(metric)
self.params.metric_arg = 0
Expand All @@ -185,6 +193,8 @@ cdef class IndexParams:
self.params.add_data_on_build = add_data_on_build
self.params.conservative_memory_allocation = \
conservative_memory_allocation
self.params.pq_codebook_trainset_fraction = \
pq_codebook_trainset_fraction

@property
def n_lists(self):
Expand Down Expand Up @@ -226,6 +236,9 @@ cdef class IndexParams:
def conservative_memory_allocation(self):
return self.params.conservative_memory_allocation

@property
def pq_codebook_trainset_fraction(self):
return self.params.pq_codebook_trainset_fraction

cdef class Index:
# We store a pointer to the index because it dose not have a trivial
Expand Down