sugarme / gotch

Go binding for Pytorch C++ API (libtorch)

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Q) Is there a function or method to clear the cached memory?

luxiant opened this issue · comments

Here I'm trying to run this function.

// channel function
func splittedDfProcess(dataframe dataframe.DataFrame, useModels customModel, c chan<- []sentimentRow) {
	var results []sentimentRow
	bar := progressbar.Default(int64(len(dataframe.Col("text").Records())))
	for i := 0; i < dataframe.Nrow(); i++ {
		index := series.Indexes([]int{i})
		row := dataframe.Subset(index)
		result := bertSentimentProcess(row, useModels)
		results = append(results, result)
		bar.Add(1)
	}
	c <- results
}

func bertSentimentProcess(dataframe dataframe.DataFrame, useModels customModel) sentimentRow {
	corpus := dataframe.Col("text").Records()[0]
	preprocessedCorpus := preprocessSentence(corpus)
	newSequence := tokenizer.NewInputSequence(preprocessedCorpus)
	encodeInput := tokenizer.NewSingleEncodeInput(newSequence)
	encodeCorpus, _ := useModels.tokenizer.Encode(encodeInput, true)

        // fit all encoding length into 128
	maxLength := 128
	ps := tokenizer.NewPaddingStrategy(tokenizer.WithFixed(maxLength))
	paddingParameter := tokenizer.PaddingParams{Strategy: *ps, Direction: 1, PadId: 1, PadTypeId: 0, PadToken: "[PAD]"}
	var finalEncode tokenizer.Encoding
	switch {
	case encodeCorpus.Len() > maxLength:
		truncatedEncode, _ := encodeCorpus.Truncate(maxLength, 2)
		finalEncode = *truncatedEncode
	case encodeCorpus.Len() < maxLength:
		var corpusConverted []tokenizer.Encoding
		corpusConverted = append(corpusConverted, *encodeCorpus)
		encodeList := tokenizer.PadEncodings(corpusConverted, paddingParameter)
		finalEncode = encodeList[0]
	default:
		finalEncode = *encodeCorpus
	}
	var tokInput []int64 = make([]int64, maxLength)
	for i := 0; i < len(finalEncode.Ids); i++ {
		tokInput[i] = int64(finalEncode.Ids[i])
	}

        // convert into input tensor and forward
	var idTurnIntoTensor []ts.Tensor
	idTurnIntoTensor = append(idTurnIntoTensor, *ts.TensorFrom(tokInput))
	idInputTensor := ts.MustStack(idTurnIntoTensor, 0).MustTo(gotch.CPU, true)
	var torchResult *ts.Tensor
	ts.NoGrad(func() {
		torchResult, _, _ = useModels.bertModel.ForwardT(idInputTensor, ts.None, ts.None, ts.None, ts.None, false)
	})

        // clone the torchResult (for memory saving?)
	torchResultCopy := torchResult.MustShallowClone()

        // get softmax value of each label
	categoryProb := torchResultCopy.MustSoftmax(-1, gotch.Float, true)
	var long, neutral, short float64
	var sentiment string
	probs := categoryProb.Float64Values()
	long = probs[0]
	neutral = probs[1]
	short = probs[2]
	if long > neutral && long > short {
		sentiment = "long"
	} else if neutral > long && neutral > short {
		sentiment = "neutral"
	} else {
		sentiment = "short"
	}
	return sentimentRow{
		post_num:  dataframe.Col("post_num").Records()[0],
		time:      dataframe.Col("time").Records()[0],
		text:      dataframe.Col("text").Records()[0],
		long:      long,
		neutral:   neutral,
		short:     short,
		sentiment: sentiment,
	}
}
...

I'm running my code in CPU in codespace with 32GB of RAM. This function kills the process because of out of memory. I tried to find a way to reduce memory consumption, especially emptying the cached memory after process of every iteration. I'm also considering another way, based on my experience in python that .eval() in pytorch helps reducing memory consumption. I have found that 'MustDrop()' in ts package drops the tensor, but I'm not sure that it will work. Am I in a right approach?

My bad. This space is where I should not post this kind of thing. I'll move this post to discuss section.