Kartikeyssj2 commited on
Commit
427bb16
1 Parent(s): c24f6d7

all files added

Browse files
Files changed (4) hide show
  1. Dockerfile +25 -0
  2. README.md +2 -2
  3. main.py +125 -0
  4. requirements.txt +7 -0
Dockerfile ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Use an official Python runtime as a parent image
2
+ FROM python:3.11.7-slim
3
+
4
+ # Set the working directory in the container
5
+ WORKDIR /app
6
+
7
+ # Copy the current directory contents into the container at /app
8
+ COPY . /app
9
+
10
+ # Install system dependencies
11
+ RUN apt-get update && apt-get install -y \
12
+ libsndfile1 \
13
+ && rm -rf /var/lib/apt/lists/*
14
+
15
+ # Install any needed packages specified in requirements.txt
16
+ RUN pip install --no-cache-dir -r requirements.txt
17
+
18
+ # Make port 80 available to the world outside this container
19
+ EXPOSE 80
20
+
21
+ # Define environment variable
22
+ ENV NAME World
23
+
24
+ # Run app.py when the container launches
25
+ CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "7860"]
README.md CHANGED
@@ -1,8 +1,8 @@
1
  ---
2
  title: Pronunciation Scoring
3
- emoji: 🏢
4
  colorFrom: pink
5
- colorTo: pink
6
  sdk: docker
7
  pinned: false
8
  license: other
 
1
  ---
2
  title: Pronunciation Scoring
3
+ emoji: 👀
4
  colorFrom: pink
5
+ colorTo: green
6
  sdk: docker
7
  pinned: false
8
  license: other
main.py ADDED
@@ -0,0 +1,125 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import re
2
+ import requests
3
+ import pyarrow as pa
4
+ import librosa
5
+ import torch
6
+ from transformers import Wav2Vec2ForCTC, Wav2Vec2Tokenizer
7
+ from fastapi import FastAPI, File, UploadFile
8
+ import warnings
9
+ from starlette.formparsers import MultiPartParser
10
+ import io
11
+
12
+
13
+ MultiPartParser.max_file_size = 200 * 1024 * 1024
14
+
15
+ # Initialize FastAPI app
16
+ app = FastAPI()
17
+
18
+ # Load Wav2Vec2 tokenizer and model
19
+ tokenizer = Wav2Vec2Tokenizer.from_pretrained("facebook/wav2vec2-base-960h")
20
+ model = Wav2Vec2ForCTC.from_pretrained("facebook/wav2vec2-base-960h")
21
+
22
+ # Function to download English word list
23
+ def download_word_list():
24
+ print("Downloading English word list...")
25
+ url = "https://raw.githubusercontent.com/dwyl/english-words/master/words_alpha.txt"
26
+ response = requests.get(url)
27
+ words = set(response.text.split())
28
+ print("Word list downloaded.")
29
+ return words
30
+
31
+ english_words = download_word_list()
32
+
33
+ # Function to count correctly spelled words in text
34
+ def count_spelled_words(text, word_list):
35
+ print("Counting spelled words...")
36
+ # Split the text into words
37
+ words = re.findall(r'\b\w+\b', text.lower())
38
+
39
+ correct = sum(1 for word in words if word in word_list)
40
+ incorrect = len(words) - correct
41
+
42
+ print("Spelling check complete.")
43
+ return incorrect, correct
44
+
45
+ # Function to apply spell check to an item (assuming it's a dictionary)
46
+ def apply_spell_check(item, word_list):
47
+ print("Applying spell check...")
48
+ if isinstance(item, dict):
49
+ # This is a single item
50
+ text = item['transcription']
51
+ incorrect, correct = count_spelled_words(text, word_list)
52
+ item['incorrect_words'] = incorrect
53
+ item['correct_words'] = correct
54
+ print("Spell check applied to single item.")
55
+ return item
56
+ else:
57
+ # This is likely a batch
58
+ texts = item['transcription']
59
+ results = [count_spelled_words(text, word_list) for text in texts]
60
+
61
+ incorrect_counts, correct_counts = zip(*results)
62
+
63
+ item = item.append_column('incorrect_words', pa.array(incorrect_counts))
64
+ item = item.append_column('correct_words', pa.array(correct_counts))
65
+
66
+ print("Spell check applied to batch of items.")
67
+ return item
68
+
69
+ # FastAPI routes
70
+ @app.get('/')
71
+ async def root():
72
+ return "Welcome to the pronunciation scoring API!"
73
+
74
+ @app.post('/pronunciation_scoring')
75
+ async def unscripted_root(audio_file: UploadFile):
76
+ print("Pronunciation Scoring")
77
+
78
+ # Read the UploadFile into memory
79
+ contents = await audio_file.read()
80
+
81
+ print("Contents:" , contents)
82
+
83
+ # Create a BytesIO object from the contents
84
+ audio_bytes = io.BytesIO(contents)
85
+
86
+ print("audio_bytes:" , audio_bytes)
87
+
88
+ # Load the audio file using librosa
89
+ audio, sr = librosa.load(audio_bytes)
90
+
91
+ # Tokenize audio
92
+ print("Tokenizing audio...")
93
+ input_values = tokenizer(audio, return_tensors="pt").input_values
94
+
95
+ # Perform inference
96
+ print("Performing inference with Wav2Vec2 model...")
97
+ logits = model(input_values).logits
98
+
99
+ # Get predictions
100
+ print("Getting predictions...")
101
+ prediction = torch.argmax(logits, dim=-1)
102
+
103
+ # Decode predictions
104
+ print("Decoding predictions...")
105
+ transcription = tokenizer.batch_decode(prediction)[0]
106
+
107
+ # Convert transcription to lowercase
108
+ transcription = transcription.lower()
109
+
110
+ # Print transcription and word counts
111
+ print("Decoded transcription:", transcription)
112
+ incorrect, correct = count_spelled_words(transcription, english_words)
113
+ print("Spelling check - Incorrect words:", incorrect, ", Correct words:", correct)
114
+
115
+ # Calculate pronunciation score
116
+ fraction = correct / (incorrect + correct)
117
+ score = round(fraction * 10, 2)
118
+ print("Pronunciation score for", transcription, ":", score)
119
+
120
+ print("Pronunciation scoring process complete.")
121
+
122
+ return {
123
+ "transcription": transcription,
124
+ "pronunciation_score": score
125
+ }
requirements.txt ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ requests
2
+ pyarrow
3
+ librosa
4
+ torch
5
+ transformers
6
+ fastapi
7
+ starlette