Project Euler #18 in Python: Maximum sum down a triangle of numbers
In break_pyramid you use list comprehension to split a row into 
numbers – why not use list comprehension as well to split the input
into rows?

def break_pyramid(num_pyr):
    '''
    Breaks the number string into an array
    '''
    pyramid = [[int(col) for col in row.split(' ')] for row in num_pyr.split('\n')]
    return pyramid




In add_from_under, this

greater_vals = [max(lower_row[i:i+2]) for i in range(len(upper_row))]


creates many intermediate slices. The alternative

greater_vals = [max(l, r) for l, r in zip(lower_row, lower_row[1:])]


seems to be slightly faster. You can even combine both zip operations
into a single one:

def add_from_under(upper_row, lower_row):
    return [upper + max(lower_left, lower_right)
         for upper, lower_left, lower_right in zip(upper_row, lower_row, lower_row[1:])]


so that no intermediate list is created.



The main loop applies add_from_under cumulatively to the pyramid
rows (in reverse order). That is a "reduce" operation and can be done
with functools.reduce:

from functools import reduce

def main():
    pyramid = break_pyramid(num_pyr)
    final_row = reduce(add_from_under, reversed(pyramid))
    return final_row[0]


if we exchange the parameter order in add_from_under to

def add_from_under(lower_row, upper_row):
    return [upper + max(lower_left, lower_right)
         for upper, lower_left, lower_right in zip(upper_row, lower_row, lower_row[1:])]


Now the pyramid variable is just iterated over, but not modified
anymore.