RecTools icon indicating copy to clipboard operation
RecTools copied to clipboard

recommend() method for ImplicitALSWrapperModel

Open Waujito opened this issue 1 year ago • 5 comments

Your Question

Hello! I see that here is no usage of ImplicitALSWrapperModel's recommend() method. I see that rectools' recommend() fallbacks to something underlying called ImplicitRanker with custom implementation by RecTools. I wonder why is this behaviour used instead of the native implicit's recommend(). Also this implementation works a way longer than implicit's.

Operating System

No response

Python Version

No response

RecTools version

No response

Waujito avatar Oct 30 '24 01:10 Waujito

Hi! ImplicitRanker uses exactly the same method for scoring items as in implicit library, we are calling it directly: https://github.com/MobileTeleSystems/RecTools/blob/0be5e1592e06022109faf1d446c7aee82fbd9dfb/rectools/models/rank.py#L194

In implicit framework recommend just returns the results directly without any processing. Items in recommendations can still include already-seen items and repeated items. They will get neginf scores, but they are still present.

In our wrapper we process those results, apply filtering based on scores here: https://github.com/MobileTeleSystems/RecTools/blob/0be5e1592e06022109faf1d446c7aee82fbd9dfb/rectools/models/rank.py#L106 And after that we convert results to pandas.

So this is why our recommend is slower: we do some post-processing.

blondered avatar Oct 30 '24 12:10 blondered

If the difference in speed is extraordinary then please check your version of rectools package. You might be using older version where we didn't use ImplicitRanker

blondered avatar Oct 30 '24 12:10 blondered

Yes, thank you. I see it works the same way and the speed should be the same. My speed problem(10 s vs 5 min for context) was because the RecTools' ImplicitRanker implementation does not use the GPU. I was able to run predictions on the GPU with the patch:

--- a/rank.py 2024-10-30 16:03:51.376808529 +0300
+++ b/rank.py     2024-10-30 16:07:06.556808606 +0300
@@ -18,6 +18,7 @@
 from enum import Enum
 
 import implicit.cpu
+import implicit.gpu
 import numpy as np
 from implicit.cpu.matrix_factorization_base import _filter_items_from_sparse_matrix as filter_items_from_sparse_matrix
 from scipy import sparse
@@ -191,14 +192,22 @@
 
         real_k = min(k, object_factors.shape[0])
 
-        ids, scores = implicit.cpu.topk.topk(  # pylint: disable=c-extension-no-member
-            items=object_factors,
-            query=subject_factors,
-            k=real_k,
+        object_factors = implicit.gpu.Matrix(object_factors)
+        subject_factors = implicit.gpu.Matrix(subject_factors)
+        if object_norms is not None:
+            object_norms = implicit.gpu.Matrix(object_norms)
+        if filter_query_items is not None:
+            filter_query_items = implicit.gpu.COOMatrix(filter_query_items.tocoo())
+
+
+        ids, scores = implicit.gpu.KnnQuery().topk(  # pylint: disable=c-extension-no-member
+            object_factors,
+            subject_factors,
+            real_k,
             item_norms=object_norms,  # query norms for COSINE distance are applied afterwards
-            filter_query_items=filter_query_items,  # queries x objects csr matrix for getting neginf scores
-            filter_items=None,  # rectools doesn't support blacklist for now
-            num_threads=num_threads,
+            query_filter=filter_query_items,  # queries x objects csr matrix for getting neginf scores
+            item_filter=None,  # rectools doesn't support blacklist for now
+            # num_threads=num_threads,
         )
 
         if sorted_object_whitelist is not None:

Waujito avatar Oct 30 '24 13:10 Waujito

@Waujito Thank you for sharing. It would be nice to have it out of the box so I've added this to our backlog. If you feel like contributing - it would also be great. Please let me know :)

blondered avatar Oct 30 '24 14:10 blondered

Yeah, I want to try to propose a draft implementation of this.

Waujito avatar Oct 30 '24 14:10 Waujito

That's great. In case of any questions the fastest way for a reply is in our Telegram channel https://t.me/RecTools_Support

blondered avatar Oct 31 '24 11:10 blondered

Hi! @Waujito we're still working on gpu support for all models. Found another thing: gpu ranking scores may significantly differ from cpu ranking scores in some cases. This is especially true for PureSVDModel. We are still researching the cause so decided to add models support for use_gpu in ImplicitRanker to the next release, not the current one. We hope will be quite soon.

blondered avatar Dec 11 '24 15:12 blondered