@@ -55,8 +55,6 @@ func (t *TokenClassificationOutput) GetOutput() []any {
5555
5656// options
5757
58- // TODO: need to implement the other types of aggregation (max etc)
59-
6058// WithSimpleAggregation sets the aggregation strategy for the token labels to simple
6159// It reproduces simple aggregation from the huggingface implementation.
6260func WithSimpleAggregation () pipelineBackends.PipelineOption [* TokenClassificationPipeline ] {
@@ -65,12 +63,30 @@ func WithSimpleAggregation() pipelineBackends.PipelineOption[*TokenClassificatio
6563 }
6664}
6765
66+ // WithAverageAggregation sets the aggregation strategy for the token labels to average
67+ // It reproduces simple aggregation from the huggingface implementation.
6868func WithAverageAggregation () pipelineBackends.PipelineOption [* TokenClassificationPipeline ] {
6969 return func (pipeline * TokenClassificationPipeline ) {
7070 pipeline .AggregationStrategy = "AVERAGE"
7171 }
7272}
7373
74+ // WithMaxAggregation sets the aggregation strategy for the token labels to average
75+ // It reproduces average aggregation from the huggingface implementation.
76+ func WithMaxAggregation () pipelineBackends.PipelineOption [* TokenClassificationPipeline ] {
77+ return func (pipeline * TokenClassificationPipeline ) {
78+ pipeline .AggregationStrategy = "MAX"
79+ }
80+ }
81+
82+ // WithMaxAggregation sets the aggregation strategy for the token labels to average
83+ // It reproduces average aggregation from the huggingface implementation.
84+ func WithFirstAggregation () pipelineBackends.PipelineOption [* TokenClassificationPipeline ] {
85+ return func (pipeline * TokenClassificationPipeline ) {
86+ pipeline .AggregationStrategy = "FIRST"
87+ }
88+ }
89+
7490// WithoutAggregation returns the token labels.
7591func WithoutAggregation () pipelineBackends.PipelineOption [* TokenClassificationPipeline ] {
7692 return func (pipeline * TokenClassificationPipeline ) {
@@ -86,7 +102,6 @@ func WithIgnoreLabels(ignoreLabels []string) pipelineBackends.PipelineOption[*To
86102
87103// NewTokenClassificationPipeline Initializes a feature extraction pipeline.
88104func NewTokenClassificationPipeline (config pipelineBackends.PipelineConfig [* TokenClassificationPipeline ], s * options.Options , model * pipelineBackends.Model ) (* TokenClassificationPipeline , error ) {
89-
90105 defaultPipeline , err := pipelineBackends .NewBasePipeline (config , s , model )
91106 if err != nil {
92107 return nil , err
@@ -286,13 +301,17 @@ func (p *TokenClassificationPipeline) aggregateWord(entities []Entity) (Entity,
286301 for i , e := range entities {
287302 tokens [i ] = e .TokenID [0 ]
288303 }
289- var newEntity Entity
304+
305+ newEntity := Entity {}
290306
291307 word , err := pipelineBackends .Decode (tokens , p .Model .Tokenizer , true )
292308 if err != nil {
293309 return newEntity , err
294310 }
295311
312+ var score float32
313+ var label string
314+
296315 switch p .AggregationStrategy {
297316 case "AVERAGE" :
298317 scores := make ([][]float32 , len (p .IDLabelMap ))
@@ -305,23 +324,58 @@ func (p *TokenClassificationPipeline) aggregateWord(entities []Entity) (Entity,
305324 for i , s := range scores {
306325 averages [i ] = util .Mean (s )
307326 }
308- entityIdx , score , _ := util .ArgMax (averages )
309- label , ok := p .IDLabelMap [entityIdx ]
327+ entityIdx , maxScore , err := util .ArgMax (averages )
328+ if err != nil {
329+ return newEntity , err
330+ }
331+ entityLabel , ok := p .IDLabelMap [entityIdx ]
310332 if ! ok {
311- return Entity {}, fmt .Errorf ("could not determine entity type for input %s, predicted entity index %d" , word , entityIdx )
333+ return newEntity , fmt .Errorf ("could not determine entity type for input %s, predicted entity index %d" , word , entityIdx )
334+ }
335+ score = maxScore
336+ label = entityLabel
337+ case "MAX" :
338+ var maxScore float32
339+ var maxIdx int
340+ for _ , e := range entities {
341+ idx , score , err := util .ArgMax (e .Scores )
342+ if err != nil {
343+ return newEntity , err
344+ }
345+ if score >= maxScore {
346+ maxScore = score
347+ maxIdx = idx
348+ }
312349 }
313- newEntity = Entity {
314- Entity : label ,
315- Score : score ,
316- Word : word ,
317- TokenID : tokens ,
318- Start : entities [0 ].Start ,
319- End : entities [len (entities )- 1 ].End ,
350+ entityLabel , ok := p .IDLabelMap [maxIdx ]
351+ if ! ok {
352+ return Entity {}, fmt .Errorf ("could not determine entity type for input %s, predicted entity index %d" , word , maxIdx )
320353 }
354+ score = maxScore
355+ label = entityLabel
356+ case "FIRST" :
357+ entityIdx , maxScore , err := util .ArgMax (entities [0 ].Scores )
358+ if err != nil {
359+ return newEntity , err
360+ }
361+ entityLabel , ok := p .IDLabelMap [entityIdx ]
362+ if ! ok {
363+ return Entity {}, fmt .Errorf ("could not determine entity type for input %s, predicted entity index %d" , word , entityIdx )
364+ }
365+ score = maxScore
366+ label = entityLabel
321367 default :
322368 return Entity {}, fmt .Errorf ("aggregation strategy %s not recognized" , p .AggregationStrategy )
323369 }
324- return newEntity , nil
370+
371+ return Entity {
372+ Entity : label ,
373+ Score : score ,
374+ Word : word ,
375+ TokenID : tokens ,
376+ Start : entities [0 ].Start ,
377+ End : entities [len (entities )- 1 ].End ,
378+ }, nil
325379}
326380
327381func (p * TokenClassificationPipeline ) aggregateWords (entities []Entity ) ([]Entity , error ) {
0 commit comments