Julia.JuMP в 15 раз медленнее, чем Python.Cvxpy?

Я пытался решить простую задачу оптимизации, сначала с помощью фреймворка Python.Cvxpy, а затем с помощью фреймворка Julia.JuMP, но формулировка Julia.JuMP работает в 15 раз медленнее.

Моя проблема с оптимизацией:

  1. В Python.Cvxpy: (время выполнения: 4 секунды)
# Run: time python this_file.py
import cvxpy as cp
import numpy as np
n = 2
b = np.array([2,3])
c1 = np.array([[3,4],[1,0],[0,1]])
c2 = [1,0,0]

x = cp.Variable(n)
prob = cp.Problem( cp.Minimize(b@x), [ c1@x >= c2 ])
prob.solve(cp.MOSEK)   # FOSS alternative: prob.solve(cp.GLPK)

print('Solution:', prob.value)
  1. В Julia.JuMP: (время работы: 1мин 7сек)
# Run: time julia this_file.jl
using JuMP
using Mosek, MosekTools   # FOSS alternative: using GLPK

function compute()
    n = 2
    b = [2,3]
    c1 = [3 4 ; 1 0 ; 0 1]
    c2 = [1,0,0]

    prob = Model(optimizer_with_attributes(Mosek.Optimizer))   
    # FOSS alternative: Model(optimizer_with_attributes(GLPK.Optimizer))
    @variable(prob, x[1:n])
    @objective(prob, Min, b'*x)
    @constraint(prob, c1*x .>= c2)
    JuMP.optimize!(prob)

    println("Solution: ", JuMP.objective_value(prob))
end;

compute()

Есть какие-нибудь советы или рекомендации по закреплению кода Julia.JuMP?


person pqrz    schedule 26.04.2021    source источник
comment
Кажется, вы измеряете время компиляции. Если вы попробуете более серьезные проблемы, вы, вероятно, увидите совсем другие результаты.   -  person Oscar Smith    schedule 26.04.2021
comment
Да, у JuMP очень долгое время компиляции (примерно до минуты). Но в производственной среде, когда у вас есть проблемы с несколькими сотнями тысяч переменных решения, это не имеет значения. Также при запуске compute() во второй раз в вашем случае вы увидите что-то вроде нескольких секунд.   -  person Przemyslaw Szufel    schedule 26.04.2021
comment
Возможно, стоит упомянуть, что самое важное, что вы можете сделать, чтобы ускорить этот процесс, - это перейти на версию 1.6, если вы еще этого не сделали. Часто компиляция происходит в 2-3 раза быстрее.   -  person Oscar Smith    schedule 27.04.2021
comment
Может, покажете, как вы выполнили тест? Вы запускали его из командной строки вашей ОС или из Julia REPL? И вы позволили ему скомпилировать раньше времени? К сожалению, Mosek представляет собой коммерческий продукт, требующий лицензии, поэтому не каждый может это проверить.   -  person DNF    schedule 27.04.2021
comment
@OscarSmith - Спасибо, julia v1.6 действительно кажется многообещающим   -  person pqrz    schedule 27.04.2021
comment
@DNF - для среды выполнения - использовала утилиту linux time, а для решателя - вы можете использовать альтернативу FOSS: GLPK. Обновили приведенный выше код для обеих проблем.   -  person pqrz    schedule 27.04.2021
comment
Вы хотите сказать, что запускаете это из командной строки Linux? В этом случае вы включаете загрузку и компиляцию пакета, а также время jit для вашей функции. В этом случае не стоит ожидать, что Джулия превзойдет python в краткосрочных вычислениях. Пока инструменты статической компиляции не станут более зрелыми в Julia, вызов кода из Bash не является оптимальным рабочим процессом.   -  person DNF    schedule 27.04.2021
comment
@PrzemyslawSzufel - Хорошо, это больше похоже на единовременную оплату. Спасибо, не знал этого.   -  person pqrz    schedule 27.04.2021
comment
@DNF - Если не bash - каков наилучший рабочий процесс? Или вообще - какими способами прикрутить этот скрипт (кроме апгрейда до v1.6)?   -  person pqrz    schedule 27.04.2021
comment
@pqrz вы можете скомпилировать пакет в sysimage Julia. Вот как: stackoverflow.com/questions/62752978/   -  person Przemyslaw Szufel    schedule 27.04.2021
comment
@pqrz Обычный рабочий процесс для Джулии взят из REPL Джулии. Конечно, это удобно не всем, но за пределами REPL работа с Джулией требует дополнительных усилий. Лично я никогда не использую Julia вне REPL, поэтому я не очень хорошо знаком с альтернативными рабочими процессами.   -  person DNF    schedule 27.04.2021


Ответы (1)


Более 1 минуты является чрезмерным. Вы обновляли пакеты или что-то еще и перекомпилировали?

Вот что я получаю;

(base) oscar@Oscars-MBP lore % cat ~/Desktop/discourse.jl
@time using JuMP
@time using GLPK

function compute()
    n = 2
    b = [2,3]
    c1 = [3 4 ; 1 0 ; 0 1]
    c2 = [1,0,0]

    prob = Model(GLPK.Optimizer)
    @variable(prob, x[1:n])
    @objective(prob, Min, b' * x)
    @constraint(prob, c1 * x .>= c2)
    optimize!(prob)
    println("Solution: ", objective_value(prob))
end

@time compute()
@time compute()
(base) oscar@Oscars-MBP lore % time ~/julia --project=/tmp/jump ~/Desktop/discourse.jl
  4.070492 seconds (8.34 M allocations: 599.628 MiB, 4.17% gc time, 0.09% compilation time)
  0.280838 seconds (233.24 k allocations: 16.040 MiB, 41.37% gc time)
Solution: 0.6666666666666666
 12.746518 seconds (17.74 M allocations: 1.022 GiB, 3.71% gc time, 44.57% compilation time)
Solution: 0.6666666666666666
  0.000697 seconds (2.87 k allocations: 209.516 KiB)
~/julia --project=/tmp/jump ~/Desktop/discourse.jl  22.63s user 0.55s system 100% cpu 23.102 total

Разрушая это

  • Итого: 23 секунды
  • Из них 4 секунды using JuMP
  • 13 секунд - первое решение
  • ~ 0 секунд - второе решение
  • так что остается 6 секунд, чтобы запустить Юля

Мы работаем над улучшением using JuMP и нашей проблемы, связанной с временем первого решения, но пока есть несколько вещей, которые вы можете сделать.

  1. Не запускайте скрипты через julia file.jl. Откройте Julia один раз и используйте REPL. Это позволяет избежать накладных расходов в 6 секунд.
  2. Решите более одной модели JuMP за сеанс. Вам нужно заплатить 13 секунд только один раз. Второе решение было быстрым.
  3. Решайте большие модели. Если время решения измеряется в минутах, вас, вероятно, не волнуют 13 секунд запуска.
  4. Используйте PackageCompiler https://github.com/JuliaLang/PackageCompiler.jl, чтобы избежать некоторых проблемы с задержкой.
  5. Используйте другой инструмент. Если ваш рабочий процесс направлен на решение множества небольших проблем оптимизации, и вы не можете сделать перечисленные выше вещи, на данный момент JuMP может не подойти для этой работы (хотя мы планируем улучшить проблемы с задержкой в ​​будущем).
person Oscar Dowson    schedule 28.04.2021
comment
Вы немного ошиблись по времени (см. github.com/JuliaLang/julia/pull/39802 . Использование @time @eval using JuMP и т.д., будет составлять большую часть этих 6 секунд. Время запуска Julia должно быть ближе к 0,25 секунды. - person Oscar Smith; 29.04.2021