This took me a while to find, so I thought I'd share. If you've ever been perplexed by the inability of Drupal to show multiple copies of the same form on the same page with different html ids (this breaks validation), the solution is to give them different form_ids.

The way you do this is by implementing a hook_forms that maps my_module_alpha_form_21 to my_module_alpha_form. Here's how I did it:

    /*
     * Implementation of hook_forms()
     */
    function my_module_forms() {
        // we can't declare a passed parameter, but we want one anyway
        $args = func_get_args();
        $form_id = $args[0][0];

        // base ids for dynamic forms go here
        $dynamic_forms = array(
            'my_module_alpha_form',
            'my_module_beta_form',
        );
        $forms = array();
        foreach ($dynamic_forms as $dynform) {
            if (strpos($form_id, $dynform) === 0) { // === is important! see doc on strpos
                $forms[$form_id] = array(
                    'callback' => $dynform,
                    // this get passed in before the rest of the args to drupal_get_form
                    'callback arguments' => array($myarg),
                );
            }
        }
        return $forms;
    }

And don't forget to set the #base parameter in your form functions, otherwise your submit and validate won't get called (in drupal 6 I think you have to set #submit and #validate separately instead of merely setting #base).

You also need to set the #id on any visible elements, otherwise you still end up with duplicate ids.

function my_module_alpha_form($param) {
    $form = array();
    $form['#base'] = 'my_module_alpha_form';
    $form['param'] = array(
        '#type' => 'value',
        '#value' => $param,
    );
    $form['submit'] = array(
        '#type' => 'submit',
        '#value' => t('Submit!'),
        // set the input id to something unique, otherwise we can't validate
        '#id' => 'submit_' . $param,
    );
    return $form;
}

Note: I wasn't the original one to figure this out. I got the idea from this post.