Комментарии 14
pip install pymorphy2[fast] пробовали?
PyMystem3 использует для обработки внешний исполняемый файл mystem.exe
. Видимо, такая архитектура на частых маленьких вызовах обходится очень дорого. Соответственно, ваш подход с объединением многих предложений в одно для обработки — это действительно хорошая идея.
По поводу дальнейшего ускорения. Итерация по массиву — это задача, которая хорошо параллелится. Можно попробовать joblib в качестве старта. Если расширить ваш пример с "упаковкой" текстов, получится что-то такое:
from pymystem3 import Mystem
from tqdm import tqdm
from joblib import Parallel, delayed
batch_size = 1000
texts = ["Мама мыла раму {}".format(i) for i in range(1000000)]
text_batch = [texts[i: i + batch_size] for i in range(0, len(texts), batch_size)]
def lemmatize(text):
m = Mystem()
merged_text = "|".join(text)
doc = []
res = []
for t in m.lemmatize(merged_text):
if t != '|':
doc.append(t)
else:
res.append(doc)
doc = []
return res
# Вот здесь тоже немного магии :)
processed_texts = Parallel(n_jobs=-1)(delayed(lemmatize)(t) for t in tqdm(text_batch))
У меня на ноуте c Intel Core i5-7300U @2.6Ghz при запуске в 4 процесса, миллион "мама мыла раму" лемматизируется за 16 минут. tqdm показывает ~1.1 it/sec
Ну и дальше, если корпус еще больше — можно на dask кластер вытягивать.
За joblib спасибо, параллельные потоки всегда актуальная тема, хотя не стали сильно в неё углубляться в этом случае: при текущей реализации вышли на приемлемое время подготовки, дальше уже больше внимания на модели
Видимо, такая архитектура на частых маленьких вызовах обходится очень дорогоТочноейшим образом совпадает с моими тестами на Windows, по итогу я то ли баг заводил, то ли в существующий отписывался — решения пока нет. На Linux такой проблемы нет, лемматизатор летает.
Я использовал похожую конструкцию, но инициализировал Mystem() вне функции.
Когда запускал Parallel(n_jobs=-1)(delayed(...) ловил ошибку _pickle.PicklingError: Could not pickle the task to send it to the workers
Короче, покопавшись немного с внешними библиотеками, решил сделать все «в лоб» на голом SQL. Использовались только базы opensubtitles.org и Helsinki Finite-State Technology.
Полный разбор базы получился где-то в районе 40 секунд — минуты.
Группируете тексты, поднимаете процесс mystem-а, суёте, разбираете.
Насколько я искал некоторое время назад — яндекс нигде не раскрывает исходники мистема, везде приходится использовать как процесс.
Теоретически можно попробовать расковырять exe-шник, и попытаться сделать из него библиотеку, но, подозреваю, этого нельзя делать с точки зрения лицензии и довольно сложно технически.
Скажите, а вы станфордский Stanza не пробовали, если да то как в сравнении? Спасибо.
Мы решили проблему написав свою обёртку, которая запускала бы приложение не на один раз, а на продолжительное время и общались с ним через пайпы. Производительность заметно выросла, но стали возникать проблемы со стабильностью, которые и вынудили разработчиков перезапускать приложение на каждый вызов, как мы в последствии предположили. Вышли из положения периодическим перезапуском.
Лемматизируй это быстрее (PyMorphy2, PyMystem3 и немного магии)