Module: Cohere::Transcribe::ASR::FailurePolicy

Defined in:
lib/cohere/transcribe/asr/failure_policy.rb

Overview

Classification shared by recursive batching and the native boundary. Only allocator failures are allowed to teach a smaller batch cap.

Constant Summary collapse

OUT_OF_MEMORY_MARKERS =
[
  "out of memory",
  "cannot allocate memory",
  "cublas_status_alloc_failed",
  "cuda error: memory allocation",
  "cuda_error_memory_allocation",
  "cudaerrormemoryallocation",
  "cudnn_status_alloc_failed",
  "defaultcpuallocator"
].freeze
DEVICE_FATAL_MARKERS =
[
  "cublas_status",
  "cuda error",
  "cudnn_status",
  "device-side assert",
  "driver shutting down",
  "hip error",
  "illegal memory access",
  "mps backend failed",
  "unspecified launch failure"
].freeze
INVARIANT_ERROR_CLASSES =
[
  IndexError,
  KeyError,
  LoadError,
  NameError,
  NoMethodError,
  NotImplementedError,
  ScriptError,
  SystemStackError,
  TypeError
].freeze
OUT_OF_MEMORY_PATTERN =
Regexp.union(OUT_OF_MEMORY_MARKERS)
DEVICE_FATAL_PATTERN =
Regexp.union(DEVICE_FATAL_MARKERS)

Class Method Summary collapse

Class Method Details

.classify(error) ⇒ Object



79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/cohere/transcribe/asr/failure_policy.rb', line 79

def classify(error)
  if error.respond_to?(:failure_kind)
    kind = error.failure_kind
    kind = kind.to_sym if kind.respond_to?(:to_sym)
    return kind if ExecutionError::KINDS.include?(kind)
  end
  return :oom if error.is_a?(NoMemoryError)

  message = error.message.to_s.downcase
  return :oom if message.match?(OUT_OF_MEMORY_PATTERN)
  return :fatal if INVARIANT_ERROR_CLASSES.any? { |error_class| error.is_a?(error_class) }
  return :fatal if message.match?(DEVICE_FATAL_PATTERN)

  :error
end

.fingerprint(error) ⇒ Object



95
96
97
98
99
100
101
102
103
104
# File 'lib/cohere/transcribe/asr/failure_policy.rb', line 95

def fingerprint(error)
  message = PythonText.split(error.message.to_s).join(" ")
  # Ruby supplies the exception class name as the implicit message for
  # `RuntimeError.new`, while Python's equivalent has an empty message.
  message = "<no message>" if message.empty? || message == error.class.to_s
  message = message[0, 500]
  message = message.gsub(/0x[0-9a-f]+/i, "0x*")
  message = message.gsub(/\b\d+\b/, "#")
  "#{error.class}: #{message}"
end

.formatted_message(error) ⇒ Object



106
107
108
# File 'lib/cohere/transcribe/asr/failure_policy.rb', line 106

def formatted_message(error)
  "#{error.class}: #{error.message}"
end