Upload
-
View
178
Download
2
Embed Size (px)
Citation preview
SynapseGridЯзык описания систем реального времени
Арсений Жижелев, Мэйл.Ру Геймз
Введение
Системы реального времени – баланс буферизации и latency
потоковая обработка событий/данных+ функциональное программирование
параллельность, надёжность+ композиция систем
модульность и интеграция
Аналоги SynapseGrid(Simulink, AnyLogic, Spark, Rx)
Система ведения диалога «Речевой портал»
Мотивация создания языка описания систем реального времени
Речевой портал: выделение признаков MFCC (CMU sphinx4)
● обрабатывается дискретный сигнал● есть модули
– функциональные, без состояния,– с состоянием, – с собственной буферизацией и задержкой
● в поток встроены управляющие сигналы – начало/конец речи● обратные связи
заказ такси
объявления
10мс фреймы
100мс задержки (latency)
длительный процесс распознавания (~1x)• нельзя распознавать пакетно
реакция на события в реальном времени• перебивание• обратная связь от модуля произнесения• телефония: соединение/занято• диалог по второй линии
разветвлённые алгоритмы потоковой обработки• выбор ветки обработки зависит от состояния
Речевой портал:технологические потребности
I. DSL
I. DSLПример 1: Hello, World
Hello, World
object HelloSystem extends BaseTypedSystem{ val nameInput = input [String]("nameInput") val helloOutput = output[String]("helloOutput") (nameInput -> helloOutput). map("Hello, "+_, "hello, + _")}
val f = HelloSystem.toStaticSystem.toDynamicSystem.toMapTransducer(
HelloSystem.nameInput,
HelloSystem.helloOutput)val name = "World"val hello = f(name)
val f = magic(HelloSystem)
val hello = f("World")println(hello)
val s = HelloSystem.toStaticSystems.toDot().saveTo("helloSystem.dot")
I. DSL Пример 2: VADЦепь обнаружения речи
•оценка текущего уровня громкости (мощности) и уровня фона•сглаживание уровней•подсчёт длительности условия: высокий уровень/низкий уровень
•переход в состояния: начало речи/речь/окончание речи/фон•буферизация сигнала до момента принятия решения
•перенаправление сигнала речи на речевой выход•формирование сигналов начала речи и окончания речи•конфигурирование параметров оценки
Цепь детектирования речи VAD(voice activity detection)
время
уровень
15dB
val currentStateLengthMs = state[Int]("currentStateLengthMs", 0)
continuousAudioInput.map(_.timeFrame.deltaTimeMs, "deltaTimeMs").addTo(currentStateLengthMs)
automaton.onAutomatonStateChanged.const(0).saveTo(currentStateLengthMs, "len = 0")
VAD:Подсчёт длительности текущего состояния
trait LevelsEstimationB extends Breadboard with InputB { continuousAudioInput. withState(levels). stateMap({
case (levelsValue,mediaFrame) => val newLevelsValue =
levelsValue.nextLevels(mediaFrame.energyDb) (newLevelsValue,(newLevelsValue,mediaFrame))
},"energyLevel") >> mediaFrameWithLevels
(mediaFrameWithLevels -> newLevels).map(_._1, "_._1")}
VAD:Оценка уровня сигнала/фона
trait Breadboard extends BaseTypedSystem { val settings: VadSettings val speechEndBufferMs = settings.speechEndDecisionMs val frameSizeMs = 10
//internal contacts for sub schemes interconnections lazy val mediaFrameWithLevels =
contact[(Levels, MediaFrame)]("mediaFrameWithLevels") lazy val newLevels = contact[Levels]("newLevels") lazy val speechSurelyStarted = contact[Any]("speechSurelyStarted") lazy val speechSurelyFinished = contact[Any]("speechSurelyFinished")
// The state of VAD algorithm lazy val currentStateLengthMs = state[Int]("currentStateLengthMs", 0) lazy val speechBufferReversed =
state[List[MediaFrame]]("speechBufferReversed", List()) lazy val levels = state[Levels]("levels", Levels())}
Макетная плата (breadboard/protoboard)Cake pattern
I. DSL Пример 3: ETL
Extract Transform Load
I. DSL4. Обзор возможностей
DSL
Примитивы• обычные Scala-функции• контакты• управляемые переменные состояния
Базовые средства композиции• map, flatMap, flatten, filter, collect, foreach, stateFlatMap• + несколько специальных DSL для частых задач• обратные связи (!) «из коробки»
Средства абстрагирования/агрегации• обычные trait’ы Scala – cake pattern/breadboard• подсистемы с типизированными входами/выходами –
мультифункции
Язык SynapseGrid
State DSL: работа с состоянием (stateMap, stateFlatMap, updateState, withState)
• Специализированные инструменты для numeric, для списков, для игнибиторных дуг• Зависимые переменные (spreadsheet): (update, onChange, dependsOn)• Накопление данных до сигнала сброса: lastJoinUntil
Automata DSL: конечный автомат на основе событий, поступающих на разные контакты
Continuation DSL: конечный автомат на основе событий с одного контакта
Switcher DSL: взаимоисключающие ветви(If, ElseIf, Else)
Discrete time DSL: управление дискретным временем: redlinks, delayN
Exception DSL: обработка исключений: tryMap, success, recover, unhandled
Инструментарий DSL/API
II. Исполнение системы
Однопоточное, параллельное, распределённоеИнтеграция с другим кодом
Обрабатываемые данные – immutable сигналы:
case class Signal[T](contact:Contact[T], data:T)
Signal(nameInput, "World")Signal(helloOutput, "Hello, World.")
Текущее состояние исполнения системы в дискретный момент i:
Seq[Signal[_]]
State(0) == Seq(Signal(nameInput, "World"))State(1) == Seq(Signal(helloOutput, "Hello, World."))
Signal, треллис
Треллис – развёртка состояния во времени.
val trellis = Seq( Seq(Signal(nameInput, "World")), Seq(Signal(helloOutput, "Hello, World.")))
trellis: Seq[Signal[_]]
Треллис
Signal(nameInput, "World")
Signal(helloOutput, "Hello, World.")
Сеть Петри – модель перемещения фишек по двудольному ориентированному графу.
Контакт – позицияСвязь – переходСигнал – фишка
Семантика Synapse Grid – перемещение фишек по орграфу, пока все фишки не окажутся в выходных позициях.Накладные расходы – O(1) на один переход одного сигнала.
Сеть Петри
Signal(nameInput, "World")
Signal(helloOutput, "Hello, World.")
• обычная функция – один вход/один выход• функциональная композиция – линейная
f: X => Y
• мультифункция – несколько входов и выходов• системная композиция – произвольные ветвления
^f: X1 x X2 => Y1 x Y2 g: Signal => Seq[Signal]
Подсистемы (мультифункция)
SystemBuilder – скрипт создания графа системы. Выполняется на этапе конфигурирования. Используются средства Scala: functions, cake pattern, for comprehension.
StaticSystem – immutable граф системы.Используется для статического анализа и для конвертации в *.dot_.toStaticSystem
SignalProcessor – исполнение системы.Выполняются функции, привязанные к переходам.
DynamicSystem – инкапсулированный процессор + состояние системы = чёрный ящик. Принимает и возвращает сигналы:Signal[Input] => Seq[Signal[Output]]
Transducer – выбран один вход + один выход построена функция, скрывающая сигналы. Работает только с данными:f(i:Input):Seq[Output]
Этапы конвертации системы
Runtime
Config time
Dev/test time
Нажмите на иконку в центре фрейма,что бы добавить диаграмму на слайд
• никаких изменений кода системы, только вызов .parallel у StaticSystem• детерминированный результат эквивалентный однопоточному запуску• сериализованный доступ к state'у
• дополнительные накладные расходы на параллельное исполнение. Поэтому имеет смысл только при некоторых условиях.
Параллельное исполнение
val f = HelloSystem.toStaticSystem.toDynamicSystem.toMapTransducer(
HelloSystem.nameInput,
HelloSystem.helloOutput)val name = "World"val hello = f(name)
val f = HelloSystem.toStaticSystem.parallel.toMapTransducer(
HelloSystem.nameInput,
HelloSystem.helloOutput)val name = "World"val hello = f(name)
Хотим запустить сложную систему с подсистемами на нескольких хостах
Распределённый запуск: 1
Каждая подсистема оборачивается в экторКаждый хост тоже снабжается эктором
Распределённый запуск: 2
На каждом хосте добавляется слой роутеров, каждый из которых представляет свою подсистемуПосле старта эктора он регистрируется в своём роутере.Подсистема ничего не знает о расположении других систем. Взаимодействует только со своим роутером
Распределённый запуск: 3
III. Расширение библиотеки
https://github.com/Primetalk/SynapseGrid
DSL для описания системы • SystemBuilder – контейнер для
создаваемых связей, входов и выходов. Минимальный набор методов
• DSL – pimp-my-library – добавлены helper-методы, позволяющие упростить создание разных связей
• Extensions – механизм, позволяющий добавить в SystemBuilder своё состояние, и затем пользоваться им при конструировании системы.
• StaticExtensions – механизм, позволяющий добавить в StaticSystem дополнительную информацию. Например, hint’ы для deployment descriptor’а
Устройство библиотеки
SignalProcessor• RuntimeComponent – инкапсуляция
логики обработки данных на определённом контакте.
• RuntimeSystem – index по контактам. С каждым контактом связаны RuntimeComponent’ы, которые обрабатывают сигналы.
• unhandledExceptionHandler – обработка исключений уровня системы
• redlinks – механизм, позволяющий сделать «сверхвремя» внутри одного дискретного шага
• SystemConvertingSpi – конвертация static-системы в RuntimeComponent. Используются PartialFunction.
• TrellisProducer – развёртка/построение треллиса во времени с использованием RuntimeSystem.
trait SwitcherDsl extends SystemBuilderDsl{ class SwitcherBuilder[T](c: Contact[T], name: String = "")
(implicit sb: SystemBuilder) { def If(condition: T => Boolean) = ElseIf(condition) def ElseIf(condition: T => Boolean) = { val id = nextId conditions += Condition(id, condition) createContactForId(id) } def Else = compileBranches } implicit class SwitcherContactOps[T]( val c: Contact[T]) (implicit sb: SystemBuilder) { def switcher(name: String = "") = new SwitcherBuilder[T](c, name) } }
DSL: switcher
val level = contact[Int]("level")val sw = level.switcher("sw")
sw.If(_ > 10) >> highLevelsw.ElseIf(_ > 3) >> mediumLevelsw.Else() >> lowLevel
val level = contact[Int]("level")
level.filter(_ > 10) >> highLevellevel.filter(i => i<=10 && i > 3) >> mediumLevellevel.filter(_ <= 3) >> lowLevel
IV. Приложения
Системы мягкого реального времени (reactive systems)Обработка Big Data
Приложения: (reactive systems)Системы мягкого реального времени
Речевые приложения• Распознавание/синтез речи, ведение диалогов
Обработка звука в телефонии• Телеконференции/очистка звука/подстройка громкости• Сервисы самообслуживания (DTMF)
Обработка видеопотоков
Реализация SMS-сервисов• биллинг
Распределённая обработка данных• Анализ логов• ETL
Мониторинг АСУТП
IV. Экосистема Big Data
СПАСИБО ЗА ВНИМАНИЕ
[email protected]://github.com/Primetalk/SynapseGrid