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

Segment fault issue!? #2147

Open
HieuDevs opened this issue May 14, 2024 · 3 comments
Open

Segment fault issue!? #2147

HieuDevs opened this issue May 14, 2024 · 3 comments

Comments

@HieuDevs
Copy link

HieuDevs commented May 14, 2024

I have implemented TTS for my application, everything is fine when sending one request at a time, but when running multiple requests simultaneously, I encounter a signal: segmentation fault error, and here is my code.

model, err := whisper.New(flags.GetModel())
if err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}
	http.HandleFunc("/whisper", func(w http.ResponseWriter, r *http.Request) {
		if r.Method == http.MethodPost {
			file, handler, err := r.FormFile("file")
			if err != nil {
				http.Error(w, err.Error(), http.StatusBadRequest)
				return
			}
			defer file.Close()
			result := make(chan map[string]interface{})
			go func() {

				defer model.Close()
				data, err := controller.Process(model, file, handler.Filename, false, flags)
				if err != nil {
					http.Error(w, err.Error(), http.StatusInternalServerError)
					return
				}
				result <- data
			}()
			//Send result to client
			w.WriteHeader(http.StatusOK)
			w.Header().Set("Content-Type", "application/json")
			if err := json.NewEncoder(w).Encode(<-result); err != nil {
				http.Error(w, "Error encoding JSON", http.StatusInternalServerError)
			}
		} else {
			http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
		}
	})
func Process(
	model whisper.Model,
	file multipart.File,
	fileName string,
	isTokenlizer bool,
	flags *Flags,
) (map[string]interface{}, error) {
	var data []float32
	context, err := model.NewContext()
	if err != nil {
		return nil, err
	}
	if err := flags.SetParams(context); err != nil {
		return nil, err
	}
	if strings.HasSuffix(fileName, ".wav") {
		dec := wav.NewDecoder(file)
		if buf, err := dec.FullPCMBuffer(); err != nil {
			return nil, err
		} else {
			fmt.Println("Resampling")
			data = resampler.SimpleResample(buf, whisper.SampleRate)
		}
	} else {
		return nil, errors.New("unsupported file format")
	}
	if err := context.Process(data, nil, nil); err != nil {
		return nil, errors.New("failed to process data")
	}
	segments := []map[string]interface{}{}
	if isTokenlizer {
		for {
			segment, err := context.NextSegment()
			if err != nil {
				break
			}
			tokens := []map[string]interface{}{}
			for _, token := range segment.Tokens {
				tokens = append(tokens, map[string]interface{}{
					"start": token.Start / 1000,
					"end":   token.End / 1000,
					"text":  token.Text,
				})
			}
			segments = append(segments, map[string]interface{}{
				"start":  segment.Start / 1000,
				"end":    segment.End / 1000,
				"text":   segment.Text,
				"tokens": tokens,
			})
		}
	} else {
		for {
			segment, err := context.NextSegment()
			if err != nil {
				break
			}
			segments = append(segments, map[string]interface{}{
				"start": segment.Start / 1000,
				"end":   segment.End / 1000,
				"text":  segment.Text,
			})
		}
	}

	return map[string]interface{}{
		"segments": segments,
	}, nil
}
@magnacartatron
Copy link

What does this have to do with whisper.cpp?

@HieuDevs
Copy link
Author

HieuDevs commented May 14, 2024

What does this have to do with whisper.cpp?

so if i want place this code in function receive request then it's work but very slow

model, err := whisper.New(flags.GetModel())
if err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}

So can u explain for me

@bradmurray-dt
Copy link
Contributor

From a quick glance, it looks like you're closing the model after the first request. You should be reusing the model (thread safe) but each context can only be used by a single request (at a time). Depending on the type / level of concurrency you are using, you may be better off using a worker pattern to do the transcription... as things will get very slow if you try to use more threads than your system has available.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants