From e3eac03d40f82a33048e7f18befa242e70797278 Mon Sep 17 00:00:00 2001 From: envolution Date: Sat, 30 Nov 2024 14:50:22 -0500 Subject: [PATCH 1/8] remove backend as per #13701 --- spacy/ml/parser_model.pyx | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/spacy/ml/parser_model.pyx b/spacy/ml/parser_model.pyx index f004c562e7d..d5c660e67c1 100644 --- a/spacy/ml/parser_model.pyx +++ b/spacy/ml/parser_model.pyx @@ -5,7 +5,6 @@ from libc.math cimport exp from libc.stdlib cimport calloc, free, realloc from libc.string cimport memcpy, memset from thinc.backends.cblas cimport saxpy, sgemm -from thinc.backends.linalg cimport Vec, VecVec import numpy import numpy.random @@ -116,14 +115,10 @@ cdef void predict_states( n.hiddens * n.pieces ) for i in range(n.states): - VecVec.add_i( - &A.unmaxed[i*n.hiddens*n.pieces], - W.feat_bias, 1., - n.hiddens * n.pieces - ) + saxpy(cblas)(n.hiddens * n.pieces, 1., W.feat_bias, 1, &A.unmaxed[i*n.hiddens*n.pieces], 1) for j in range(n.hiddens): index = i * n.hiddens * n.pieces + j * n.pieces - which = Vec.arg_max(&A.unmaxed[index], n.pieces) + which = _arg_max(&A.unmaxed[index], n.pieces) A.hiddens[i*n.hiddens + j] = A.unmaxed[index + which] memset(A.scores, 0, n.states * n.classes * sizeof(float)) if W.hidden_weights == NULL: @@ -138,7 +133,7 @@ cdef void predict_states( ) # Add bias for i in range(n.states): - VecVec.add_i(&A.scores[i*n.classes], W.hidden_bias, 1., n.classes) + saxpy(cblas)(n.classes, 1., W.hidden_bias, 1, &scores[i*n.classes], 1) # Set unseen classes to minimum value i = 0 min_ = A.scores[0] @@ -187,7 +182,7 @@ cdef void cpu_log_loss( """Do multi-label log loss""" cdef double max_, gmax, Z, gZ best = arg_max_if_gold(scores, costs, is_valid, O) - guess = Vec.arg_max(scores, O) + guess = _arg_max(scores, O) if best == -1 or guess == -1: # These shouldn't happen, but if they do, we want to make sure we don't # cause an OOB access. From f1ed3152495b99564424ff13776282a85c54c462 Mon Sep 17 00:00:00 2001 From: envolution Date: Sat, 30 Nov 2024 14:57:57 -0500 Subject: [PATCH 2/8] add inline _arg_max --- spacy/ml/parser_model.pyx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/spacy/ml/parser_model.pyx b/spacy/ml/parser_model.pyx index d5c660e67c1..7375375a7fc 100644 --- a/spacy/ml/parser_model.pyx +++ b/spacy/ml/parser_model.pyx @@ -526,3 +526,5 @@ cdef class precompute_hiddens: return d_best.reshape((d_best.shape + (1,))) return state_vector, backprop_relu + +cdef inline int _arg_max(const float* scores, const int n_classes) nogil: From e67cf1a5a548e18d98297981551100c1663bf7eb Mon Sep 17 00:00:00 2001 From: envolution Date: Sat, 30 Nov 2024 15:16:43 -0500 Subject: [PATCH 3/8] fix paste error --- spacy/ml/parser_model.pyx | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/spacy/ml/parser_model.pyx b/spacy/ml/parser_model.pyx index 7375375a7fc..8698fc5b6a5 100644 --- a/spacy/ml/parser_model.pyx +++ b/spacy/ml/parser_model.pyx @@ -527,4 +527,14 @@ cdef class precompute_hiddens: return state_vector, backprop_relu -cdef inline int _arg_max(const float* scores, const int n_classes) nogil: + cdef inline int _arg_max(const float* scores, const int n_classes) nogil: + if n_classes == 2: + return 0 if scores[0] > scores[1] else 1 + cdef int i + cdef int best = 0 + cdef float mode = scores[0] + for i in range(1, n_classes): + if scores[i] > mode: + mode = scores[i] + best = i + return best From 7ef234659810a8c18c0f3fc60e957b40b4cd5c35 Mon Sep 17 00:00:00 2001 From: envolution Date: Sat, 30 Nov 2024 15:23:31 -0500 Subject: [PATCH 4/8] try fix gil require issue --- spacy/ml/parser_model.pyx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/spacy/ml/parser_model.pyx b/spacy/ml/parser_model.pyx index 8698fc5b6a5..6a3aae91589 100644 --- a/spacy/ml/parser_model.pyx +++ b/spacy/ml/parser_model.pyx @@ -527,7 +527,7 @@ cdef class precompute_hiddens: return state_vector, backprop_relu - cdef inline int _arg_max(const float* scores, const int n_classes) nogil: + cdef inline int _arg_max(float[:] scores, const int n_classes) nogil: if n_classes == 2: return 0 if scores[0] > scores[1] else 1 cdef int i @@ -537,4 +537,5 @@ cdef class precompute_hiddens: if scores[i] > mode: mode = scores[i] best = i - return best + return best + From 93c95ab8e51aa553f58d66770d504a7a5fc985ff Mon Sep 17 00:00:00 2001 From: envolution Date: Sat, 30 Nov 2024 15:29:32 -0500 Subject: [PATCH 5/8] try w/ gil --- spacy/ml/parser_model.pyx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/spacy/ml/parser_model.pyx b/spacy/ml/parser_model.pyx index 6a3aae91589..e6ce4837522 100644 --- a/spacy/ml/parser_model.pyx +++ b/spacy/ml/parser_model.pyx @@ -527,7 +527,7 @@ cdef class precompute_hiddens: return state_vector, backprop_relu - cdef inline int _arg_max(float[:] scores, const int n_classes) nogil: + cdef inline int _arg_max(float[:] scores, const int n_classes): if n_classes == 2: return 0 if scores[0] > scores[1] else 1 cdef int i @@ -539,3 +539,4 @@ cdef class precompute_hiddens: best = i return best + From 2531ed95750627ae857632cca778d46bd9dbb3bd Mon Sep 17 00:00:00 2001 From: envolution Date: Sat, 30 Nov 2024 15:56:01 -0500 Subject: [PATCH 6/8] testing --- spacy/ml/parser_model.pyx | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/spacy/ml/parser_model.pyx b/spacy/ml/parser_model.pyx index e6ce4837522..5d5b5eaf9b2 100644 --- a/spacy/ml/parser_model.pyx +++ b/spacy/ml/parser_model.pyx @@ -227,6 +227,17 @@ cdef int arg_max_if_valid(const weight_t* scores, const int* is_valid, int n) no best = i return best +cdef inline int _arg_max(float[:] scores, const int n_classes) nogil: + if n_classes == 2: + return 0 if scores[0] > scores[1] else 1 + cdef int i + cdef int best = 0 + cdef float mode = scores[0] + for i in range(1, n_classes): + if scores[i] > mode: + mode = scores[i] + best = i + return best class ParserStepModel(Model): def __init__( @@ -527,16 +538,5 @@ cdef class precompute_hiddens: return state_vector, backprop_relu - cdef inline int _arg_max(float[:] scores, const int n_classes): - if n_classes == 2: - return 0 if scores[0] > scores[1] else 1 - cdef int i - cdef int best = 0 - cdef float mode = scores[0] - for i in range(1, n_classes): - if scores[i] > mode: - mode = scores[i] - best = i - return best From afaf41f79425cb61a6f964dfc79c07555d118d88 Mon Sep 17 00:00:00 2001 From: envolution Date: Sat, 30 Nov 2024 16:08:45 -0500 Subject: [PATCH 7/8] move new function out of class --- spacy/ml/parser_model.pyx | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/spacy/ml/parser_model.pyx b/spacy/ml/parser_model.pyx index 5d5b5eaf9b2..8bb1ad4a633 100644 --- a/spacy/ml/parser_model.pyx +++ b/spacy/ml/parser_model.pyx @@ -227,16 +227,16 @@ cdef int arg_max_if_valid(const weight_t* scores, const int* is_valid, int n) no best = i return best -cdef inline int _arg_max(float[:] scores, const int n_classes) nogil: - if n_classes == 2: - return 0 if scores[0] > scores[1] else 1 +cdef int _arg_max(const float* scores, const int n_classes) nogil: cdef int i cdef int best = 0 cdef float mode = scores[0] + for i in range(1, n_classes): if scores[i] > mode: mode = scores[i] best = i + return best class ParserStepModel(Model): @@ -538,5 +538,3 @@ cdef class precompute_hiddens: return state_vector, backprop_relu - - From 3dadad8d557b0f3b913fef29a90e22e330aeb67d Mon Sep 17 00:00:00 2001 From: envolution Date: Sat, 30 Nov 2024 16:12:11 -0500 Subject: [PATCH 8/8] use proper c-array --- spacy/ml/parser_model.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spacy/ml/parser_model.pyx b/spacy/ml/parser_model.pyx index 8bb1ad4a633..5231db1667c 100644 --- a/spacy/ml/parser_model.pyx +++ b/spacy/ml/parser_model.pyx @@ -133,7 +133,7 @@ cdef void predict_states( ) # Add bias for i in range(n.states): - saxpy(cblas)(n.classes, 1., W.hidden_bias, 1, &scores[i*n.classes], 1) + saxpy(cblas)(n.classes, 1., W.hidden_bias, 1, &A.scores[i*n.classes], 1) # Set unseen classes to minimum value i = 0 min_ = A.scores[0]